🏗️ O que é Infraestrutura como Código?
IaC (Infrastructure as Code) é a prática de gerenciar e provisionar infraestrutura através de arquivos de configuração versionados, em vez de processos manuais ou interfaces gráficas.
Com IaC você trata servidores, redes, bancos de dados e qualquer recurso de infra da mesma forma que trata código de aplicação — com versionamento, revisão, testes e automação.
- Reprodutibilidade — o mesmo código cria ambientes idênticos em dev, staging e prod
- Versionamento — histórico completo de mudanças na infra via Git
- Automação — elimina erros humanos de configuração manual
- Documentação viva — o código é a documentação da infra
- Disaster recovery — recrie toda a infra em minutos a partir do código
🛠️ Ferramentas de IaC
Terraform
Multi-cloud, declarativo, HCL. Padrão do mercado para provisionamento.
CloudFormation
Nativo AWS, YAML/JSON. Integração total com serviços AWS.
Ansible
Configuração e orquestração. Agentless, usa SSH.
Pulumi
IaC com linguagens reais: Python, TypeScript, Go.
| Ferramenta | Tipo | Linguagem | Melhor para |
|---|---|---|---|
| Terraform | Provisionamento | HCL | Multi-cloud, padrão de mercado |
| CloudFormation | Provisionamento | YAML/JSON | Projetos 100% AWS |
| Ansible | Configuração | YAML | Configurar servidores, apps |
| Pulumi | Provisionamento | Python/TS/Go | Times que preferem linguagens reais |
🟣 Terraform — Fundamentos
O Terraform usa a linguagem HCL (HashiCorp Configuration Language) para descrever recursos de infra de forma declarativa.
Instalação no Ubuntu/WSL2:
# Adicionar repositório HashiCorp
wget -O- https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /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
# Verificar
terraform version
Estrutura básica de um projeto Terraform:
projeto/
├── main.tf # recursos principais
├── variables.tf # declaração de variáveis
├── outputs.tf # valores de saída
├── providers.tf # configuração do provider
└── terraform.tfvars # valores das variáveis (não commitar se tiver secrets)
Comandos essenciais:
# Inicializar projeto (baixa providers e módulos)
terraform init
# Ver o que será criado/alterado/destruído
terraform plan
# Aplicar as mudanças
terraform apply
# Aplicar sem confirmação (cuidado!)
terraform apply -auto-approve
# Destruir toda a infra
terraform destroy
# Ver estado atual
terraform show
# Listar recursos no state
terraform state list
# Formatar código
terraform fmt
# Validar sintaxe
terraform validate
☁️ Terraform + AWS — Exemplos Práticos
providers.tf — configurar AWS:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
# State remoto no S3 (recomendado para times)
backend "s3" {
bucket = "aegiscloud-terraform-state"
key = "producao/terraform.tfstate"
region = "us-east-1"
}
}
provider "aws" {
region = var.aws_region
}
main.tf — bucket S3 + CloudFront:
# Bucket S3 para site estático
resource "aws_s3_bucket" "site" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_website_configuration" "site" {
bucket = aws_s3_bucket.site.id
index_document { suffix = "index.html" }
error_document { key = "index.html" }
}
# Distribuição CloudFront
resource "aws_cloudfront_distribution" "cdn" {
enabled = true
default_root_object = "index.html"
origin {
domain_name = aws_s3_bucket.site.bucket_regional_domain_name
origin_id = "S3Origin"
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3Origin"
viewer_protocol_policy = "redirect-to-https"
forwarded_values {
query_string = false
cookies { forward = "none" }
}
}
restrictions {
geo_restriction { restriction_type = "none" }
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
variables.tf e outputs.tf:
# variables.tf
variable "aws_region" {
description = "Região AWS"
type = string
default = "us-east-1"
}
variable "bucket_name" {
description = "Nome do bucket S3"
type = string
}
# outputs.tf
output "cloudfront_url" {
description = "URL do CloudFront"
value = "https://${aws_cloudfront_distribution.cdn.domain_name}"
}
output "bucket_name" {
value = aws_s3_bucket.site.bucket
}
📦 State e Workspaces
O terraform.tfstate é o arquivo que mapeia os recursos declarados no código com os recursos reais na nuvem. É o "cérebro" do Terraform.
# Criar bucket S3 para state remoto
aws s3 mb s3://aegiscloud-terraform-state --region us-east-1
# Criar tabela DynamoDB para lock de state
aws dynamodb create-table \
--table-name terraform-lock \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region us-east-1
Workspaces permitem múltiplos ambientes com o mesmo código:
# Criar e usar workspace de staging
terraform workspace new staging
terraform workspace new producao
# Listar workspaces
terraform workspace list
# Trocar de workspace
terraform workspace select producao
# Usar workspace no código
# resource "aws_instance" "app" {
# instance_type = terraform.workspace == "producao" ? "t3.medium" : "t3.micro"
# }
🟠 AWS CloudFormation
O CloudFormation é a solução nativa da AWS para IaC. Usa YAML ou JSON e tem integração profunda com todos os serviços AWS.
Template básico — EC2 + Security Group:
AWSTemplateFormatVersion: '2010-09-09'
Description: Servidor web simples
Parameters:
InstanceType:
Type: String
Default: t3.micro
AllowedValues: [t3.micro, t3.small, t3.medium]
Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Permite HTTP e SSH
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: ami-0c02fb55956c7d316 # Amazon Linux 2 us-east-1
SecurityGroupIds:
- !Ref WebSecurityGroup
UserData:
Fn::Base64: |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
Outputs:
PublicIP:
Value: !GetAtt WebServer.PublicIp
Description: IP público do servidor
# Deploy do stack via CLI
aws cloudformation deploy \
--template-file template.yaml \
--stack-name meu-servidor-web \
--parameter-overrides InstanceType=t3.micro \
--region us-east-1
# Ver eventos do stack
aws cloudformation describe-stack-events \
--stack-name meu-servidor-web \
--region us-east-1
# Deletar stack
aws cloudformation delete-stack \
--stack-name meu-servidor-web \
--region us-east-1
🔴 Ansible — Configuração de Servidores
O Ansible é usado para configurar servidores após o provisionamento — instalar pacotes, configurar serviços, fazer deploy de aplicações. Funciona via SSH, sem agente nos servidores.
Instalação:
sudo apt update && sudo apt install -y ansible
ansible --version
Inventory — lista de servidores:
# inventory.ini
[webservers]
192.168.1.10 ansible_user=ubuntu
192.168.1.11 ansible_user=ubuntu
[databases]
192.168.1.20 ansible_user=ubuntu
[all:vars]
ansible_ssh_private_key_file=~/.ssh/minha-chave.pem
Playbook — instalar e configurar Nginx:
# playbook-nginx.yml
---
- name: Configurar servidores web
hosts: webservers
become: true # sudo
vars:
app_port: 80
tasks:
- name: Atualizar pacotes
apt:
update_cache: yes
- name: Instalar Nginx
apt:
name: nginx
state: present
- name: Copiar configuração
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Reiniciar Nginx
- name: Garantir que Nginx está rodando
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Reiniciar Nginx
service:
name: nginx
state: restarted
# Executar playbook
ansible-playbook -i inventory.ini playbook-nginx.yml
# Testar conectividade com todos os hosts
ansible all -i inventory.ini -m ping
# Executar comando ad-hoc
ansible webservers -i inventory.ini -m shell -a "df -h"
✅ Boas Práticas de IaC
- State remoto sempre: use S3 + DynamoDB para Terraform em times — nunca state local
- Módulos reutilizáveis: crie módulos Terraform para padrões repetidos (VPC, ECS cluster, RDS)
- Variáveis por ambiente: use
terraform.tfvarsseparados para dev/staging/prod - Nunca commite secrets: use AWS SSM Parameter Store ou Secrets Manager para senhas e chaves
- Plan antes de apply: sempre revise o
terraform planantes de aplicar em produção - Tagging obrigatório: tag todos os recursos com
Environment,Project,Owner— facilita billing e gestão - Drift detection: execute
terraform planperiodicamente para detectar mudanças manuais na infra
