Última revisão: maio de 2026
Construa os serviços da AWS do exame DOP-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 puro, um pipeline completo de código para produção — um repositório Git CodeCommit, um projeto CodeBuild que executa sua suíte de testes e empacota artefatos, um aplicativo CodeDeploy que implanta em um alvo, um pipeline CodePipeline que encadeia fonte → construção → implantação, e um canary CloudWatch Synthetics que sonda o endpoint implantado e emite alarmes quando ele para de responder. Esta é a arquitetura de referência DOP-C02 em cinco blocos.
Cada recurso é Terraform puro. Coloque os trechos em um único main.tf, execute terraform init, então terraform apply passo a passo.
>= 1.5 ou OpenTofu >= 1.6.us-east-1.https://example.com; em produção, este seria o endpoint de verificação de integridade da sua aplicação.aws_s3_bucket como a fonte do pipeline (o CodePipeline suporta fonte S3).Principalmente "pague pelo uso", sem cobrança significativa por inatividade:
BUILD_GENERAL1_SMALL; uma construção de laboratório custa centavos.O stack completo custa menos de US$ 5/mês em execução. Destrua quando terminar.
Abertura padrão. Os serviços Code* são regionais — escolha a região que seus repositórios de origem e ambientes de destino compartilham. Padrão para us-east-1 para o laboratório.
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 é o host Git da AWS. O DOP-C02 testa a suíte Code* de ponta a ponta como uma história bem integrada — as perguntas de exame mais comuns perguntam qual combinação de serviços nativos da AWS atinge um determinado resultado, e a resposta quase sempre começa com CodeCommit.
O default_branch = "main" corresponde aos padrões modernos do Git (o CodeCommit historicamente criava master). O repositório que criamos estará vazio após apply; em uso real, você faria seu primeiro commit com um buildspec.yml e appspec.yml na raiz — esses são os arquivos que o CodeBuild (Etapa 3) e o CodeDeploy (Etapa 4) leem em cada execução do pipeline.
resource "aws_codecommit_repository" "app" {
repository_name = "certlabpro-dop-c02-app"
description = "Application source for the DOP-C02 lab pipeline."
default_branch = "main"
}O CodeBuild executa as etapas de construção e teste do seu buildspec.yml. O DOP-C02 testa a compensação imagem gerenciada versus imagem personalizada aqui — imagens gerenciadas não exigem manutenção, mas são mais lentas para iniciar; imagens personalizadas oferecem inicialização mais rápida e cadeias de ferramentas reproduzíveis. O laboratório usa a imagem gerenciada aws/codebuild/standard:7.0, que cobre Node, Python, Java, Go, .NET, Ruby de fábrica.
O perfil IAM dá ao CodeBuild permissão para gravar em CloudWatch Logs (para saída de construção), ler a fonte do CodeCommit e gravar artefatos no bucket S3 da Etapa 1. LINUX_CONTAINER + BUILD_GENERAL1_SMALL é o nível mais barato a US$ 0,005/minuto de construção.
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
}
}O CodeDeploy lida com a implantação real — em EC2, Lambda ou ECS. O DOP-C02 testa repetidamente o eixo de estratégia de implantação: AllAtOnce (mais barato, mais arriscado), HalfAtATime, OneAtATime, CodeDeployDefault.LambdaCanary10Percent5Minutes (o padrão canary para Lambda) e CodeDeployDefault.ECSAllAtOnce. Escolhemos a plataforma de computação Lambda para o laboratório porque ela não exige que instâncias EC2 realmente existam — o que mantém o laboratório barato e com escopo limitado.
A configuração de implantação CodeDeployDefault.LambdaAllAtOnce é a mais simples das estratégias Lambda. Em produção, LambdaCanary10Percent5Minutes é a resposta DOP-C02 mais frequentemente recomendada para implantações com risco mitigado: ela transfere 10% do tráfego para a nova versão, espera 5 minutos por alarmes do CloudWatch e, em seguida, transfere o restante se nada disparar.
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 é o orquestrador que une as três etapas anteriores em um único grafo: fonte do CodeCommit, construção com CodeBuild, implantação com CodeDeploy. Cada transição é um ponto de conexão — você pode adicionar aprovações manuais, estágios de teste paralelos e notificações entre quaisquer duas etapas. O domínio Gerenciamento de Configuração e IaC do DOP-C02 testa essa estrutura de estágio e ação repetidamente.
Uma vez que o pipeline existe, você tem CI/CD. A última peça — CloudWatch Synthetics — fecha o ciclo da observabilidade da implantação: um canary é um script de navegador sem cabeça gerenciado (baseado em Puppeteer) que é executado em um cronograma e reporta sucesso/falha ao CloudWatch. O domínio Monitoramento e Registro do DOP-C02 se apoia fortemente neste padrão: implante uma mudança → o canary detecta a regressão em minutos → o auto-rollback do CodeDeploy (que configuramos na Etapa 4) é acionado pelo alarme do CloudWatch do canary.
O script canary abaixo sonda https://example.com a cada 5 minutos; em produção, você o apontaria para o endpoint de integridade da sua aplicação, com asserções sobre o corpo e cabeçalhos da resposta, não apenas 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 derruba tudo neste laboratório. Duas observações:
aws s3 rm s3://<bucket> --recursive) antes de destroy ou use force_destroy = true no recurso do bucket e reaplique uma vez antes de destruir.start_canary = true — ele está rodando continuamente em intervalos de 5 minutos a partir do momento do apply. Cada execução custa aproximadamente US$ 0,0012; um canary de laboratório esquecido rodando por uma semana custa aproximadamente US$ 0,25. Barato, mas real. Destrua quando terminar.O DOP-C02 abrange uma ampla área profissional — CloudFormation StackSets para IaC multi-conta / multi-região, Service Catalog, regras + remediação do AWS Config, Systems Manager OpsCenter + Patch Manager, automação do AWS Health Dashboard, verificações do Trusted Advisor, AWS Backup, EventBridge Pipes, Step Functions para orquestração entre serviços e X-Ray para rastreamento distribuído.
Nós nos limitamos ao pipeline CI/CD de ponta a ponta porque é a arquitetura mais testada no exame — todos os outros padrões do DOP-C02 (regras do Config alimentando remediação, paginação Synthetics via SNS, implantação de StackSets via CodePipeline) são construídos sobre essa base. Tenha a cadeia de origem para implantação em suas mãos primeiro; adicione StackSets multi-conta e orquestração entre regiões assim que os conceitos básicos se tornarem mecânicos.
Para as áreas não provisionadas aqui, as seções Navegar, Guia e Editorial desta página de certificação contêm cobertura conceitual. Um laboratório de acompanhamento que adicione CloudFormation StackSets + Regras do Config + Systems Manager Patch Manager complementaria o domínio gerenciamento de operações em escala.