Olá! Bem-vindo à nossa décima sétima lição.
Na aula anterior, você deu vida à nossa infraestrutura, usando o fluxo de trabalho init, plan e apply para provisionar um ambiente ECS completo na AWS. Foi um marco importante! No entanto, como apontamos no final, nosso código, embora funcional, é rígido. Ele está repleto de valores "hardcoded", como nomes de regiões e configurações de recursos, o que o torna difícil de reutilizar ou adaptar.
Nesta lição, vamos abordar esse problema de frente, transformando nosso código estático em uma configuração flexível e reutilizável. O nosso objetivo é gerenciar a configuração com variáveis do Terraform e expor detalhes dos recursos usando outputs. Para alguém com sua experiência em desenvolvimento de software, os conceitos serão familiares: pense em variáveis como argumentos de uma função e em outputs como seus valores de retorno. Este é um passo essencial para escrever código de IaC maduro e profissional.
1. Parâmetros de Entrada: Tornando seu Código Flexível com Variáveis
Variáveis de entrada (ou simplesmente "variáveis") são a maneira como parametrizamos nossas configurações do Terraform. Elas nos permitem passar valores para nosso código no momento da execução, sem alterar os arquivos .tf originais.
Uma variable é declarada em um bloco como este:
variable "aws_region" {
type = string
description = "A região da AWS onde os recursos serão criados."
default = "us-east-1"
}
Os principais argumentos são:
type: Define o tipo de dado esperado (string,number,list,map, etc.). Isso é análogo à tipagem estática em C#, ajudando a evitar erros.description: Uma explicação do propósito da variável. É uma boa prática, semelhante à documentação de código.default: Um valor padrão a ser usado se nenhum outro for fornecido. Isso torna a variável opcional.
Para uma introdução completa às variáveis, assista às primeiras seções do vídeo a seguir.
Terraform Basics: Input Variables
O vídeo "Terraform Basics: Input Variables" do canal Ned in the Cloud oferece uma excelente explicação conceitual e sintática das variáveis de entrada.
Assista aos seguintes trechos: 01:41 a 04:02: Entenda o que são as variáveis de entrada e a sintaxe básica do bloco variable. 04:35 a 06:05: Veja os três argumentos principais: description, type e default. 06:05 a 10:16: Aprenda como referenciar o valor de uma variável em seu código usando a sintaxe var.<nome_da_variavel>.
Refatorando Nosso Projeto
Vamos aplicar esses conceitos.
-
Crie um arquivo
variables.tf: É uma convenção manter todas as declarações de variáveis em um arquivo separado para organização. -
Identifique e mova os valores "hardcoded": Percorra seus arquivos (
vpc.tf,ecs.tf, etc.) e identifique valores que poderiam ser parametrizados. Aqui estão alguns candidatos ideais:- Região da AWS
- CIDR block do VPC
- Nomes de recursos (cluster, serviço, etc.)
- Configurações da Task Definition (CPU, memória)
- Nome da imagem do container
-
Declare as variáveis em
variables.tf: Para cada valor identificado, crie um blocovariable. Por exemplo:# Em variables.tf variable "aws_region" { description = "A região da AWS para provisionar a infraestrutura." type = string default = "us-east-1" } variable "vpc_cidr_block" { description = "O bloco CIDR para o VPC." type = string default = "10.0.0.0/16" } variable "app_name" { description = "O nome base para os recursos da aplicação." type = string default = "minha-api-net" } variable "app_port" { description = "A porta em que a aplicação escuta no container." type = number default = 8080 } -
Substitua os valores no código: Agora, substitua os valores "hardcoded" pelas referências às variáveis.
# Em vpc.tf resource "aws_vpc" "main" { cidr_block = var.vpc_cidr_block # ... } # Em ecs.tf resource "aws_ecs_cluster" "main" { name = "${var.app_name}-cluster" } # No container_definitions do aws_ecs_task_definition # ... "portMappings": [ { "containerPort": var.app_port, "hostPort": var.app_port } ], # ...

2. Fornecendo Valores para as Variáveis
Declarar variáveis é apenas metade da história. Precisamos de uma maneira de fornecer os valores. O Terraform oferece várias, com uma ordem de precedência clara.
-
Arquivos de Definição de Variáveis (Recomendado para uso local):
terraform.tfvars: Um arquivo que o Terraform carrega automaticamente se estiver presente. É ideal para definir os valores principais para um ambiente específico.*.auto.tfvars: Qualquer arquivo com essa terminação também é carregado automaticamente.- Sintaxe:
# Em terraform.tfvars aws_region = "us-east-1" app_name = "meu-projeto-pessoal"
-
Flags de Linha de Comando:
-var="nome=valor": Para substituir valores individuais. Útil para testes rápidos.-var-file="caminho/para/arquivo.tfvars": Para especificar um arquivo de variáveis com nome personalizado.
-
Variáveis de Ambiente:
- Nomeie a variável de ambiente como
TF_VAR_<nome_da_variavel>. Por exemplo,export TF_VAR_aws_region="us-west-2". Isso é extremamente útil em pipelines de CI/CD (como Jenkins ou GitLab CI, com os quais você tem experiência) para injetar configurações sem expô-las no código.
- Nomeie a variável de ambiente como
Ordem de Precedência (do menor para o maior):
O Terraform carrega as variáveis na seguinte ordem. Se uma variável for definida em vários locais, o último valor carregado vence:
- Valores
defaultdentro dos blocosvariable. - Valores em arquivos
terraform.tfvarse*.auto.tfvars. - Valores de arquivos
-var-filena linha de comando. - Valores de flags
-varna linha de comando. - Variáveis de ambiente (
TF_VAR_...).
O vídeo a seguir demonstra essas abordagens e, crucialmente, explica a ordem de precedência.
Terraform Basics: Input Variables
Para entender como fornecer valores e como o Terraform resolve conflitos, a segunda metade do vídeo "Terraform Basics: Input Variables" é essencial.
Assista à seção de 23:11 a 30:19. Ela detalha os diferentes métodos para fornecer valores às variáveis e, mais importante, a ordem de avaliação que o Terraform utiliza. Compreender essa precedência é fundamental para depurar configurações.
Teste seu entendimento!
Você tem a seguinte variável em variables.tf:
variable "instance_type" {
type = string
default = "t2.micro"
}
No seu arquivo terraform.tfvars, você define instance_type = "t3.small".
Ao executar o comando terraform apply -var="instance_type=m5.large", qual tipo de instância será provisionado?
Show answer
Será provisionada a m5.large. A flag -var na linha de comando tem uma precedência maior do que o arquivo terraform.tfvars e o valor default no bloco da variável.
3. Valores de Saída: Expondo Detalhes da sua Infraestrutura
Outputs (saídas) são a maneira do Terraform expor informações sobre os recursos que ele gerencia. Pense neles como os valores de retorno da sua configuração. Eles são úteis para:
- Exibir informações importantes no console após um
apply(ex: o endereço DNS do seu load balancer). - Passar dados para outros sistemas, como um script de implantação.
- Permitir que outras configurações do Terraform leiam informações deste estado (via
terraform_remote_state).
A sintaxe é simples e geralmente colocada em um arquivo outputs.tf:
# Em outputs.tf
output "alb_dns_name" {
description = "O nome DNS público do Application Load Balancer."
value = aws_lb.main.dns_name
}
Para uma visão geral clara dos outputs e seus casos de uso, o vídeo a seguir é perfeito.
Terraform Basics: Output Values
O vídeo "Terraform Basics: Output Values", também do Ned in the Cloud, explica por que e como usar os outputs.
Assista aos seguintes trechos: 01:36 a 02:59: Entenda o propósito fundamental dos outputs como uma forma de obter informações de uma configuração. 02:59 a 07:38: Explore os três principais casos de uso: exibir no terminal, passar dados entre módulos e compartilhar estado entre configurações. 07:38 a 11:47: Aprenda a sintaxe do bloco output e seus argumentos, como value, description e sensitive.
Aplicando os Outputs ao Nosso Projeto
Após um terraform apply, precisamos saber como acessar nossa aplicação. O output mais crucial para nós é o endereço DNS do Application Load Balancer.
-
Crie um arquivo
outputs.tf. -
Adicione o output do ALB:
# Em outputs.tf output "alb_dns_name" { description = "O nome DNS público do Application Load Balancer para acessar a API." value = aws_lb.main.dns_name } output "ecr_repository_url" { description = "A URL do repositório ECR para onde a imagem da aplicação deve ser enviada." value = aws_ecr_repository.main.repository_url }
Agora, ao executar terraform apply, após a conclusão, você verá os outputs impressos no seu terminal:
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
alb_dns_name = "minha-api-net-alb-1234567890.us-east-1.elb.amazonaws.com"
ecr_repository_url = "123456789012.dkr.ecr.us-east-1.amazonaws.com/minha-api-net"
Você também pode consultar esses valores a qualquer momento com o comando terraform output:
$ terraform output alb_dns_name
"minha-api-net-alb-1234567890.us-east-1.elb.amazonaws.com"
$ terraform output -json
{
"alb_dns_name": {
"sensitive": false,
"type": "string",
"value": "minha-api-net-alb-1234567890.us-east-1.elb.amazonaws.com"
},
"ecr_repository_url": {
"sensitive": false,
"type": "string",
"value": "123456789012.dkr.ecr.us-east-1.amazonaws.com/minha-api-net"
}
}
A saída em JSON é especialmente útil para passar para scripts ou outras ferramentas de automação.
Conclusão
Parabéns! Você refatorou com sucesso sua configuração do Terraform, transformando-a de um script estático para um código de infraestrutura flexível e reutilizável. Essa é uma habilidade fundamental para qualquer profissional que trabalha com IaC.
Principais Pontos:
- Variáveis de Entrada (
variable) permitem parametrizar suas configurações, tornando-as adaptáveis a diferentes ambientes e requisitos sem alterar o código-fonte. - Valores para variáveis podem ser fornecidos através de arquivos
.tfvars, flags de linha de comando ou variáveis de ambiente, com uma ordem de precedência clara. - Valores de Saída (
output) expõem informações importantes sobre os recursos provisionados, tornando-os acessíveis para usuários, scripts ou outras configurações do Terraform. - Manter variáveis e outputs em arquivos dedicados (
variables.tf,outputs.tf) é uma excelente prática para a organização e legibilidade do projeto.
Próxima Lição:
Nossa infraestrutura está de pé, nosso código está flexível e agora sabemos como obter as informações necessárias dele. O último passo no ciclo de vida da infraestrutura é saber como removê-la de forma limpa e segura. Na próxima lição, vamos explorar o comando terraform destroy para desprovisionar todos os recursos que criamos, uma etapa crucial para gerenciar custos e ambientes temporários.