Terraform é uma ferramenta multiplataforma para construir, modificar e versionar uma infraestrutura com segurança.
Com ele você escreve um código, numa linguagem declarativa e de fácil compreensão tudo o que você precisa em sua infra.
A ferramenta suporta vários provedores como AWS, DigitalOcean, Google Cloud e etc.
Dependendo do provedor que você usar é possível definir desde as configurações mais low-level (rede, firewall) até as mais high-level (banco de dados, load balancer e etc).
Ao descrever sua infra como código você elimina a necessidade de configurar tudo na mão e documentar toda essa configuração, pois a documentação é o código que você escreve.
Para saber o que será feito, basta rodar “terraform plan”. Para aplicar, “terraform apply” é o caminho.
Isso sem falar sobre as vantagens de ter esse código versionado, e ainda automatizar a atualização da infra num processo de deploy.
Eu estou começando a brincar com Terraform agora, e nesse artigo vamos criar uma infra básica, com duas maquininhas e um load balancer para distribuir a carga entre elas.
Para testar se essa coisa funciona, vamos pedir para o Terraform provisionar essas máquinas com o Apache.
Instalando o Terraform
Antes de mais nada, vamos baixar a aplicação no site oficial. No momento da escrita deste texto a última versão é a 0.12. O programa é multiplataforma, então basta escolher na página de download a versão apropriada para seu sistema.
Depois de baixado basta descompactar o arquivo zip e mandá-lo para uma pasta que esteja em seu path:
$ sudo unzip -d /usr/local/bin terraform_0.12.7_linux_amd64.zip
Agora é só ser feliz!
Autenticar o Terraform com a DigitalOcean
Antes de começar a fazer qualquer coisa, você precisa de um token de API da DigitalOcean. Você pode gerar um personal accestoken aqui.
Depois de gerar esse token, guarde-o numa variável de ambiente de nome DIGITALOCEAN_TOKEN ou DIGITALOCEAN_ACCESS_TOKEN.
Você pode configurar esse token no arquivo Terraform, mas isso não é interessante se você for subir sua configuração para um repositório. Afinal você não quer que ninguém tenha acesso a seu personal access token, certo?
Algumas explicações
O Terraform usa uma linguagem de configuração chamada HCL.
Ela é uma linguagem muito simples. Trata-se de um conjunto de blocos, com alguns campos “chave=valor”.
Os arquivos devem conter a extensão .tf.
Você pode dividir sua configuração em vários arquivos, sem se preocupar em incluí-los um no outro pois o Terraform sabe exatamente a ordem dos recursos a serem executados quando você referencia alguma variável em algum arquivo. Isso é muito interessante, diga-se de passagem.
Mão na massa
Upload da sua public key para ser usada numa droplet
Para ter acesso a uma droplet você precisa ter uma public key ou então a DigitalOcean envia uma senha de root por email.
A segunda opção não é interessante quando estamos falando de automatização, então vamos criar um
arquivo de nome ssh.tf, que será o responsável por fazer o upload de sua chave pública para
a DigitalOcean:
resource "digitalocean_ssh_key" "default" {
name = "Terraform"
public_key = file("~/.ssh/id_rsa.pub")
}
Na primeira linha informamos ao Terraform que vamos usar o provider “digitalocean”, e o recurso “ssh_key”. Depois damos um nome a esse recurso, para ser referenciado mais tarde, se for preciso (nesse caso é “default”).
Na segunda linha damos um nome a chave que iremos fazer o upload, só por questão de legibilidade no painel da DigitalOcean.
Na terceira linha usamos a função file, que lê o conteúdo de um arquivo. Nesse caso o arquivo da chave pública que fica dentro de “seu-usuario/.ssh/id_rsa.pub”.
Agora para não esquecer, rode terraform init
, para o programa baixar o plugin do provider da DigitalOcean, no diretório .terraform dentro do mesmo diretório do seu arquivo .tf.
Você já pode rodar terraform plan
para ver o que o programa irá fazer.
Se você quer ver logo essa chave criada, pode rodar terraform apply
. Mas a parte legal ainda nem começou.
Criando uma droplet
A DigitalOcean dá o nome de “droplet” para as máquinas que você cria. Então uma droplet nada mais é do que o servidor da sua aplicação.
Vamos primeiro ver o conteúdo do arquivo droplet.tf, para depois vermos as explicações:
resource "digitalocean_droplet" "web" {
count = 2
name = "web-${count.index}"
region = "nyc1"
size = "s-1vcpu-1gb"
image = "ubuntu-18-04-x64"
ssh_keys = [digitalocean_ssh_key.default.fingerprint]
}
A linha 2 é uma variável reservada do Terraform, que especifica quantas vezes essa configuração deve ser executada. É o jeito de fazer um loop básico.
Na linha 3 damos o nome as máquinas. Especial aí é o ${count.index}
: Isso serve para sabermos onde está o nosso loop. Então uma máquina terá o nome de “web-0” e a outra “web-1”.
nas linhas 4 – 6 especificamos qual máquina queremos (a mais barata), a região e a imagem do sistema operacional.
Na linha 7 especificamos qual chave SSH nossa máquina irá usar. Podemos especificar mais de uma, por isso a lista ([...]
).
Note que, referenciamos uma variável, “digitalocean_ssh_key.default.fingerprint”. Quando criamos um recurso são retornadas algumas informações, como por exemplo o IP da droplet.
Nesse caso estamos pegando o fingerprint da chave SSH que criamos no arquivo ssh.tf.
Tá começando a ficar bonito! 🙂
Loadbalancer
Está terminando. Vamos criar o arquivo loadbalancer.tf, para apontar para as duas maquininhas que criamos acima:
resource "digitalocean_loadbalancer" "public" {
name = "lb-public"
region = "nyc1"
droplet_ids = digitalocean_droplet.web[*].id
forwarding_rule {
entry_port = 80
entry_protocol = "http"
target_port = 80
target_protocol = "http"
}
healthcheck {
port = 22
protocol = "tcp"
}
}
Quando criamos um loadbalancer significa que temos mais de uma máquina. Na linha 4 especificamos os ids das máquinas que criamos no passo anterior.
A expressão digitalocean_droplet.web[*].id
expande para algo como [digitalocean_droplet.web[0].id, digitalocean_droplet.web[1].id]
.
Nas linhas 6 – 11 definimos que o loadbalancer irá escutar na porta 80 e redirecionar para a porta 80 das máquinas.
Já nas linhas 13 – 16 definimos uma regra de healthcheck. Se a máquina responder na porta 22 TCP então está tudo certo.
Provisionando as máquinas
Se até agora você já rodou terraform apply
alguma vez, está na hora de ver a mágica.
O Terraform identifica mudanças em qualquer um dos recursos, então depois desse próximo passo ele não irá criar tudo de novo, irá apenas atualizar a droplet.
Vamos editar o arquivo droplet.tf, logo abaixo das informações da máquina, acima do “}”, para adicionar alguns comandos de provisionamento:
provisioner "remote-exec" {
inline = [
"apt update",
"apt install -y apache2",
"echo server-${count.index}>/var/www/html/index.html",
"chown www-data:www-data /var/www/html/index.html",
]
connection {
type = "ssh"
host = self.ipv4_address
user = "root"
private_key = file("~/.ssh/id_rsa")
timeout = "2m"
}
}
Acima usamos o provisionador “remote_exec” para executar alguns comandos na máquina via SSH.
O que fizemos foi instalar o Apache e criar um arquivo “index.html” em “/var/www/html” com a frase “web-numero-do-servidor”.
Como testar? Qual o IP do meu loadbalancer?
Calma! Criando o arquivo output.tf você pode saber tudo o que você deseja:
output "droplets_ipv4_addresses" {
value = digitalocean_droplet.web[*].ipv4_address
}
output "loadbalancer_ip_address" {
value = digitalocean_loadbalancer.public.ip
}
Agora sempre que você rodar terraform apply
o programa irá mostrar o IP das suas duas droplets e do seu loadbalancer.
Para testar basta acessar o IP do loadbalancer. Hora ele vai cair no web-0, hora no web-1. Se isso acontecer, parabéns para nós!
Fim
Depois de testar, se tudo correu bem, é sempre bom rodar terraform destroy
se você não for usar isso e não quiser ser cobrado.
Nessa introdução não fizemos praticamente nada.
A DigitalOcean permite criar bancos de dados na nuvem (digitalocean_database), apontar o domínio para o loadbalancer (digitalocean_domain), proteger as máquinas com um firewall (digitalocean_firewall), etc.
Você pode ir brincando e testando tudo isso. O céu é o limite.
Se você ficou com preguiça de acompanhar o texto, aqui está um repositório no GitHub com o código que eu coloquei aqui.
Não deixe de ler a documentação do provider DigitalOcean para Terraform.
Qualquer crítica, elogio, sugestão, comenta aí!
Até a próxima!