Última revisión: mayo de 2026
Crea los servicios de AWS del examen DVA-C02 con Terraform puro: bloque a bloque, cada uno vinculado a un dominio del examen. El mismo código funciona en OpenTofu.
Al final de este laboratorio habrá aprovisionado, con Terraform simple, el microservicio sin servidor canónico de AWS — una tabla DynamoDB, una función Lambda con un rol IAM de privilegio mínimo, un API Gateway HTTP delante de ella, y CloudWatch Logs + una alarma de error de Lambda para que sepa cuándo falla el servicio. Esta es la arquitectura que el DVA-C02 evalúa en una de cada dos preguntas.
Cada recurso es Terraform simple — el mismo código funciona sin modificaciones en OpenTofu. Sin variables, sin módulos, sin estado remoto. Suelte los fragmentos en un único main.tf, ejecute terraform init una vez, y luego terraform apply paso a paso.
>= 1.5 o OpenTofu >= 1.6.us-east-1..zip en el momento de la planificación a través de archive_file — no se necesita un paso de construcción separado.Todos los recursos aquí son de pago por uso, sin facturación por inactividad:
Todo el stack se mantiene inactivo en $0. Destruya cuando haya terminado por costumbre, no por pánico de costo.
Apertura estándar: fijar aws ~> 5.60, predeterminar a us-east-1, etiquetar todo con el nombre del proyecto para que Cost Explorer pueda informar más tarde sobre lo que este laboratorio gastó (se esperan ~$0, pero el hábito es el punto relevante para el examen).
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.60"
}
archive = {
source = "hashicorp/archive"
version = "~> 2.4"
}
}
}
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Project = "certlabpro-dva-c02"
ManagedBy = "terraform"
}
}
}DynamoDB es el almacén NoSQL al que DVA-C02 espera que recurra en cualquier escenario de "latencia de un solo dígito de milisegundos a escala". Creamos una tabla con facturación bajo demanda (sin planificación de capacidad), una clave de partición y TTL activado para la expiración automática de registros — un patrón recurrente del DVA-C02 para el almacenamiento en caché, el almacenamiento de sesiones y cualquier carga de trabajo con datos que caducan de forma natural.
No hay clave de clasificación en este laboratorio; solo haremos acceso clave-valor. La recuperación a un punto en el tiempo está activada por defecto para cualquier tabla de producción que el examen espere que aprovisione; también la habilitamos aquí. Tanto billing_mode = PAY_PER_REQUEST como point_in_time_recovery son atributos del examen de alta frecuencia.
resource "aws_dynamodb_table" "items" {
name = "certlabpro-dva-c02-items"
billing_mode = "PAY_PER_REQUEST"
hash_key = "id"
attribute {
name = "id"
type = "S"
}
ttl {
attribute_name = "expires_at"
enabled = true
}
point_in_time_recovery {
enabled = true
}
}Lambda es donde reside nuestra lógica de aplicación. Le asignamos un rol de privilegio mínimo: puede escribir en su grupo de registros de CloudWatch (la política administrada AWSLambdaBasicExecutionRole) y llamar exactamente a cuatro acciones de DynamoDB (GetItem, PutItem, UpdateItem, Query) contra una sola tabla — la que creamos en el Paso 2.
La fuente de datos archive_file agrupa el manejador Python en línea en un .zip en el momento de la planificación, por lo que no hay un paso de construcción separado. El manejador es intencionalmente diminuto (devuelve la ruta + el nombre de la tabla como JSON) — DVA-C02 evalúa la configuración de Lambda mucho más que el código de Lambda, y los atributos relevantes para el examen están aquí: runtime, handler, timeout, memory_size, variables de entorno y el rol.
data "archive_file" "lambda_src" {
type = "zip"
output_path = "${path.module}/build/handler.zip"
source {
filename = "index.py"
content = <<-EOT
import json, os
def handler(event, context):
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({
"table": os.environ["TABLE_NAME"],
"path": event.get("rawPath", "/"),
}),
}
EOT
}
}
resource "aws_iam_role" "lambda" {
name = "certlabpro-dva-c02-lambda"
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" "lambda_logs" {
role = aws_iam_role.lambda.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
resource "aws_iam_role_policy" "lambda_ddb" {
name = "ddb-table-access"
role = aws_iam_role.lambda.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:Query"]
Resource = aws_dynamodb_table.items.arn
}]
})
}
resource "aws_lambda_function" "api" {
function_name = "certlabpro-dva-c02-api"
role = aws_iam_role.lambda.arn
runtime = "python3.12"
handler = "index.handler"
filename = data.archive_file.lambda_src.output_path
source_code_hash = data.archive_file.lambda_src.output_base64sha256
timeout = 10
memory_size = 256
environment {
variables = {
TABLE_NAME = aws_dynamodb_table.items.name
}
}
}
resource "aws_cloudwatch_log_group" "lambda" {
name = "/aws/lambda/${aws_lambda_function.api.function_name}"
retention_in_days = 7
}API Gateway es lo que convierte nuestra Lambda en algo que el mundo puede invocar. DVA-C02 evalúa específicamente las API HTTP (la versión más barata, rápida y nueva de API Gateway) sobre las API REST (la versión más antigua) en la mayoría de las preguntas modernas — las API HTTP son ~70% más baratas y tienen una latencia ~60% menor, y admiten la misma integración de Lambda que necesitamos.
Tres recursos unen esto: la propia API, una integración que apunta a nuestra Lambda, y una ruta que mapea las solicitudes entrantes ANY / a esa integración. La etapa de auto-despliegue significa que los cambios en la API surten efecto inmediatamente al terraform apply.
El aws_lambda_permission es el detalle que los principiantes olvidan: API Gateway está invocando nuestra Lambda desde fuera de la propia política de recursos de la función, por lo que necesitamos otorgarle permiso para hacerlo. Sin este recurso, la API aceptará la solicitud y luego devolverá un 500 al intentar invocar una Lambda que no tiene permiso para invocar.
resource "aws_apigatewayv2_api" "main" {
name = "certlabpro-dva-c02"
protocol_type = "HTTP"
}
resource "aws_apigatewayv2_integration" "lambda" {
api_id = aws_apigatewayv2_api.main.id
integration_type = "AWS_PROXY"
integration_uri = aws_lambda_function.api.invoke_arn
payload_format_version = "2.0"
}
resource "aws_apigatewayv2_route" "root" {
api_id = aws_apigatewayv2_api.main.id
route_key = "ANY /"
target = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}
resource "aws_apigatewayv2_stage" "default" {
api_id = aws_apigatewayv2_api.main.id
name = "$default"
auto_deploy = true
}
resource "aws_lambda_permission" "apigw" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.api.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_apigatewayv2_api.main.execution_arn}/*/*"
}
output "api_url" {
value = aws_apigatewayv2_api.main.api_endpoint
}Cada Lambda emite una métrica Errors a CloudWatch — el recuento de invocaciones que lanzaron errores. El dominio Monitorización, Registro y Resolución de problemas del DVA-C02 (~12% del examen) evalúa si usted instrumenta esto desde el primer día. Creamos una alarma de CloudWatch sobre la tasa de errores de Lambda y enrutamos las notificaciones a través de SNS a una dirección de correo electrónico.
Después de terraform apply, AWS envía un correo electrónico de confirmación a la dirección en email_endpoint — haga clic en Confirmar suscripción una vez, y la alarma le llegará realmente cuando los errores aumenten.
La combinación de los Pasos 2 al 5 es el microservicio completo: un almacén con estado (DynamoDB), computación sin estado (Lambda), un borde HTTPS (API Gateway HTTP API) y visibilidad operativa (CloudWatch Logs + alarmas). Esa es la arquitectura del DVA-C02 en cinco bloques.
resource "aws_sns_topic" "alerts" {
name = "certlabpro-dva-c02-alerts"
}
resource "aws_sns_topic_subscription" "alerts_email" {
topic_arn = aws_sns_topic.alerts.arn
protocol = "email"
endpoint = "you@example.com" # replace with your real email
}
resource "aws_cloudwatch_metric_alarm" "lambda_errors" {
alarm_name = "certlabpro-dva-c02-lambda-errors"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "Errors"
namespace = "AWS/Lambda"
period = 300
statistic = "Sum"
threshold = 5
alarm_description = "Lambda errored more than 5 times in 5 minutes."
alarm_actions = [aws_sns_topic.alerts.arn]
treat_missing_data = "notBreaching"
dimensions = {
FunctionName = aws_lambda_function.api.function_name
}
}terraform destroy desmonta todo en este laboratorio de forma limpia. Dos notas:
El DVA-C02 cubre más servicios orientados al desarrollador de los que puede abarcar este laboratorio — Step Functions para orquestación, SQS + SNS para mensajería asíncrona, EventBridge para trabajos programados, Kinesis Data Streams para pipelines en tiempo real, X-Ray para rastreo distribuido, Secrets Manager + Parameter Store, Cognito para autenticación de usuarios, AppSync para GraphQL, ECS / EKS / Fargate para contenedores, CodeCommit + CodeBuild + CodeDeploy + CodePipeline para CI/CD, S3 para activos estáticos y CloudFront para el borde.
Nos centramos en el patrón de microservicio sin servidor más evaluado — Lambda + API Gateway HTTP API + DynamoDB + CloudWatch — porque es la única arquitectura que todo candidato al DVA-C02 necesita poder dibujar y explicar de memoria. Los otros patrones se basan en estas primitivas (Step Functions compone Lambdas; SQS activa Lambdas; EventBridge las programa) y se aprenden mejor añadiendo una pieza a la vez a esta base.
Para una cobertura conceptual servicio por servicio del resto, consulte las secciones Buscar, Manual y Editorial de esta página de certificación.