Como criar um ambiente de Testing Automatizado com Terraform e GitHub Actions
Este tutorial mostra como criar um pipeline que usa Terraform e GitHub Actions para levantar um ambiente efémero de testes e apagá‑lo automaticamente. Útil para testar alterações de infraestruturas sem poluir a conta Azure/AWS e reduzir custos.
Pré-requisitos
- Conta Azure ou AWS com permissões para criar recursos (ou um ambiente local como Docker para exemplo simplificado).
- Repositório GitHub com permissões para GitHub Actions.
- Terraform instalado localmente para testar e validar os ficheiros.
- Conhecimentos básicos de Terraform e GitHub Actions.
Passo 1: Conceito e organização dos ficheiros
Explica‑se o porquê: um ambiente efémero é criado por branch/pull request, usado para testes e removido no merge/fecho. Vamos separar a configuração Terraform e o workflow do GitHub Actions.
# Estrutura mínima do repositório
/
├─ terraform/
│ ├─ main.tf
│ ├─ variables.tf
│ └─ outputs.tf
└─ .github/workflows/terraform-testing.yml
Passo 2: Terraform mínimo para ambiente de exemplo
Aqui um exemplo simples que cria uma VM/instância ou, para facilitar sem cloud, um recurso local (ex.: null_resource). Use isto para validar a lógica de create/destroy.
# terraform/main.tf
terraform {
required_providers {
null = {
source = "hashicorp/null"
version = "~> 3.0"
}
}
}
provider "null" {}
resource "null_resource" "test_env" {
triggers = {
branch = var.branch_name
}
}
output "env_id" {
value = null_resource.test_env.id
}
# terraform/variables.tf
variable "branch_name" {
type = string
default = "local"
}
Passo 3: Workflow GitHub Actions para criar e destruir
O workflow executa terraform init/plan/apply ao abrir uma pull request e faz destroy quando a PR é fechada ou quando o branch é removido. Usa um naming único por branch.
# .github/workflows/terraform-testing.yml
name: Terraform Testing Env
on:
pull_request:
types: [opened, reopened, synchronize]
pull_request_target:
types: [closed]
jobs:
apply:
if: github.event_name == 'pull_request' && github.event.action != 'closed'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: '1.5.0'
- name: Terraform Init
working-directory: terraform
run: terraform init -input=false
- name: Terraform Apply
working-directory: terraform
env:
TF_VAR_branch_name: ${{ github.head_ref }}
run: terraform apply -auto-approve -input=false
destroy:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: '1.5.0'
- name: Terraform Init
working-directory: terraform
run: terraform init -input=false
- name: Terraform Destroy
working-directory: terraform
env:
TF_VAR_branch_name: ${{ github.head_ref }}
run: terraform destroy -auto-approve -input=false
Passo 4: Gestão de state e segredos
Se usar recursos reais na cloud, nunca guarde o state local no runner. Configure um backend remoto (ex.: Azure Storage, S3) e use secrets no GitHub para credenciais. Exemplo rápido para backend S3:
# Adicionar ao terraform/main.tf
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "envs/${var.branch_name}.tfstate"
region = "eu-west-1"
}
}
Passo 5: Erros comuns e como os evitar
Principais problemas: conflitos de state quando vários runs usam a mesma key, falta de permissões da conta do runner, esquecer o destroy em branches abandonados. Soluções: backend por branch, roles/associações de responsabilidade mínimas, limpeza periódica com script cron.
Verificar o resultado
Ao abrir uma pull request verá o job 'Terraform Testing Env' correr e aplicar os recursos. Confirme nos outputs do job o env_id. Ao fechar a PR, verifique que o job de destroy executou e que o recurso foi removido (ou no backend de state não exista o key correspondente).
Conclusão
Tem agora um fluxo básico para criar ambientes efémeros com Terraform e GitHub Actions: cria na PR, testa e destrói no fecho. Próximos passos: trocar null_resource por recursos reais (VM, RDS, Storage), adicionar testes automáticos que corram contra o ambiente e suportar locks de state. Dica: comece por testar localmente com terraform plan e depois simule o runner usando act para validar o workflow.