Última revisión: mayo de 2026
Crea los servicios de AWS del examen DOP-C02 con Terraform puro: bloque a bloque, cada uno vinculado a un dominio del examen. El mismo código funciona en OpenTofu.
Al finalizar este laboratorio, habrá aprovisionado, con Terraform puro, una completa canalización de código a producción: un repositorio Git de CodeCommit, un proyecto CodeBuild que ejecuta su conjunto de pruebas y empaqueta artefactos, una aplicación CodeDeploy que se despliega en un objetivo, una canalización CodePipeline que encadena fuente → construcción → despliegue, y un canary de CloudWatch Synthetics que sondea el endpoint desplegado y emite alarmas cuando deja de responder. Esta es la arquitectura de referencia DOP-C02 en cinco bloques.
Cada recurso es Terraform puro. Inserte los fragmentos en un único main.tf, ejecute terraform init, luego terraform apply paso a paso.
>= 1.5 o OpenTofu >= 1.6.us-east-1.https://example.com; en producción este sería el endpoint de verificación de salud de su aplicación.aws_s3_bucket como fuente de la canalización (CodePipeline admite la fuente S3).Principalmente de pago por uso, sin facturación significativa por inactividad:
BUILD_GENERAL1_SMALL; una compilación de laboratorio cuesta céntimos.Todo el stack cuesta menos de $5/mes en ejecución. Destrúyalo cuando termine.
Introducción estándar. Los servicios de Code* son regionales; elija la región que comparten sus repositorios de origen y entornos de destino. Se usa us-east-1 por defecto para el laboratorio.
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.60"
}
}
}
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Project = "certlabpro-dop-c02"
ManagedBy = "terraform"
}
}
}
resource "aws_s3_bucket" "artifacts" {
bucket_prefix = "certlabpro-dop-c02-artifacts-"
}
resource "aws_s3_bucket_public_access_block" "artifacts" {
bucket = aws_s3_bucket.artifacts.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}CodeCommit es el host Git de AWS. El DOP-C02 evalúa la suite Code* de extremo a extremo como una historia estrechamente integrada; las preguntas de examen más comunes preguntan qué combinación de servicios nativos de AWS logra un resultado determinado, y la respuesta casi siempre comienza con CodeCommit.
El default_branch = "main" coincide con los valores predeterminados modernos de Git (CodeCommit históricamente creaba master). El repositorio que creamos está vacío después de apply; en un uso real, enviaría su primer commit con un buildspec.yml y appspec.yml en la raíz; esos son los archivos que CodeBuild (Paso 3) y CodeDeploy (Paso 4) leen en cada ejecución de la canalización.
resource "aws_codecommit_repository" "app" {
repository_name = "certlabpro-dop-c02-app"
description = "Application source for the DOP-C02 lab pipeline."
default_branch = "main"
}CodeBuild ejecuta los pasos de compilación y prueba de su buildspec.yml. El DOP-C02 evalúa aquí la compensación entre imagen gestionada y imagen personalizada: las imágenes gestionadas no requieren mantenimiento, pero son más lentas en iniciar; las imágenes personalizadas le brindan un inicio en frío más rápido y cadenas de herramientas reproducibles. El laboratorio utiliza la imagen gestionada aws/codebuild/standard:7.0, que cubre Node, Python, Java, Go, .NET y Ruby de forma predeterminada.
El rol de IAM otorga a CodeBuild permiso para escribir en CloudWatch Logs (para la salida de la compilación), leer la fuente de CodeCommit y escribir artefactos en el bucket S3 del Paso 1. LINUX_CONTAINER + BUILD_GENERAL1_SMALL es el nivel más económico con $0.005/minuto de compilación.
resource "aws_iam_role" "codebuild" {
name = "certlabpro-dop-c02-codebuild"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "codebuild.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy" "codebuild" {
name = "build-permissions"
role = aws_iam_role.codebuild.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"]
Resource = "*"
},
{
Effect = "Allow"
Action = ["s3:GetObject", "s3:PutObject", "s3:ListBucket"]
Resource = [aws_s3_bucket.artifacts.arn, "${aws_s3_bucket.artifacts.arn}/*"]
},
{
Effect = "Allow"
Action = "codecommit:GitPull"
Resource = aws_codecommit_repository.app.arn
},
]
})
}
resource "aws_codebuild_project" "build" {
name = "certlabpro-dop-c02-build"
service_role = aws_iam_role.codebuild.arn
source {
type = "CODEPIPELINE"
buildspec = "buildspec.yml"
}
artifacts {
type = "CODEPIPELINE"
}
environment {
type = "LINUX_CONTAINER"
image = "aws/codebuild/standard:7.0"
compute_type = "BUILD_GENERAL1_SMALL"
privileged_mode = false
}
}CodeDeploy gestiona el despliegue real, en EC2, Lambda o ECS. El DOP-C02 evalúa repetidamente el eje de la estrategia de despliegue: AllAtOnce (el más barato, el más arriesgado), HalfAtATime, OneAtATime, CodeDeployDefault.LambdaCanary10Percent5Minutes (el patrón canary de Lambda) y CodeDeployDefault.ECSAllAtOnce. Elegimos la plataforma de computación Lambda para el laboratorio porque no requiere que las instancias EC2 existan realmente, lo que mantiene el laboratorio económico y con un alcance limitado.
La configuración de despliegue CodeDeployDefault.LambdaAllAtOnce es la más simple de las estrategias de Lambda. En producción, LambdaCanary10Percent5Minutes es la respuesta más frecuentemente recomendada en el DOP-C02 para despliegues con mitigación de riesgos: cambia el 10% del tráfico a la nueva versión, espera 5 minutos para las alarmas de CloudWatch y luego cambia el resto si no hay problemas.
resource "aws_iam_role" "codedeploy" {
name = "certlabpro-dop-c02-codedeploy"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "codedeploy.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "codedeploy_lambda" {
role = aws_iam_role.codedeploy.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda"
}
resource "aws_codedeploy_app" "app" {
name = "certlabpro-dop-c02-app"
compute_platform = "Lambda"
}
resource "aws_codedeploy_deployment_group" "lambda" {
app_name = aws_codedeploy_app.app.name
deployment_group_name = "default"
service_role_arn = aws_iam_role.codedeploy.arn
deployment_config_name = "CodeDeployDefault.LambdaAllAtOnce"
deployment_style {
deployment_option = "WITH_TRAFFIC_CONTROL"
deployment_type = "BLUE_GREEN"
}
auto_rollback_configuration {
enabled = true
events = ["DEPLOYMENT_FAILURE"]
}
}CodePipeline es el orquestador que une los tres pasos anteriores en un único grafo: fuente de CodeCommit, compilación con CodeBuild, despliegue con CodeDeploy. Cada transición es un punto de conexión; puede añadir aprobaciones manuales, etapas de prueba paralelas y notificaciones entre dos etapas cualesquiera. El dominio Gestión de la Configuración e IaC del DOP-C02 evalúa repetidamente esta estructura de etapas y acciones.
Una vez que existe la canalización, tiene CI/CD. La última pieza — CloudWatch Synthetics — cierra el círculo de la observabilidad del despliegue: un canary es un script de navegador sin interfaz gráfica gestionado (basado en Puppeteer) que se ejecuta según un horario y reporta el éxito o el fallo a CloudWatch. El dominio Monitorización y Registro del DOP-C02 se apoya fuertemente en este patrón: despliegue un cambio → el canary detecta la regresión en minutos → la reversión automática de CodeDeploy (que configuramos en el Paso 4) se activa desde la alarma de CloudWatch del canary.
El script del canary a continuación sondea https://example.com cada 5 minutos; en producción lo apuntaría al endpoint de salud de su aplicación, con aserciones sobre el cuerpo y las cabeceras de la respuesta, no solo HTTP 200.
# ── CodePipeline ──────────────────────────────────────────────
resource "aws_iam_role" "codepipeline" {
name = "certlabpro-dop-c02-codepipeline"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "codepipeline.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy" "codepipeline" {
name = "pipeline-permissions"
role = aws_iam_role.codepipeline.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"codecommit:*",
"codebuild:*",
"codedeploy:*",
"s3:*",
"iam:PassRole",
]
Resource = "*"
}]
})
}
resource "aws_codepipeline" "main" {
name = "certlabpro-dop-c02"
role_arn = aws_iam_role.codepipeline.arn
artifact_store {
location = aws_s3_bucket.artifacts.bucket
type = "S3"
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "AWS"
provider = "CodeCommit"
version = "1"
output_artifacts = ["source"]
configuration = {
RepositoryName = aws_codecommit_repository.app.repository_name
BranchName = "main"
}
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
version = "1"
input_artifacts = ["source"]
output_artifacts = ["build"]
configuration = {
ProjectName = aws_codebuild_project.build.name
}
}
}
}
# ── Synthetics canary ─────────────────────────────────────────
resource "aws_iam_role" "canary" {
name = "certlabpro-dop-c02-canary"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "canary_logs" {
role = aws_iam_role.canary.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
data "archive_file" "canary_src" {
type = "zip"
output_path = "${path.module}/build/canary.zip"
source {
filename = "nodejs/node_modules/index.js"
content = <<-EOT
const synthetics = require("Synthetics");
exports.handler = async () => {
const page = await synthetics.getPage();
const res = await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
if (!res.ok()) throw new Error("Status code " + res.status());
};
EOT
}
}
resource "aws_synthetics_canary" "endpoint" {
name = "certlabpro-dop-c02-endpoint"
artifact_s3_location = "s3://${aws_s3_bucket.artifacts.bucket}/canary/"
execution_role_arn = aws_iam_role.canary.arn
handler = "index.handler"
zip_file = data.archive_file.canary_src.output_path
runtime_version = "syn-nodejs-puppeteer-9.0"
start_canary = true
schedule {
expression = "rate(5 minutes)"
}
}terraform destroy elimina todo en este laboratorio. Dos notas:
aws s3 rm s3://<bucket> --recursive) antes de destroy o use force_destroy = true en el recurso del bucket y vuelva a aplicar una vez antes de destruir.start_canary = true — se ejecuta continuamente a intervalos de 5 minutos desde el momento de apply. Cada ejecución cuesta aproximadamente $0.0012; un canary de laboratorio olvidado que se ejecute durante una semana cuesta aproximadamente $0.25. Barato, pero real. Destrúyalo cuando termine.El DOP-C02 cubre una amplia superficie profesional: CloudFormation StackSets para IaC multi-cuenta / multi-región, Service Catalog, reglas de AWS Config + remediación, Systems Manager OpsCenter + Patch Manager, automatización de AWS Health Dashboard, verificaciones de Trusted Advisor, AWS Backup, EventBridge Pipes, Step Functions para orquestación entre servicios y X-Ray para rastreo distribuido.
Nos centramos en la canalización de CI/CD de extremo a extremo porque es la arquitectura más evaluada en el examen; todos los demás patrones del DOP-C02 (reglas de Config que alimentan la remediación, paginación de Synthetics a través de SNS, despliegue de StackSets a través de CodePipeline) se basan en esta base. Tenga primero la cadena de origen a despliegue en sus manos; luego agregue StackSets multi-cuenta y orquestación entre regiones una vez que los conceptos básicos resulten mecánicos.
Para las superficies no aprovisionadas aquí, las secciones Buscar, Manual y Editorial de esta página de certificación tienen cobertura conceptual. Un laboratorio de seguimiento que añada CloudFormation StackSets + Config Rules + Systems Manager Patch Manager completaría el dominio de gestión de operaciones a escala.