Terraform e Ansible juntos no fluxo de entrega
Objetivos desta aula
- Encadear provisionamento e configuração
- Gerar inventário dinâmico
- Aplicar IaC pelo pipeline com aprovação
O fluxo maduro é: Terraform provisiona e expõe outputs (IPs, IDs, endpoints), um inventário dinâmico consome esses dados e o Ansible configura os hosts. Nada de copiar IP à mão — o acoplamento por output é o que torna o processo repetível.
No pipeline, separe claramente plan (em PR, com role somente leitura, resultado comentado no PR) de apply (em main ou tag, com ambiente protegido e aprovação humana). Essa separação é o que permite revisar infraestrutura como se revisa código.
Registre no repositório a ordem de execução, os pré-requisitos e o procedimento de rollback de infraestrutura — que raramente é 'destroy'. Em recursos com dados, rollback significa restaurar backup, não apagar e recriar.
1. A divisão de responsabilidades
Terraform cria VPC, instâncias e banco e exporta outputs (IPs, IDs). Ansible usa esses dados, via inventário dinâmico por tag, para configurar os hosts. Cada ferramenta faz o que faz melhor.
2. Imagens prontas (golden images)
Em vez de configurar no boot, o Packer + Ansible gera uma AMI pronta; o Terraform só a referencia. O servidor sobe mais rápido e sempre igual.
3. Pipeline de infraestrutura
- PR: fmt, validate, tflint, checkov/trivy config, plan comentado no PR
- Revisão humana do plan
- Merge: apply com o plano aprovado
- Ansible aplica configuração
- Smoke test
4. Segurança do pipeline de infra
OIDC para a AWS, role de plan (somente leitura) separada da role de apply, e apply de prod apenas via environment com aprovação.
5. Checagem final
Um PR de infraestrutura do CloudShop mostra o plan, passa nos scanners e, após o merge, provisiona e configura sem passos manuais.
Na prática
Pipeline de IaC com plan e apply separados
yaml
name: infra
on:
pull_request:
paths: ["infra/**"]
push:
branches: [main]
paths: ["infra/**"]
permissions:
contents: read
id-token: write
pull-requests: write
jobs:
plan:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/cloudshop-plan
aws-region: us-east-1
- uses: hashicorp/setup-terraform@v3
- run: terraform -chdir=infra/envs/staging init
- run: terraform -chdir=infra/envs/staging validate
- run: terraform -chdir=infra/envs/staging plan -no-color | tee plan.txt
- uses: actions/upload-artifact@v4
with: { name: plan, path: plan.txt }
apply:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/cloudshop-apply
aws-region: us-east-1
- uses: hashicorp/setup-terraform@v3
- run: terraform -chdir=infra/envs/staging init
- run: terraform -chdir=infra/envs/staging apply -auto-approve
- name: Configurar hosts com Ansible
run: |
pip install ansible boto3
ansible-playbook -i inventory_aws_ec2.yml ansible/site.ymlInventário dinâmico por tags
yaml
# inventory_aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions: [us-east-1]
filters:
tag:project: cloudshop
tag:env: staging
instance-state-name: running
keyed_groups:
- key: tags.role
prefix: role
hostnames:
- private-ip-addressNota de segurança: Inventário dinâmico exige credenciais de leitura EC2. Use a mesma role OIDC do pipeline, sem chave estática.
Plan no PR com scanners
yaml
jobs:
plan:
runs-on: ubuntu-latest
permissions: { contents: read, id-token: write, pull-requests: write }
defaults: { run: { working-directory: infra/envs/dev } }
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- uses: aws-actions/configure-aws-credentials@v4
with: { role-to-assume: arn:aws:iam::123456789012:role/tf-plan-readonly, aws-region: us-east-1 }
- run: terraform init -input=false
- run: terraform fmt -check && terraform validate
- run: trivy config --exit-code 1 --severity HIGH,CRITICAL .
- run: terraform plan -input=false -no-color -out tfplan | tee plan.txtPor que isso importa
Provisionar e configurar em um fluxo único e auditável é exatamente o que a vaga chama de automação de infraestrutura.
Erro comum
Aplicar Terraform da máquina local e depois não saber quem mudou o quê.
Dica de produção
Comente o plano no PR automaticamente: revisão de infraestrutura fica acessível a todo o time.
Alerta de segurança
Nunca dê permissão de apply a workflow disparado por PR de fork.
Pergunta de entrevista
Como você conecta a saída do Terraform à configuração feita pelo Ansible?
Glossário
- inventário dinâmico
- Inventário gerado consultando a API da nuvem em vez de arquivo fixo.
- output
- Valor exportado pelo Terraform para consumo por outras ferramentas.
- golden image
- Imagem de máquina pré-configurada e versionada.
- Packer
- Ferramenta para construir imagens de máquina de forma automatizada.
- tflint
- Linter para código Terraform.
Conexão com o CloudShop
Automatizar provisionamento e configuração do staging do CloudShop em um único fluxo.
Quiz da aula
1. Onde o apply do Terraform deve rodar em um time maduro?
2. Por que separar role de plan e role de apply?
3. Vantagem da golden image?
Minhas anotações
Salvo automaticamente neste navegador.