Última revisão: maio de 2026
Construa os serviços da AWS do exame DVA-C02 com Terraform puro — um bloco de cada vez, cada um vinculado a um domínio do exame. O mesmo código funciona no OpenTofu.
Ao final deste laboratório, você terá provisionado, com Terraform simples, o microsserviço serverless canônico da AWS — uma tabela DynamoDB, uma função Lambda com uma função IAM de privilégio mínimo, um API Gateway HTTP à sua frente, e CloudWatch Logs + um alarme de erro Lambda para que você saiba quando o serviço falhar. Esta é a arquitetura que o DVA-C02 testa em quase todas as questões.
Cada recurso é Terraform simples — o mesmo código funciona sem modificações no OpenTofu. Sem variáveis, sem módulos, sem estado remoto. Coloque os trechos em um único main.tf, execute terraform init uma vez, depois terraform apply passo a passo.
>= 1.5 ou OpenTofu >= 1.6.us-east-1..zip no momento do planejamento via archive_file — nenhuma etapa de compilação separada é necessária.Todos os recursos aqui são pagos por uso, sem cobrança de ociosidade:
Todo o stack fica ocioso a $0. Destrua quando terminar por hábito, não por pânico de custos.
Abertura padrão: fixe aws ~> 5.60, defina como padrão us-east-1, marque tudo com o nome do projeto para que o Cost Explorer possa posteriormente relatar o que este laboratório gastou (espera-se ~$0, mas o hábito é o ponto relevante para o exame).
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 é o armazenamento NoSQL que o DVA-C02 espera que você utilize em qualquer cenário de "latência de milissegundos de um único dígito em escala". Criamos uma tabela com cobrança sob demanda (sem planejamento de capacidade), uma chave de partição e TTL ativado para expiração automática de registros — um padrão recorrente do DVA-C02 para cache, armazenamento de sessão e qualquer carga de trabalho com dados que expiram naturalmente.
Nenhuma chave de ordenação neste laboratório; faremos apenas acesso chave-valor. A recuperação pontual está ativada por padrão para qualquer tabela de produção que o exame espera que você provisione; nós a ativamos aqui também. Tanto billing_mode = PAY_PER_REQUEST quanto point_in_time_recovery são atributos de alta frequência no exame.
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
}
}A Lambda é onde nossa lógica de aplicação reside. Damos a ela uma função de privilégio mínimo: ela pode gravar em seu grupo de logs do CloudWatch (a política gerenciada AWSLambdaBasicExecutionRole) e chamar exatamente quatro ações do DynamoDB (GetItem, PutItem, UpdateItem, Query) contra exatamente uma tabela — aquela que criamos na Etapa 2.
A fonte de dados archive_file agrupa o handler Python inline em um .zip no momento do planejamento, então não há uma etapa de compilação separada. O handler é intencionalmente minúsculo (retorna o caminho + nome da tabela como JSON) — o DVA-C02 testa muito mais a configuração da Lambda do que o código da Lambda, e os atributos relevantes para o exame estão aqui: runtime, handler, timeout, memory_size, variáveis de ambiente e a função.
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
}O API Gateway é o que transforma nossa Lambda em algo que o mundo pode chamar. O DVA-C02 testa especificamente APIs HTTP (a versão mais barata, rápida e recente do API Gateway) em vez de APIs REST (a versão mais antiga) na maioria das questões modernas — as APIs HTTP são ~70% mais baratas e têm ~60% menos latência, e suportam a mesma integração Lambda que precisamos.
Três recursos ligam isso: a própria API, uma integração que aponta para nossa Lambda, e uma rota que mapeia as solicitações ANY / de entrada para essa integração. O estágio de auto-implantação significa que as alterações na API entram em vigor imediatamente após terraform apply.
A aws_lambda_permission é o detalhe que os iniciantes esquecem: o API Gateway está invocando nossa Lambda de fora da própria política de recurso da função, então precisamos conceder a ele permissão para fazê-lo. Sem este recurso, a API aceitará a solicitação e retornará um 500 ao tentar invocar uma Lambda que não tem permissão 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
}Toda Lambda emite uma métrica de Errors para o CloudWatch — contagem de invocações que geraram erro. O domínio Monitoramento, Registro e Resolução de Problemas do DVA-C02 (~12% do exame) testa se você instrumenta isso desde o primeiro dia. Criamos um alarme do CloudWatch na taxa de erros da Lambda e roteamos as notificações via SNS para um endereço de e-mail.
Após terraform apply, a AWS envia um e-mail de confirmação para o endereço em email_endpoint — clique em Confirmar inscrição uma vez, e o alarme realmente o alcançará quando os erros aumentarem.
A combinação das Etapas 2 a 5 é o microsserviço completo: um armazenamento com estado (DynamoDB), computação sem estado (Lambda), uma borda HTTPS (API Gateway HTTP API) e visibilidade operacional (CloudWatch Logs + alarmes). Essa é a arquitetura DVA-C02 em cinco blocos.
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 tudo neste laboratório de forma limpa. Duas observações:
O DVA-C02 abrange mais serviços voltados para desenvolvedores do que este laboratório pode conter — Step Functions para orquestração, SQS + SNS para mensagens assíncronas, EventBridge para trabalhos agendados, Kinesis Data Streams para pipelines em tempo real, X-Ray para rastreamento distribuído, Secrets Manager + Parameter Store, Cognito para autenticação de usuário, AppSync para GraphQL, ECS / EKS / Fargate para contêineres, CodeCommit + CodeBuild + CodeDeploy + CodePipeline para CI/CD, S3 para ativos estáticos e CloudFront para a borda.
Nós nos limitamos ao padrão de microsserviço serverless mais testado — Lambda + API Gateway HTTP API + DynamoDB + CloudWatch — porque é a arquitetura que todo candidato DVA-C02 precisa ser capaz de desenhar e explicar de memória. Os outros padrões são construídos sobre essas primitivas (Step Functions compõem Lambdas; SQS aciona Lambdas; EventBridge as agenda) e são melhor aprendidos adicionando uma peça por vez a esta base.
Para cobertura conceitual serviço a serviço do restante, consulte as seções Navegar, Guia e Editorial desta página de certificação.