(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

CI/CD Terraform con GitHub Actions: validar y planificar

João Barros 24 de July de 2026 3 min de lectura

Automatizar la validación y la planificación de Terraform con GitHub Actions acelera las revisiones y reduce errores humanos. Este tutorial muestra cómo configurar una pipeline que ejecuta terraform fmt, init, validate y terraform plan y publica el resultado como comentario en el Pull Request. Al automatizar estos pasos, se pueden detectar problemas antes del merge y dar contexto a las decisiones de infraestructura a los revisores — por ejemplo, saber que un terraform plan prevé la creación de 3 recursos y la modificación de 1, sin tener que ejecutar comandos localmente.

Prerrequisitos

  • Cuenta GitHub con repositorio (público o privado). Se recomienda repositorio con rama protegida y políticas de revisión.
  • Conocimientos básicos de Terraform (ficheros .tf). Saber ejecutar terraform init, terraform plan e interpretar la salida.
  • Git y GitHub CLI básicos para crear ramas y Pull Requests. Un flujo típico: rama con hasta 10 cambios .tf por PR es más fácil de revisar.
  • Secrets en GitHub (providers/credentials) cuando sea necesario. Para un repositorio con 1-2 providers, añada las variables necesarias como secrets.

Paso 1: Estructura mínima del repositorio Terraform

Cree una estructura simple con un main.tf de ejemplo. Mantenemos el backend local por simplicidad — en producción use un backend remoto (S3, Azure Storage, etc.). Una estructura mínima para un módulo o entorno puede ser:

# main.tf
resource "null_resource" "exemplo" {
  provisioner "local-exec" {
    command = "echo Hello"
  }
}

Sugerencia práctica: mantenga el repositorio organizado por carpetas por entorno (por ejemplo, environments/dev, environments/prod) y limite cada PR a un entorno cuando sea posible. Para un repositorio con 20-50 ficheros .tf, la pipeline sigue funcionando — el tiempo de ejecución aumenta según el número de providers y módulos, típicamente entre 10s y 2min para init+validate en proyectos pequeños.

Paso 2: Crear el workflow de GitHub Actions

Crear un workflow en .github/workflows/terraform.yml que ejecute los pasos: checkout, setup-terraform, terraform fmt, terraform init, terraform validate, terraform plan y publicar el plan en el PR. Usamos actions oficiales para simplificar y garantizar versiones estables.

name: Terraform CI

on:
  pull_request:
    paths:
      - '**/*.tf'

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v4

    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v2
      with:
        terraform_version: 1.5.0

    - name: Terraform fmt
      run: terraform fmt -check -recursive

    - name: Terraform init
      run: terraform init -input=false

    - name: Terraform validate
      run: terraform validate

    - name: Terraform plan
      id: plan
      run: |
        terraform plan -no-color -out=plan.tfplan || true
        terraform show -no-color plan.tfplan > plan.txt || true
        echo "plan-body<> $GITHUB_OUTPUT
        cat plan.txt >> $GITHUB_OUTPUT
        echo "EOF" >> $GITHUB_OUTPUT

    - name: Comment plan on PR
      uses: peter-evans/create-or-update-comment@v3
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        issue-number: ${{ github.event.pull_request.number }}
        body: |
          **Terraform Plan**

          
Mostrar output del plan (abrir) ``` ${{ steps.plan.outputs.plan-body }} ```

Notas prácticas: usar -no-color facilita la lectura en comentarios. El paso terraform plan está usando || true para garantizar que, incluso con exit code>0, capturamos la salida y comentamos en el PR — ideal para diagnosticar errores sin bloquear la publicación del comentario.

Paso 3: Configurar secrets y providers

Si su Terraform usa providers que requieren credenciales (AWS, Azure, GCP), añada los secrets en GitHub (Settings > Secrets > Actions). Ejemplo para AWS:

- name: Configure AWS creds
  if: env.AWS_REQUIRED == 'true'
  run: |
    echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
    echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV

Ejemplo práctico: para un proyecto pequeño, defina 3 secrets (ACCESS_KEY, SECRET_KEY y REGION). Verifique que el token de GitHub Actions tiene permisos para comentar PRs (GITHUB_TOKEN tiene permisos por defecto, pero para repositorios con restricciones puede ser necesario un token personal con permisos limitados).

Paso 4: Manejar errores comunes

Errores típicos y soluciones rápidas:

  • terraform fmt -check falla: ejecutar terraform fmt localmente o ajustar el CI para corregir automáticamente usando terraform fmt -recursive. En equipos, configure un pre-commit hook para evitar estos errores — puede reducir fallos en CI en ~30%.
  • Fallo de autenticación del provider: confirmar secrets en el repositorio y variables de entorno en el workflow. Verifique también el tiempo de vida de las claves (rutina de rotación cada 90 días es común).
  • terraform plan falla con exit code >0: capturamos la salida y continuamos el job con || true para poder comentar el plan; analice la salida en el comentario. Si el plan falla por falta de state remoto, verifique backend y locks.

Verificar el resultado

Abra una rama, haga cambios en los .tf y cree un Pull Request. Acceda a la pestaña Actions del PR y verifique que el workflow se ejecutó con éxito. En el propio Pull Request debería aparecer un comentario con la salida del terraform plan — si el comentario no aparece, verifique los logs del paso Comment plan on PR y el permiso del GITHUB_TOKEN. En proyectos con CI medio, el tiempo total desde el push hasta el comentario es típicamente 30s–3min.

Conclusión

Con esta pipeline básica de CI para Terraform, gana automatización en las revisiones y reduce riesgos de regresión. Próximos pasos recomendados: mover el state a un backend remoto (S3/Backend de Azure), añadir job de terraform fmt automático que corrija ficheros, y condicionar terraform apply a ramas protegidas con aprobación manual. Pequeñas mejoras, como bloquear merges sin comentarios de plan o añadir análisis de drift, pueden reducir incidentes en producción en decenas de porcentajes. Consejo: ¿quiere que incluya un ejemplo con backend remoto (S3/Consul/Azure Storage) y locks en el workflow?