Introdução ao Terraform: Infrastructure as Code
1. O que é Infrastructure as Code (IaC) e por que usar Terraform?
Infrastructure as Code (IaC) é a prática de gerenciar e provisionar infraestrutura computacional através de arquivos de configuração declarativos, em vez de processos manuais. Em vez de acessar um console web ou executar comandos manuais no terminal para criar servidores, redes, bancos de dados ou containers, você escreve código que define o estado desejado da sua infraestrutura.
Os benefícios do IaC são transformadores:
- Reprodutibilidade: ambientes idênticos podem ser criados quantas vezes forem necessárias
- Versionamento: arquivos de configuração podem ser armazenados em Git, permitindo histórico de mudanças, revisões e rollbacks
- Automação: elimina erros humanos e acelera o provisionamento de minutos para segundos
- Documentação viva: o código descreve exatamente como a infraestrutura está configurada
Comparado ao gerenciamento manual, onde cada servidor pode ter configurações ligeiramente diferentes devido a intervenções humanas, o IaC garante consistência total entre ambientes de desenvolvimento, homologação e produção.
No ecossistema DevOps, o Terraform se destaca por ser agnóstico de provedor — você pode gerenciar recursos AWS, Azure, GCP, Docker e Kubernetes com a mesma ferramenta e sintaxe. Sua abordagem declarativa permite que você descreva o que quer (um container rodando Nginx, um deployment Kubernetes com 3 réplicas) e o Terraform descobre como chegar lá.
2. Instalação e Configuração Inicial do Terraform
A instalação do Terraform CLI é simples. No Linux (Ubuntu/Debian):
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
No macOS via Homebrew:
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
No Windows, baixe o binário do site oficial e adicione ao PATH.
Após instalar, crie a estrutura básica de um projeto:
mkdir meu-projeto-terraform
cd meu-projeto-terraform
touch main.tf providers.tf variables.tf outputs.tf
O arquivo providers.tf configura os plugins que o Terraform usará para interagir com APIs externas:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.0"
}
}
}
3. Conceitos Fundamentais: Providers, Resources e State
Providers são plugins que traduzem as APIs dos serviços (Docker, Kubernetes, AWS) para recursos que o Terraform entende. Cada provedor tem sua própria documentação e parâmetros de configuração.
Resources são os blocos de construção que definem componentes da infraestrutura. Um resource pode ser um container Docker, um deployment Kubernetes, uma instância EC2 ou um bucket S3.
State é o arquivo terraform.tfstate que mapeia os recursos provisionados no mundo real para sua configuração declarativa. Sem o state, o Terraform não saberia o que já foi criado e o que precisa ser modificado ou destruído. Este arquivo é crítico — nunca deve ser editado manualmente e deve ser armazenado com segurança (idealmente em backend remoto para times).
4. Primeiros Passos: Provisionando um Container Docker com Terraform
Vamos criar um container Nginx usando o provider Docker. Crie o arquivo main.tf:
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "meu-nginx-tf"
ports {
internal = 80
external = 8080
}
volumes {
host_path = "/tmp/nginx-html"
container_path = "/usr/share/nginx/html"
}
}
Agora execute os comandos fundamentais:
terraform init # Baixa os providers e configura o backend
terraform plan # Mostra o que será criado/modificado/destruído
terraform apply # Executa as mudanças (confirme com "yes")
O terraform plan exibe um resumo detalhado:
Terraform will perform the following actions:
# docker_image.nginx will be created
+ resource "docker_image" "nginx" {
+ id = (known after apply)
+ name = "nginx:latest"
+ repo_digest = (known after apply)
}
# docker_container.nginx will be created
+ resource "docker_container" "nginx" {
+ id = (known after apply)
+ image = (known after apply)
+ name = "meu-nginx-tf"
+ ports {
+ external = 8080
+ internal = 80
}
}
Após o apply, acesse http://localhost:8080 e veja o Nginx rodando.
5. Gerenciando Recursos Kubernetes com Terraform
Para gerenciar Kubernetes, configure o provider apontando para seu kubeconfig:
provider "kubernetes" {
config_path = "~/.kube/config"
}
Agora crie um Deployment e um Service:
resource "kubernetes_deployment_v1" "nginx" {
metadata {
name = "nginx-deployment"
labels = {
app = "nginx"
}
}
spec {
replicas = 3
selector {
match_labels = {
app = "nginx"
}
}
template {
metadata {
labels = {
app = "nginx"
}
}
spec {
container {
image = "nginx:latest"
name = "nginx"
port {
container_port = 80
}
}
}
}
}
}
resource "kubernetes_service_v1" "nginx" {
metadata {
name = "nginx-service"
}
spec {
selector = {
app = "nginx"
}
port {
port = 80
target_port = 80
}
type = "LoadBalancer"
}
}
A diferença entre kubectl apply e terraform apply é fundamental: com kubectl, você aplica manifestos YAML diretamente. Com terraform, você gerencia o ciclo de vida completo — se alguém alterar manualmente o deployment com kubectl edit, o Terraform detectará o drift no próximo plan e oferecerá reconciliação.
6. Trabalhando com Variáveis e Outputs
Variáveis tornam seus templates reutilizáveis. Crie variables.tf:
variable "container_name" {
description = "Nome do container Docker"
type = string
default = "meu-nginx-padrao"
}
variable "nginx_port" {
description = "Porta externa do Nginx"
type = number
default = 8080
}
Use as variáveis no main.tf:
resource "docker_container" "nginx" {
name = var.container_name
image = docker_image.nginx.image_id
ports {
internal = 80
external = var.nginx_port
}
}
Para passar valores específicos, crie terraform.tfvars:
container_name = "nginx-producao"
nginx_port = 80
Outputs extraem informações úteis do state:
output "container_id" {
value = docker_container.nginx.id
description = "ID do container criado"
}
output "container_ip" {
value = docker_container.nginx.ip_address
description = "IP do container"
}
Após o apply, os outputs são exibidos no terminal ou podem ser consultados com terraform output.
7. Ciclo de Vida do Terraform: Plan, Apply, Destroy
O fluxo de trabalho padrão do Terraform é:
terraform init— inicializa o diretório de trabalho, baixa providersterraform plan— cria um plano de execução mostrando as mudançasterraform apply— executa o plano, criando ou modificando recursosterraform destroy— remove todos os recursos gerenciados
Para times, o state remoto é essencial. Configure um backend S3:
terraform {
backend "s3" {
bucket = "meu-terraform-state-bucket"
key = "dev/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
}
}
O DynamoDB garante locking de estado — se dois membros do time rodarem apply simultaneamente, um será bloqueado até o outro terminar, prevenindo corrupção do state.
8. Conclusão e Próximos Passos
O Terraform transforma a maneira como equipes DevOps gerenciam infraestrutura. Combinado com Docker e Kubernetes, você pode provisionar desde containers locais até clusters completos em produção com o mesmo fluxo de trabalho declarativo. A capacidade de versionar, revisar e automatizar toda a infraestrutura reduz drasticamente erros e acelera entregas.
Nos próximos artigos desta série, exploraremos:
- Módulos Terraform para reutilização de código
- Gerenciamento de secrets com GitHub Actions e Terraform
- Pipelines CI/CD completos com provisionamento automatizado
Para continuar seus estudos, a documentação oficial da HashiCorp e os tutoriais práticos são os melhores recursos.
Referências
- Documentação Oficial do Terraform — Referência completa sobre instalação, providers, recursos e melhores práticas
- HashiCorp Learn: Get Started with Terraform — Tutoriais práticos para iniciantes, incluindo exemplos com Docker e Kubernetes
- Provider Docker para Terraform (kreuzwerker) — Documentação oficial do provider Docker, com todos os recursos suportados
- Provider Kubernetes para Terraform (HashiCorp) — Guia completo para gerenciar deployments, services e outros recursos Kubernetes
- Gerenciamento de State Remoto no Terraform — Como configurar backends S3 com DynamoDB para locking de estado em times
- Terraform: Infrastructure as Code (livro) — Referência aprofundada sobre padrões de design, módulos e workflows avançados
- Boas Práticas Terraform para DevOps — Artigo da HashiCorp com recomendações para estrutura de projetos, variáveis e segurança