Infrastructure as Code (IaC) ha revolucionado cómo aprovisionamos y gestionamos infraestructura, tratando la configuración de infraestructura como software. Así como probamos el código de aplicaciones, IaC requiere testing riguroso para prevenir errores costosos, vulnerabilidades de seguridad e interrupciones de servicio. Un solo cambio de infraestructura no probado puede derribar sistemas de producción, comprometer la seguridad o generar costos inesperados en la nube.

Esta guía comprensiva explora estrategias de testing para las principales herramientas IaC incluyendo Terraform, Ansible y CloudFormation (como se discute en AI Copilot for Test Automation: GitHub Copilot, Amazon CodeWhisperer and the Future of QA), junto con la implementación de Compliance as Code para asegurar que la infraestructura cumple con los estándares organizacionales y requisitos regulatorios.

Entendiendo el Testing de Infrastructure as Code

¿Por Qué Probar el Código de Infraestructura?

A diferencia del código de aplicación donde los bugs pueden afectar características, los errores de IaC pueden:

  • Causar interrupciones completas del servicio: Configuraciones inválidas pueden destruir recursos de producción
  • Crear vulnerabilidades de seguridad: Controles de acceso mal configurados exponen sistemas a ataques
  • Generar costos masivos: El aprovisionamiento no intencionado de recursos puede costar miles por hora
  • Violar requisitos de cumplimiento: Infraestructura no conforme arriesga penalidades legales y financieras
  • Crear drift e inconsistencia: Cambios no probados llevan a drift de configuración entre entornos

Niveles de Testing IaC

El testing IaC sigue una pirámide similar al testing de aplicaciones:

NivelPropósitoHerramientasVelocidadCobertura
Análisis EstáticoValidación de sintaxis, linting, escaneo de seguridadtflint, ansible-lint, cfn-lintRápido (segundos)Alta
Pruebas UnitariasProbar módulos/recursos individuales aisladamenteTerratest, Molecule, TaskCatMedio (minutos)Media
Pruebas de IntegraciónProbar interacciones y dependencias de recursosTerratest, Kitchen, InSpecLento (10-30 min)Media
Pruebas End-to-EndDesplegar infraestructura completa y validarTerratest, ServerspecMuy Lento (30+ min)Baja
Testing de CumplimientoValidar contra políticas y estándaresOPA, Sentinel, Cloud CustodianRápido (segundos)Alta

Testing de Terraform

Terraform es la herramienta IaC más popular, soportando múltiples proveedores de nube con un lenguaje de configuración declarativo.

Análisis Estático con tflint

tflint verifica el código Terraform para errores potenciales, sintaxis obsoleta y mejores prácticas.

Instalación:

# macOS
brew install tflint

# Linux
curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash

Configuración (.tflint.hcl):

plugin "aws" {
  enabled = true
  version = "0.25.0"
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

config {
  module = true
  force = false
}

rule "terraform_deprecated_interpolation" {
  enabled = true
}

rule "terraform_naming_convention" {
  enabled = true
  format  = "snake_case"
}

Ejecutando tflint:

# Inicializar plugins
tflint --init

# Lint directorio actual
tflint

# Formatos de salida
tflint --format=json
tflint --format=checkstyle > tflint-report.xml

Escaneo de Seguridad con tfsec

tfsec escanea código Terraform para problemas de seguridad y configuraciones incorrectas.

Instalación:

# macOS
brew install tfsec

# Docker
docker run --rm -it -v "$(pwd):/src" aquasec/tfsec /src

Ejecutando tfsec:

# Escanear directorio actual
tfsec .

# Formatos de salida
tfsec . --format=json > tfsec-results.json
tfsec . --format=junit > tfsec-report.xml

# Excluir verificaciones específicas
tfsec . --exclude=aws-s3-enable-bucket-encryption

# Establecer severidad mínima
tfsec . --minimum-severity=HIGH

Pruebas Unitarias con Terratest

Terratest es una librería Go para probar código de infraestructura desplegándolo realmente en entornos reales.

Instalación:

# Inicializar módulo Go
go mod init github.com/company/terraform-tests

# Instalar Terratest
go get github.com/gruntwork-io/terratest/modules/terraform

Ejemplo Terratest (vpc_test.go):

package test

import (
	"testing"
	"github.com/gruntwork-io/terratest/modules/terraform"
	"github.com/stretchr/testify/assert"
)

func TestVPCCreation(t *testing.T) {
	t.Parallel()

	terraformOptions := &terraform.Options{
		TerraformDir: "../examples/vpc",
		Vars: map[string]interface{}{
			"vpc_name": "test-vpc",
			"vpc_cidr": "10.0.0.0/16",
		},
	}

	defer terraform.Destroy(t, terraformOptions)
	terraform.InitAndApply(t, terraformOptions)

	vpcID := terraform.Output(t, terraformOptions, "vpc_id")
	assert.NotEmpty(t, vpcID)
}

Ejecutando Terratest:

# Ejecutar todas las pruebas
go test -v -timeout 30m

# Ejecutar prueba específica
go test -v -timeout 30m -run TestVPCCreation

# Ejecutar pruebas en paralelo
go test -v -timeout 45m -parallel 3

Testing de Playbooks de Ansible

Ansible automatiza la gestión de configuración y el despliegue de aplicaciones usando playbooks YAML.

Ansible Lint

ansible-lint verifica playbooks para errores comunes y mejores prácticas.

Instalación:

pip install ansible-lint

Configuración (.ansible-lint):

profile: production

exclude_paths:
  - .cache/
  - .github/
  - test/fixtures/

skip_list:
  - experimental
  - galaxy

rules:
  line-length:
    max: 160

Ejecutando ansible-lint:

# Lint todos los playbooks
ansible-lint

# Lint playbook específico
ansible-lint playbooks/deploy.yml

# Formatos de salida
ansible-lint --format=json > lint-results.json

Molecule: Framework de Testing de Ansible

Molecule proporciona un framework completo de testing para roles y playbooks de Ansible.

Instalación:

pip install molecule molecule-docker ansible-lint

Inicializar nuevo role con Molecule:

molecule init role my_role --driver-name=docker

Configuración de Molecule (molecule/default/molecule.yml):

---
dependency:
  name: galaxy

driver:
  name: docker

platforms:
  - name: ubuntu-20
    image: geerlingguy/docker-ubuntu2004-ansible:latest
    pre_build_image: true
    privileged: true

provisioner:
  name: ansible

verifier:
  name: ansible

lint: |
  set -e
  yamllint .
  ansible-lint .

Playbook de prueba de Molecule (molecule/default/verify.yml):

---
- name: Verify
  hosts: all
  tasks:
    - name: Check if Nginx is installed
      package:
        name: nginx
        state: present
      check_mode: true
      register: nginx_install
      failed_when: nginx_install.changed

    - name: Verify Nginx is listening on port 80
      wait_for:
        port: 80
        timeout: 5
        state: started

Ejecutando pruebas Molecule:

# Ejecutar secuencia completa de pruebas
molecule test

# Ejecutar pasos específicos
molecule create      # Crear instancias de prueba
molecule converge    # Aplicar playbook
molecule verify      # Ejecutar pruebas de verificación
molecule destroy     # Destruir instancias de prueba

# Modo debug
molecule --debug test

Testing de CloudFormation

AWS CloudFormation usa plantillas JSON o YAML para definir infraestructura.

Linting de CloudFormation con cfn-lint

Instalación:

pip install cfn-lint

Configuración (.cfnlintrc):

templates:
  - templates/**/*.yaml
  - templates/**/*.yml

ignore_checks:
  - E3012

regions:
  - us-east-1
  - us-west-2

Ejecutando cfn-lint:

# Lint plantilla
cfn-lint template.yaml

# Lint todas las plantillas
cfn-lint templates/**/*.yaml

# Formatos de salida
cfn-lint template.yaml --format json
cfn-lint template.yaml --format junit > cfn-lint-results.xml

Validación de CloudFormation

# Validar sintaxis de plantilla
aws cloudformation validate-template --template-body file://template.yaml

# Estimar costo
aws cloudformation estimate-template-cost \
  --template-body file://template.yaml \
  --parameters file://parameters.json

Compliance as Code

Compliance as Code automatiza la aplicación de políticas, asegurando que la infraestructura cumple con estándares de seguridad, regulatorios y organizacionales.

Open Policy Agent (OPA)

OPA proporciona control basado en políticas usando el lenguaje Rego.

Instalación:

# macOS
brew install opa

# Linux
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64
chmod +x opa

Ejemplo de política (terraform.rego):

package terraform.analysis

# Denegar buckets S3 sin cifrado
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_s3_bucket"
    not resource.change.after.server_side_encryption_configuration
    msg := sprintf("S3 bucket '%s' debe tener cifrado habilitado", [resource.address])
}

# Denegar grupos de seguridad con ingreso sin restricciones
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_security_group"
 (como se discute en [Shift-Left Testing: Early Problem Detection Strategy](/blog/shift-left-testing-early-detection))    rule := resource.change.after.ingress[_]
    "0.0.0.0/0" in rule.cidr_blocks
    msg := sprintf("Security (como se discute en [Monitoring and Observability for QA: Complete Guide](/blog/monitoring-observability-for-qa)) group '%s' permite acceso sin restricciones", [resource.address])
}

# Requerir etiquetas específicas
required_tags := ["Environment", "Owner", "CostCenter"]

deny[msg] {
    resource := input.resource_changes[_]
    tags := object.get(resource.change.after, "tags", {})
    missing := [tag | tag := required_tags[_]; not tags[tag]]
    count(missing) > 0
    msg := sprintf("Recurso '%s' falta etiquetas requeridas: %v", [resource.address, missing])
}

Probando Terraform con OPA:

# Generar plan de Terraform
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json

# Evaluar política
opa eval --data terraform.rego --input tfplan.json "data.terraform.analysis.deny"

Checkov: Escáner de Código de Infraestructura

Checkov escanea IaC para problemas de seguridad y cumplimiento.

Instalación:

pip install checkov

Ejecutando Checkov:

# Escanear Terraform
checkov -d .

# Escanear archivo específico
checkov -f main.tf

# Escanear CloudFormation
checkov -f template.yaml --framework cloudformation

# Formatos de salida
checkov -d . --output json > checkov-results.json
checkov -d . --output junitxml > checkov-results.xml

# Omitir verificaciones específicas
checkov -d . --skip-check CKV_AWS_18,CKV_AWS_19

Mejores Prácticas para Testing IaC

  1. Probar en aislamiento: Usar cuentas/proyectos separados para testing
  2. Limpiar recursos: Siempre destruir infraestructura de prueba
  3. Usar datos realistas: Probar con configuraciones similares a producción
  4. Control de versiones de pruebas: Almacenar pruebas junto con código de infraestructura
  5. Automatizar todo: Ejecutar pruebas en pipelines CI/CD
  6. Monitorear costos: Rastrear gastos en infraestructura de prueba
  7. Paralelizar pruebas: Acelerar retroalimentación con ejecución paralela
  8. Documentar políticas: Hacer claros los requisitos de cumplimiento
  9. Actualizaciones regulares de políticas: Mantener reglas de seguridad actuales
  10. Medir cobertura: Rastrear qué está probado y qué no

Conclusión

El testing de Infrastructure as Code es esencial para mantener infraestructura confiable, segura y conforme. Combinando análisis estático, pruebas unitarias, pruebas de integración y prácticas de compliance-as-code, los equipos pueden detectar problemas temprano, prevenir desastres en producción y mantener altos estándares de calidad de infraestructura.

La clave es implementar múltiples capas de testing — desde verificaciones estáticas rápidas hasta pruebas de despliegue comprehensivas — y automatizarlas en pipelines CI/CD. Comienza con validación y linting básicos, luego añade progresivamente testing más sofisticado a medida que tu infraestructura crece en complejidad.

Puntos Clave:

  • IaC requiere el mismo rigor que el testing de código de aplicación
  • El análisis estático captura la mayoría de problemas antes del despliegue
  • Las pruebas unitarias y de integración validan el comportamiento real de la infraestructura
  • Compliance as Code automatiza la aplicación de políticas
  • Múltiples capas de testing proporcionan defensa en profundidad
  • La automatización en CI/CD asegura testing consistente
  • Limpia recursos de prueba para controlar costos
  • Documenta y versiona todas las pruebas y políticas