Prueba el contrato de un módulo

ShellBeginner
Practicar Ahora

Introducción

Una configuración puede tener el formato correcto y una estructura válida y, aun así, etiquetar incorrectamente un entorno de informes. Tu equipo necesita comprobaciones ejecutables de las entradas, las salidas y las etiquetas previstas de un pequeño módulo de almacenamiento antes de confiar en un plan de entrega.

Escribirás un contrato de módulo, probarás dos entornos admitidos y una entrada no admitida, y harás que un defecto real de negocio detenga la tarea. Debes comprender las variables y salidas de los módulos y los controles de formato y validación del laboratorio anterior. El almacenamiento de referencia existente debe permanecer sin cambios.

Relación con las certificaciones

Certificación Tarea del examen Práctica
DevOps Engineer – Professional (DOP-C02) Tarea 1.2 Práctica básica de integración de aserciones ejecutables de módulos en un control de calidad automatizado.

Las entradas del módulo se comprueban mediante aserciones en modo de planificación antes de un plan de entrega, mientras se conserva el almacenamiento de referencia.

Define el contrato de entradas

En este paso, definirás qué entradas de entorno acepta el módulo de almacenamiento. La validación de entradas rechaza una solicitud no admitida antes de crear un plan de recursos.

Entra en el módulo suministrado y carga las herramientas preparadas.

cd /home/labex/project/report-module
source environment.sh

Lee su interfaz y la implementación de recursos.

cat variables.tf main.tf outputs.tf pipeline.json

environment selecciona preview o review; bucket_prefix distingue los nombres de almacenamiento de quien invoca el módulo. El nombre del bucket combina ambas entradas, y la etiqueta Environment y la salida deben identificar el entorno solicitado. Los archivos suministrados main.tf, outputs.tf, provider.tf y run-job.py deben conservarse: mantén su contenido final sin cambios. Tu trabajo corresponde a variables.tf, tests/ y pipeline.json.

Añade un bloque validation a environment. contains comprueba la pertenencia a la lista admitida; una condition falsa produce el mensaje de error proporcionado. El documento incrustado entre comillas escribe HCL literal.

cat > variables.tf <<'EOF'
variable "environment" {
  type    = string
  default = "preview"
  validation {
    condition     = contains(["preview", "review"], var.environment)
    error_message = "Choose preview or review."
  }
}
variable "bucket_prefix" {
  type    = string
  default = "delivery-contract"
}
EOF

Da formato al cambio.

terraform fmt

Prueba una solicitud no admitida. -var proporciona un valor para esta invocación. Este comando devuelve intencionadamente el código de salida nativo 1; debe indicar Choose preview or review., en lugar de proponer un bucket de producción.

terraform plan -input=false -var=environment=production

La validación define la interfaz aceptada. En el siguiente paso, las pruebas ejercitarán ambos valores aceptados y este rechazo esperado.

Escribe aserciones y observa un fallo real

En este paso, usarás el comando nativo terraform test para comprobar el comportamiento previsto del módulo. El formato y la validación pueden aceptar una salida fijada en el código pero incorrecta; una aserción compara el resultado calculado con la entrada solicitada.

Terraform lee archivos .tftest.hcl en tests/. Cada run es un escenario de prueba independiente. La declaración explícita command = plan evalúa un plan sin aplicarlo. Mantén los archivos de prueba en tests/ con el formato .tftest.hcl. En este laboratorio, cada ejecución debe usar el modo de planificación y el proveedor y módulo suministrados; los módulos alternativos, los proveedores simulados y las sobrescrituras quedan fuera de la tarea. Mantén bucket_prefix heredado de la entrada del conjunto de pruebas: no le asignes un valor en las variables de prueba del archivo ni de una ejecución, para que quien invoque las pruebas pueda seleccionar otro prefijo legítimo. Estas pruebas comprueban valores conocidos del plan, no la creación real, los permisos en ejecución ni una aplicación desplegada.

Crea el directorio de pruebas. mkdir -p lo crea si es necesario y acepta un directorio existente.

mkdir -p tests

Escribe aserciones para el entorno predeterminado y el alternativo. var hace referencia a las entradas de la ejecución, las referencias a recursos inspeccionan los valores previstos y output hace referencia a las salidas del módulo. expect_failures exige que falle la validación de la variable indicada; no convierte errores arbitrarios del proveedor o de red en pruebas correctas.

cat > tests/contract.tftest.hcl <<'EOF'
run "preview_contract" {
  command = plan
  assert {
    condition     = output.environment == var.environment
    error_message = "The output must identify the requested environment."
  }
  assert {
    condition     = aws_s3_bucket.reports.bucket == "${var.bucket_prefix}-${var.environment}"
    error_message = "The bucket name must use the requested prefix and environment."
  }
  assert {
    condition     = aws_s3_bucket.reports.tags.Environment == var.environment
    error_message = "The planned tag must identify the requested environment."
  }
}
run "review_contract" {
  command = plan
  variables { environment = "review" }
  assert {
    condition     = output.environment == var.environment
    error_message = "The alternate environment must not use the default label."
  }
  assert {
    condition     = aws_s3_bucket.reports.bucket == "${var.bucket_prefix}-${var.environment}"
    error_message = "The alternate bucket must use its requested inputs."
  }
  assert {
    condition     = aws_s3_bucket.reports.tags.Environment == var.environment
    error_message = "The alternate environment tag must match its input."
  }
}
run "unsupported_environment" {
  command         = plan
  variables { environment = "production" }
  expect_failures = [var.environment]
}
EOF

Da formato recursivamente a las pruebas y a los archivos del módulo.

terraform fmt -recursive

Ejecuta el conjunto de pruebas.

terraform test

Deben superarse tres ejecuciones y aparecer un resumen de éxito. No se despliega ningún bucket de prueba. Los valores de entrada y salida proceden de un plan real de Terraform que usa el proveedor configurado.

Demuestra que tus aserciones detectan un defecto plausible. Sustituye temporalmente solo la salida del entorno por una etiqueta predeterminada fija; conserva la salida del nombre del bucket.

cat > outputs.tf <<'EOF'
output "environment" {
  value = "preview"
}
output "bucket_name" {
  value = aws_s3_bucket.reports.bucket
}
EOF

Vuelve a ejecutar las pruebas. Este comando devuelve intencionadamente el código de salida nativo 1. La aserción del entorno alternativo debe fallar, mostrando que un HCL válido puede incumplir el contrato del módulo.

terraform test

Restaura desde Git la implementación suministrada de las salidas. Esto elimina el defecto temporal y conserva la validación y las pruebas que has escrito.

git restore -- outputs.tf

Ejecuta la implementación corregida con las mismas aserciones.

terraform test

Todas las ejecuciones deben superar las pruebas de nuevo. Las pruebas deben aceptar entradas legítimas, en lugar de reconocer únicamente una salida predeterminada.

Haz que las pruebas detengan la tarea de entrega

En este paso, colocarás las pruebas del módulo entre los controles estáticos y la planificación. El ejecutor suministrado forma parte de la preparación; edita la configuración de etapas en lugar de cambiar run-job.py.

Añade test después de fmt/validate y antes de plan.

cat > pipeline.json <<'EOF'
{"stages":["fmt","validate","test","plan"]}
EOF

Ejecuta la tarea completa.

python3 run-job.py

Deben superarse las cuatro etapas. El plan final puede devolver el código nativo 2 porque este módulo no se ha aplicado; el ejecutor lo considera una vista previa correcta. En cambio, una prueba fallida debe detener la tarea antes de su etapa de planificación. No existe ninguna etapa de aplicación.

Ejecuta el conjunto de pruebas con otro prefijo legítimo de bucket. Este -var cambia la entrada del conjunto de pruebas sin editar el módulo ni sus pruebas.

terraform test -var=bucket_prefix=audit-contract

Deben superarse las mismas tres ejecuciones. Para este ejercicio, mantén bucket_prefix heredado de quien invoca las pruebas en todas las ejecuciones: no le asignes un valor en bloques variables del archivo de pruebas ni de una ejecución. Esas asignaciones sobrescriben las entradas de prueba de la CLI e impedirían que este comando ejercitara el prefijo solicitado. Las sobrescrituras de entorno siguen siendo necesarias para probar ambos entornos admitidos. Las aserciones construidas a partir de las entradas solicitadas siguen funcionando cuando quien invoca las pruebas elige otro nombre válido.

Lee el informe de referencia existente directamente del almacenamiento. Estos buckets preparados pertenecen a otro entorno; no los destruyas ni los modifiques.

aws s3   cp s3://delivery-reference-reports/report.txt -

Debe seguir diciendo reference report v1. Comprueba también los datos vecinos.

aws s3   cp s3://delivery-reference-neighbor/keep.txt -

Debes ver preserve contract neighbor. Tus pruebas no han creado recursos de almacenamiento, por lo que no hay ningún conjunto de recursos de prueba que destruir. Conserva el contrato de entradas, las pruebas y la configuración de la canalización para la comprobación final; el defecto temporal de la salida ya se ha eliminado.

Resumen

Has definido un contrato de entradas admitidas, usado pruebas nativas de Terraform en modo de planificación para comparar las salidas y etiquetas previstas con las entradas y observado un fallo real de una aserción. Después has incorporado las pruebas al control de calidad de entrega conservando los datos existentes y el estado de negocio.

Las pruebas en modo de planificación no demuestran el comportamiento desplegado. Los pasos posteriores de entrega combinan estas comprobaciones con un plan concreto revisado y una aplicación real controlada. Consulta la referencia oficial de Terraform test y la documentación de configuración de pruebas para conocer los mecanismos practicados aquí.