0 XP
Módulo 7 · Terraform e Ansible

Terraform e Ansible juntos no fluxo de entrega

Avançado 45 min+25 XPTerraformAnsibleGitHub Actions

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

  1. PR: fmt, validate, tflint, checkov/trivy config, plan comentado no PR
  2. Revisão humana do plan
  3. Merge: apply com o plano aprovado
  4. Ansible aplica configuração
  5. 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.yml

Inventá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-address

Nota 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.txt

Por 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. 1. Onde o apply do Terraform deve rodar em um time maduro?

  2. 2. Por que separar role de plan e role de apply?

  3. 3. Vantagem da golden image?

Minhas anotações

Salvo automaticamente neste navegador.

AnteriorPróxima