Terraform para iniciantes: infraestrutura como código na prática
1. Introdução ao Terraform e Infraestrutura como Código
Infraestrutura como Código (IaC) é a prática de gerenciar e provisionar recursos de infraestrutura por meio de arquivos de configuração, em vez de processos manuais. O Terraform, desenvolvido pela HashiCorp, é uma ferramenta open-source que adota uma abordagem declarativa: você descreve o estado desejado da infraestrutura, e o Terraform determina as ações necessárias para atingi-lo.
Diferente de ferramentas imperativas (como scripts Ansible ou Shell), onde você especifica cada passo, no Terraform você declara o que quer, não como fazer. Os conceitos fundamentais incluem:
- Estado (state): arquivo que mapeia os recursos reais para sua configuração
- Provedores (providers): plugins que permitem interagir com APIs de cloud (AWS, Azure, GCP)
- Recursos (resources): componentes de infraestrutura que você gerencia (VMs, bancos, redes)
Para instalar, baixe o binário do site oficial da HashiCorp e adicione ao PATH. A autenticação básica na AWS, por exemplo, pode ser feita via variáveis de ambiente:
export AWS_ACCESS_KEY_ID="sua-chave"
export AWS_SECRET_ACCESS_KEY="sua-chave-secreta"
2. Primeiros Passos: Escrevendo e Executando Configurações
Um arquivo .tf segue uma estrutura simples com blocks, arguments e expressões. Veja a estrutura básica:
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "meu_servidor" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "ExemploIniciante"
}
}
Os comandos essenciais do Terraform são:
terraform init: inicializa o diretório de trabalho, baixa providersterraform plan: mostra o que será criado/modificado/destruídoterraform apply: executa as mudanças descritas no plano
Exemplo prático: provisionar uma instância EC2 na AWS. Após criar o arquivo main.tf com o conteúdo acima, execute:
terraform init
terraform plan
terraform apply
O Terraform solicitará confirmação. Digite yes e a instância será criada. Para destruir tudo, use terraform destroy.
3. Gerenciamento de Estado e Versionamento
O arquivo de estado (terraform.tfstate) é o coração do Terraform. Ele contém um mapeamento completo dos recursos gerenciados e seus atributos atuais. Esse arquivo é crítico e nunca deve ser editado manualmente.
Para trabalho em equipe, o estado remoto é essencial. No AWS S3, por exemplo:
terraform {
backend "s3" {
bucket = "meu-bucket-estado"
key = "infra/terraform.tfstate"
region = "us-east-1"
}
}
Isso permite que múltiplos membros da equipe compartilhem o mesmo estado, evitando conflitos. O Terraform usa bloqueio de estado (via DynamoDB) para impedir operações simultâneas.
Comandos úteis para gerenciamento de estado:
terraform state list # Lista todos os recursos no estado
terraform state show <nome> # Mostra detalhes de um recurso
terraform state rm <nome> # Remove recurso do estado (não destrói)
4. Variáveis, Outputs e Modularização
Variáveis tornam suas configurações reutilizáveis e flexíveis. Defina variáveis de entrada:
variable "ambiente" {
description = "Ambiente de deploy"
type = string
default = "dev"
}
variable "tipo_instancia" {
type = string
}
Os outputs expõem informações úteis após o apply:
output "ip_publico" {
value = aws_instance.meu_servidor.public_ip
description = "IP público da instância"
}
Para ambientes diferentes, use arquivos terraform.tfvars:
# dev.tfvars
ambiente = "dev"
tipo_instancia = "t2.micro"
# prod.tfvars
ambiente = "prod"
tipo_instancia = "t2.large"
Execute com: terraform apply -var-file="dev.tfvars"
Módulos permitem organizar infraestrutura complexa. Crie um diretório modules/ e referencie:
module "vpc" {
source = "./modules/vpc"
cidr = "10.0.0.0/16"
nome = "minha-vpc"
}
5. Ciclo de Vida e Dependências entre Recursos
O Terraform gerencia automaticamente dependências implícitas quando você referencia um atributo de outro recurso:
resource "aws_vpc" "principal" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "publica" {
vpc_id = aws_vpc.principal.id # Dependência implícita
cidr_block = "10.0.1.0/24"
}
Para dependências explícitas, use depends_on:
resource "aws_instance" "servidor" {
# ...
depends_on = [aws_subnet.publica]
}
O bloco lifecycle controla o comportamento durante atualizações:
resource "aws_instance" "critico" {
# ...
lifecycle {
create_before_destroy = true # Cria novo antes de destruir antigo
prevent_destroy = true # Impede destruição acidental
}
}
Exemplo completo provisionando VPC, sub-rede e instância:
provider "aws" {
region = "us-east-1"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = { Name = "VPC-Principal" }
}
resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
tags = { Name = "Subnet-Publica" }
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
subnet_id = aws_subnet.main.id
tags = { Name = "Servidor-Web" }
}
6. Debugging, Segurança e Boas Práticas
Comandos de depuração essenciais:
terraform validate # Verifica sintaxe e validade
terraform fmt # Formata código automaticamente
terraform graph # Gera grafo de dependências (visualizável com Graphviz)
Para segurança, evite hardcoding de segredos. Use variáveis sensíveis:
variable "db_password" {
type = string
sensitive = true
}
Ou integre com AWS Secrets Manager:
data "aws_secretsmanager_secret" "db" {
name = "meu-banco"
}
data "aws_secretsmanager_secret_version" "atual" {
secret_id = data.aws_secretsmanager_secret.db.id
}
Boas práticas incluem:
- Versionar todo código .tf em Git
- Usar workspaces para isolar ambientes: terraform workspace new dev
- Evitar hardcoding de valores (use variáveis)
- Bloquear versões de providers: required_providers com versão fixa
7. Próximos Passos e Integração com CI/CD
Para automatizar deploys, integre o Terraform com pipelines CI/CD. Exemplo com GitHub Actions:
name: Deploy Infraestrutura
on:
push:
branches: [ main ]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Terraform Init
run: terraform init
- name: Terraform Apply
run: terraform apply -auto-approve
O comando terraform import permite trazer recursos existentes para o gerenciamento do Terraform:
terraform import aws_instance.existente i-1234567890abcdef0
Para aprofundamento, explore:
- Terraform Cloud: serviço gerenciado com estado remoto, políticas e runs automatizados
- Terraform Registry: repositório oficial de módulos e providers
- HashiCorp Learn: tutoriais interativos gratuitos
O Terraform transforma a maneira como você gerencia infraestrutura, trazendo consistência, rastreabilidade e automação. Comece pequeno, com um recurso simples, e gradualmente expanda para ambientes completos e complexos.
Referências
- Documentação Oficial do Terraform — Guia completo de instalação, configuração e todos os comandos disponíveis
- Terraform: Introdução à Infraestrutura como Código (HashiCorp Learn) — Tutorial interativo para iniciantes com exemplos práticos na AWS
- Terraform Registry - AWS Provider — Catálogo oficial de recursos AWS documentados com exemplos de uso
- Gerenciamento de Estado Remoto no Terraform (AWS S3 + DynamoDB) — Documentação detalhada sobre configuração de backend remoto
- Boas Práticas com Terraform: Estrutura de Módulos e Workspaces — Guia oficial sobre criação de módulos reutilizáveis e organização de ambientes
- Integração Terraform com GitHub Actions — Tutorial passo a passo para automatizar deploys com CI/CD
- Terraform Cloud: Gerenciamento Colaborativo de Infraestrutura — Plataforma gerenciada da HashiCorp para times que usam Terraform em produção