Curso Completo Gratis!
Esse post faz parte de um curso completo sobre Terraform, caso voce queira saber mais sobre terraform da um pulo no meu blog ou no meu youtube para ter acesso ao curso completo 100% gratuito.
Mas se quiser contribuir:
Aqui no Udemy tem o mesmo curso que esta disponivel 100% gratuito no youtube pra quem quiser e puder contribuir financeiramete :)
Terraform Apply
Vamos utilizar o comando terraform apply
para tentarmos criar nosso droplet.
terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.web will be created
+ resource "digitalocean_droplet" "web" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "web-1"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "nyc2"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ status = (known after apply)
+ urn = (known after apply)
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Se você prestar atenção, vai perceber que a saída até aqui é bem similar a que tivemos no plan
, isso acontece por que o apply
antes de realmente aplicar as alterações ele executa um plan para que você possa se certificar de que realmente quer fazer isso.
Se você quiser burlar esse plan e simplesmente aceitar o que vai ser criado, basta executar terraform apply -auto-approve
.
terraform apply -auto-approve
digitalocean_droplet.web: Creating...
Error: Error creating droplet: POST https://api.digitalocean.com/v2/droplets: 401 Unable to authenticate you
Achou que eu ia te livrar de todos os erros? Achou errado!
Bom, 401 Unable to authenticate you
significa que não foi possível se autenticar com a api da Digital Ocean. Se voltarmos lá na página sobre o provider vamos conseguir entender melhor como corrigir o erro.
De toda forma, a primeira coisa que precisamos fazer é criar um token no painel da Digital Ocean. Acesse o painel de controle da sua conta e procure por API, no momento que escrevo é o último item da coluna esquerda. Clique em generate new token
de um nome para o seu token e copie o token que vai aparecer para você. Algo como:
b783123asd294f002c5ea9af1231298327903284kmmsadoiu48d02707a2018588d
Agora vamos seguir o jeito mais simples e completamente
variable "do_token" {
default = "b783123asd294f002c5ea9af1231298327903284kmmsadoiu48d02707a2018588d"
}
provider "digitalocean" {
token = var.do_token
}
O nome do_token
poderia ser qualquer coisa, esse é o campo onde você nomeia sua variável e o parametro default
e onde você cadastra um valor padrão pra ela. Sem esse parâmetro, toda vez que você rodar o plan
ou o apply
ele vai te perguntar o valor da variável. Se isso é o que você quer, basta remover a linha com o parâmetro default.
Vamos executar novamente nosso apply:
terraform apply -auto-approve
digitalocean_droplet.web: Creating...
Error: Error creating droplet: POST https://api.digitalocean.com/v2/droplets: 401 Unable to authenticate you
Mesmo com o token cadastrado, a gente continua recebendo o mesmo erro. Isso acontece por que apesar de termos criado uma variável, não contamos para o provider que ele deve utilizar essa variável. Vamos fazer isso agora.
provider "digitalocean" {
token = var.do_token
}
variable "do_token" {
default = "b783726c929c48febf8555eee856f84f002c5ea9af7d49648d02707a2018588d"
}
resource "digitalocean_droplet" "web" {
image = "ubuntu-20-04-x64"
name = "web-1"
region = "nyc2"
size = "s-1vcpu-1gb"
}
Agora o provider digitalocean
sabe que ele deve procurar por uma variável chamada do_token
e utilizar no parâmetro token
.
Vamos tentar mais uma vez criar nossa máquina.
terraform apply -auto-approve
digitalocean_droplet.web: Creating...
Error: Error creating droplet: POST https://api.digitalocean.com/v2/droplets: 422 nyc2 is unavailable.
Opa, agora aconteceu uma das maiores felicidades de quem escreve código. Mudou o erro! O que é bom pois antes estavamos recebendo uma mensagem de que não conseguíamos nos conectar e agora a mensagem foi 422 nyc2 nao esta disponivel
. Acontece que apesar da documentação do provider dar o exemplo com a região nyc2
, essa região não está disponível a algum tempo já. Eu não sei exatamente se eles nunca se preocuparam em corrigir isso ou se o objetivo é fazer a gente aprender a debugar o problema. Enfim, a solução é só alterar a região para qualquer outra que exista, vamos mudar pra ams3
que e a região de Amsterdam pra ficar mais pertinho de mim, mas você pode usar outra qualquer como nyc3
por exemplo.
Mais uma tentativa:
terraform apply -auto-approve
digitalocean_droplet.web: Creating...
digitalocean_droplet.web: Still creating... [10s elapsed]
digitalocean_droplet.web: Still creating... [20s elapsed]
digitalocean_droplet.web: Still creating... [30s elapsed]
digitalocean_droplet.web: Creation complete after 33s [id=232247846]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Muito bom, mas agora vem a questão! Como a gente pode ter alguns dados desse droplet que acabamos de criar? Por exemplo, se eu quiser saber o IP desse droplet, como a gente faz?
Pra isso vamos utilizar os outputs
.
Terraform Output
Toda documentação de um resource é dividido em pelo menos tres níveis.
- Exemplo de Uso
- Referência de Argumento (ou parâmetro)
- Referência de Atributos
Todos os itens que tivermos dentro do nível de referência de atributo podem ser utilizados seja para passar para um outro resource ou para ser utilizado como output do nosso código. Antes de começarmos a misturar atributos de um recurso com argumento de outro, vamos usar os atributos na sua forma mais simples, como um output.
O output
em si é uma feature que permite voce apresentar o valor de alguma coisa do seu código na tela. Mais pra frente vamos ver uma outra utilidade do output
que é retornar os valores de um módulo. Mas fica tranquilo que isso é mais pra frente.
Por hora vamos adicionar o seguinte num arquivo chamado output.tf
, que esteja na mesma pasta que nosso main.tf
.
output "droplet_ip" {
value = "hashicourse"
}
Vamos executar novamente o comando apply
e vamos ver que agora temos mais um retorno no nosso código.
terraform apply -auto-approve
digitalocean_droplet.web: Refreshing state... [id=232247846]
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
droplet_ip = "hashicourse"
Nada foi criado ou alterado, como esperado, mas vemos um Outputs:
na resposta e o valor que a gente cadastrou pro ip do nosso droplet. Agora manter esse valor hardcoded não vai nos ajudar muito. Vamos então utilizar um atributo do nosso droplet pra isso.
Primeiro, deixa eu te mostrar o código:
resource "digitalocean_droplet" "web" {
image = "ubuntu-20-04-x64"
name = "web-1"
region = "ams3"
size = "s-1vcpu-1gb"
}
output "droplet_ip" {
value = digitalocean_droplet.web.ipv4_address
}
.A forma de chegarmos nesse atributo é bem simples.
- [A] Primeiro você precisa pegar o nome do recurso, que é aquele primeiro ali "digitalocean_droplet" que nada mais é como uma forma de dizer para o provedor qual o recurso você tá querendo criar.
- [B] Segundo pega o nome que você deu para aquele recurso, no nosso caso "web". É muito comum precisarmos utilizar mais de uma vez um recurso no nosso código e essa é uma das formas de nomear aquele recurso. Vale lembrar que esse nome é único, ok?
- [C] Por último precisamos ir lá na documentação e ver qual dos atributos disponíveis nos fornece o que precisamos. É raro que você precise de algo que não está ali disponível, mas raro não é impossível.
Por fim basta montar sempre no formato A.B.C :)
Se você rodar o seu código agora deve ter um retorno como o seguinte:
terraform apply -auto-approve
digitalocean_droplet.web: Refreshing state... [id=232247846]
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
droplet_ip = "104.248.203.68"
Muito provavelmente seu numero de ip é diferente do meu, mas se por algum milagre você pegou o mesmo, bate um print e me manda :)
Uma última dica no que se refere a outputs é que você não precisa utilizar apenas o apply para ter acesso a todos os outputs do seu código. Considerando que você já tenha executado o apply pelo menos uma vez, você pode utilizar o terraform output
:
terraform output
droplet_ip = "104.248.203.68"
Terraform Destroy
Agora que já criamos um droplet, você talvez esteja se perguntando "Beleza, agora como eu desligo esse droplet pra não gastar meu bônus?", bom pra isso tem um comando com nome bem sugestivo destroy
.
O terraform destroy
é o oposto do apply
. Uma das coisas que ambos tem em comum é o plan antes de executar. A gente não falou antes, mas existe um parâmetro no plan
chamado de -destroy
. E esse é o parâmetro que o terraform usa quando a gente executa o terraform destroy
, a saída deve ser parecida com a seguinte:
terraform destroy
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# digitalocean_droplet.web will be destroyed
- resource "digitalocean_droplet" "web" {
- backups = false -> null
- created_at = "2021-02-17T19:34:37Z" -> null
- disk = 25 -> null
- id = "232254786" -> null
- image = "ubuntu-20-04-x64" -> null
- ipv4_address = "104.248.197.79" -> null
- ipv4_address_private = "10.110.0.2" -> null
- ipv6 = false -> null
- locked = false -> null
- memory = 1024 -> null
- monitoring = false -> null
- name = "web-1" -> null
- price_hourly = 0.00744 -> null
- price_monthly = 5 -> null
- private_networking = true -> null
- region = "ams3" -> null
- resize_disk = true -> null
- size = "s-1vcpu-1gb" -> null
- status = "active" -> null
- urn = "do:droplet:232254786" -> null
- vcpus = 1 -> null
- volume_ids = [] -> null
- vpc_uuid = "b83009d3-8cb0-4545-8123-6f2238e40284" -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
Changes to Outputs:
- droplet_ip = "104.248.197.79" -> null
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value:
O que vemos aqui é que vamos destruir todos os nossos recursos, que no caso é apenas um droplet. Você pode digitar yes
no comando acima ou utilizar o -auto-approve
junto com o destroy para destruir todos os recursos sem nem olhar pro plan -destroy
.
terraform destroy -auto-approve
digitalocean_droplet.web: Destroying... [id=232247846]
digitalocean_droplet.web: Still destroying... [id=232247846, 10s elapsed]
digitalocean_droplet.web: Still destroying... [id=232247846, 20s elapsed]
digitalocean_droplet.web: Destruction complete after 22s
Destroy complete! Resources: 1 destroyed.
Beleza, agora você pode descansar em paz que seu bônus/dinheiro não está sendo mais consumido. Lembre-se sempre de destruir os recursos da sua conta pra garantir que não tenha surpresa no fim do mês. Importante também é criar um alerta lá na digitalocean, eu recomendo criar um valor de 5$ que é o custo de um droplet, se passar disso provavelmente algo está errado.
Arquivo de Variaveis
Uma coisa comum de se ver são códigos que utilizam uma variável da seguinte forma:
variable "do_token" {
description = "Uma descricao bacana!"
type = string
}
Ou seja, nao possuem um valor padrão para a variável, acontece que dependendo da quantidade de variáveis que existem nesse formato, pode ser bem chato de ficar colocando uma a uma.
Uma solução, bem gambiarra, que eu já fiz muito é colocar um valor default
para cada uma dessas variáveis e garantir que não iria adicionar as alterações desse arquivo no repositório git. O que normalmente acabava acontecendo depois de um tempo. Acontece que o terraform
te dá a possibilidade de usar um arquivo só para adicionar esse valores. Basta criarmos um arquivo qualquer_coisa.tfvars
. Normalmente as pessoas utilizam terraform.tfvars
ou então nome_do_ambiente.tfvars
. Vamos criar o nosso como terraform.tfvars
mesmo.
do_token = "b783123asd294f002c5ea9af1231298327903284kmmsadoiu48d02707a2018588d"
Esse é o formato do arquivo de variáveis, caso exista um valor padrão e você queira sobrescrever ele, pode colocar o novo valor nesse arquivo e vai funcionar também. Agora precisamos dizer para o terraform
que ele deve buscar os valores das variáveis primeiro nesse arquivo, para isso vamos executar o apply
novamente passando o -var-file
como parâmetro. Esse -varfile
vale para o plan
e o destroy
também.
terraform apply -var-file terraform.tfvars
An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.web will be created
+ resource "digitalocean_droplet" "web" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "web-1"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "ams3"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ status = (known after apply)
+ urn = (known after apply)
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ droplet_ip = (known after apply)
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
digitalocean_droplet.web: Creating...
digitalocean_droplet.web: Still creating... [10s elapsed]
digitalocean_droplet.web: Still creating... [20s elapsed]
digitalocean_droplet.web: Still creating... [30s elapsed]
digitalocean_droplet.web: Creation complete after 34s [id=232397944]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
droplet_ip = "206.189.0.61"
Top comments (0)