Nesta aula, vamos consolidar os conceitos de Infraestrutura como Código (IaC) aplicados a um projeto real. Você aprenderá a definir recursos de forma declarativa, gerenciar o estado da infraestrutura, organizar ambientes (desenvolvimento, homologação, produção) e versionar tudo corretamente. Utilizaremos o Terraform como ferramenta principal, com exemplos em bash para comandos de linha de comando.

O objetivo é que, ao final, você seja capaz de estruturar um projeto IaC do zero, seguindo as melhores práticas de DevOps, garantindo reprodutibilidade, rastreabilidade e segurança.

Definindo recursos

Em IaC, recursos são os componentes da infraestrutura (máquinas virtuais, redes, bancos de dados, etc.) que declaramos em código. No Terraform, cada recurso é definido em um bloco resource com um tipo e um nome. A sintaxe básica é:

resource "tipo_recurso" "nome_identificador" {
  argumento1 = valor1
  argumento2 = valor2
}

Por exemplo, para criar uma instância EC2 na AWS:

resource "aws_instance" "servidor_web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "Servidor Web"
  }
}

Além de recursos, é importante definir provedores (como AWS, Azure, GCP) e variáveis para tornar o código reutilizável. Uma boa prática é separar os recursos em módulos, facilitando a manutenção e reutilização.

Estado

O estado é o registro do mapeamento entre os recursos declarados no código e os recursos reais provisionados. O Terraform armazena esse estado em um arquivo chamado terraform.tfstate. Ele é fundamental para que o Terraform saiba o que já foi criado e possa atualizar ou destruir recursos com segurança.

O estado deve ser tratado com cuidado, pois contém informações sensíveis. Para projetos em equipe, é essencial usar um backend remoto (como S3, Terraform Cloud, ou Azure Storage) para armazenar o estado de forma centralizada e com controle de versão. Exemplo de configuração de backend S3:

terraform {
  backend "s3" {
    bucket = "meu-bucket-estado"
    key    = "infra/terraform.tfstate"
    region = "us-east-1"
  }
}

Além disso, é recomendável habilitar o lock (bloqueio) do estado para evitar que múltiplas pessoas alterem a infraestrutura simultaneamente. Com o DynamoDB, por exemplo, conseguimos isso.

Ambientes

Ambientes (dev, staging, prod) são essenciais para isolar mudanças e garantir estabilidade. Com IaC, podemos gerenciar cada ambiente com a mesma base de código, apenas variando configurações. Uma abordagem comum é usar workspaces do Terraform ou diretórios separados para cada ambiente.

Com workspaces, você pode ter o mesmo código e alternar entre ambientes com o comando terraform workspace select. Exemplo:

terraform workspace new dev
terraform workspace new prod
terraform workspace select dev

Outra estratégia é usar arquivos de variáveis específicos por ambiente, como dev.tfvars e prod.tfvars, e aplicar com terraform apply -var-file="dev.tfvars". Isso permite definir tamanhos de máquina, configurações de rede, etc., de acordo com o ambiente.

Versionamento

Versionar a infraestrutura como código é um dos pilares do IaC. Isso permite rastrear mudanças, reverter alterações e colaborar em equipe. Use Git para versionar todos os arquivos do projeto, incluindo os arquivos .tf, scripts e documentação. É importante adicionar o arquivo de estado ao .gitignore, pois ele não deve ser versionado (contém dados sensíveis e é gerado dinamicamente).

Além do Git, é crucial versionar também os módulos e provedores. No Terraform, você pode fixar versões dos provedores no arquivo versions.tf:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

Boas práticas incluem: usar branches para desenvolvimento, fazer code review antes de aplicar, e usar pipelines de CI/CD para automatizar a aplicação da infraestrutura (como GitHub Actions ou GitLab CI).

Boas práticas e observações finais

Ao provisionar infraestrutura com IaC, lembre-se de:

  • Manter o código limpo e comentado.
  • Usar módulos para componentes reutilizáveis.
  • Nunca editar o estado manualmente; sempre use terraform apply.
  • Documentar o projeto com um README explicando como executar.
  • Automatizar o máximo possível com pipelines.

Essas práticas garantem que sua infraestrutura seja tratada como software, com todos os benefícios de versionamento, teste e colaboração.

Referências

Exercícios

  1. Defina um recurso: Escreva um bloco de recurso no Terraform para criar um bucket S3 privado na AWS. Inclua as tags obrigatórias.
  2. ✓ Resposta:
    resource "aws_s3_bucket" "meu_bucket" {
      bucket = "meu-bucket-iaac-2025"
      acl    = "private"
      tags = {
        Name        = "Meu Bucket"
        Environment = "Dev"
      }
    }
  3. Configuração de backend: Explique por que devemos usar um backend remoto para o estado e dê um exemplo de configuração para o Terraform Cloud.
  4. ✓ Resposta: Usar backend remoto é essencial para equipes, pois permite compartilhar o estado, bloquear acesso concorrente e manter o histórico. Exemplo:
    terraform {
      backend "remote" {
        organization = "minha-org"
        workspaces {
          name = "infra-prod"
        }
      }
    }
  5. Ambientes com workspaces: Crie os comandos para criar e usar um workspace chamado "staging" e aplicar a configuração.
  6. ✓ Resposta:
    terraform workspace new staging
    terraform workspace select staging
    terraform apply
  7. Versionamento de provedores: Escreva um arquivo versions.tf que fixa a versão do provedor AWS para a versão 4.x, mas permita atualizações de patch.
  8. ✓ Resposta:
    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 4.0"
        }
      }
    }
  9. Gitignore: Liste pelo menos três arquivos que devem estar no .gitignore de um projeto Terraform e explique o motivo.
  10. ✓ Resposta: Arquivos a ignorar: terraform.tfstate (contém dados sensíveis), terraform.tfstate.backup (backup do estado), .terraform/ (contém plugins e módulos baixados). Eles não devem ser versionados pois são gerados localmente e podem conter informações críticas.