Последняя проверка: май 2026 г.
Разверните сервисы AWS для экзамена DOP-C02 с помощью чистого Terraform: пошаговое руководство с привязкой каждого блока к разделам экзамена. Код также совместим с OpenTofu.
К концу этой лабораторной работы вы развернете, используя чистый Terraform, полный конвейер от кода до продакшена — репозиторий Git CodeCommit, проект CodeBuild, который запускает ваш набор тестов и упаковывает артефакты, приложение CodeDeploy, которое разворачивается на целевой системе, конвейер CodePipeline, который связывает источник → сборку → развертывание, и мониторинг CloudWatch Synthetics, который проверяет развернутую конечную точку и подает сигнал тревоги, когда она перестает отвечать. Это эталонная архитектура DOP-C02 в пяти блоках.
Каждый ресурс — это чистый Terraform. Поместите фрагменты в один файл main.tf, запустите terraform init, затем terraform apply шаг за шагом.
>= 1.5 или OpenTofu >= 1.6.us-east-1.https://example.com; в продакшене это была бы конечная точка проверки работоспособности вашего приложения.aws_s3_bucket в качестве источника конвейера (CodePipeline поддерживает источник S3).В основном оплата по факту использования, без значительных расходов за бездействие:
BUILD_GENERAL1_SMALL; сборка в лаборатории стоит центы.Вся инфраструктура стоит менее $5 в месяц в рабочем состоянии. Удалите по завершении.
Стандартное начало. Сервисы Code* являются региональными — выберите регион, который используют ваши исходные репозитории и целевые среды. По умолчанию для лаборатории используется us-east-1.
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 — это хост Git от AWS. DOP-C02 тестирует комплекс Code* от начала до конца как тесно интегрированную систему — наиболее распространенные вопросы на экзамене спрашивают, какая комбинация нативных сервисов AWS достигает заданного результата, и ответ почти всегда начинается с CodeCommit.
default_branch = "main" соответствует современным настройкам Git по умолчанию (CodeCommit исторически создавал master). Репозиторий, который мы создаем, пуст после apply; в реальном использовании вы бы отправили свой первый коммит с файлами buildspec.yml и appspec.yml в корне — это файлы, которые CodeBuild (Шаг 3) и CodeDeploy (Шаг 4) читают при каждом запуске конвейера.
resource "aws_codecommit_repository" "app" {
repository_name = "certlabpro-dop-c02-app"
description = "Application source for the DOP-C02 lab pipeline."
default_branch = "main"
}CodeBuild выполняет шаги сборки и тестирования из вашего buildspec.yml. DOP-C02 здесь проверяет компромисс между управляемым образом и пользовательским образом — управляемые образы не требуют обслуживания, но медленнее запускаются; пользовательские образы дают более быстрый холодный старт и воспроизводимые наборы инструментов. В лаборатории используется управляемый образ aws/codebuild/standard:7.0, который поддерживает Node, Python, Java, Go, .NET, Ruby «из коробки».
Роль IAM предоставляет CodeBuild разрешение на запись в CloudWatch Logs (для вывода сборки), чтение исходного кода из CodeCommit и запись артефактов в бакет S3 из Шага 1. LINUX_CONTAINER + BUILD_GENERAL1_SMALL — это самый дешевый уровень по цене $0,005 за минуту сборки.
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 выполняет фактическое развертывание — на EC2, Lambda или ECS. DOP-C02 многократно проверяет ось стратегий развертывания: AllAtOnce (самый дешевый, самый рискованный), HalfAtATime, OneAtATime, CodeDeployDefault.LambdaCanary10Percent5Minutes (паттерн Lambda canary) и CodeDeployDefault.ECSAllAtOnce. Мы выбираем вычислительную платформу Lambda для лаборатории, потому что она не требует фактического существования экземпляров EC2 — это делает лабораторию дешевой и узконаправленной.
Конфигурация развертывания CodeDeployDefault.LambdaAllAtOnce является самой простой из стратегий Lambda. В продакшене LambdaCanary10Percent5Minutes является наиболее часто рекомендуемым ответом DOP-C02 для развертываний со сниженным риском: он переключает 10% трафика на новую версию, ждет 5 минут для срабатывания оповещений CloudWatch, а затем переключает остальной трафик, если ничего не произошло.
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 — это оркестратор, который связывает три предыдущих шага в единый граф: исходный код из CodeCommit, сборка с помощью CodeBuild, развертывание с помощью CodeDeploy. Каждый переход является точкой подключения — вы можете добавлять ручные утверждения, параллельные этапы тестирования и уведомления между любыми двумя этапами. Область Управление конфигурацией и IaC в DOP-C02 многократно тестирует эту структуру этапов и действий.
Как только конвейер создан, у вас есть CI/CD. Последняя часть — CloudWatch Synthetics — замыкает цикл наблюдаемости развертывания: «канарейка» — это управляемый скрипт безголового браузера (на основе Puppeteer), который запускается по расписанию и сообщает об успехе/неудаче в CloudWatch. Область Мониторинг и логирование DOP-C02 сильно опирается на этот паттерн: развертывание изменения → «канарейка» улавливает регрессию в течение нескольких минут → автоматический откат CodeDeploy (который мы настроили на Шаге 4) срабатывает по сигналу тревоги CloudWatch от «канарейки».
Скрипт «канарейки» ниже опрашивает https://example.com каждые 5 минут; в продакшене вы бы направили его на конечную точку работоспособности вашего приложения, с утверждениями по телу ответа и заголовкам, а не только по 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 удаляет все в этой лабораторной работе. Два замечания:
aws s3 rm s3://<bucket> --recursive) перед destroy или используйте force_destroy = true для ресурса бакета и примените его еще раз перед удалением.start_canary = true — она работает непрерывно с интервалом в 5 минут с момента apply. Каждый запуск стоит ~$0,0012; забытая лабораторная «канарейка», работающая неделю, стоит ~$0,25. Дешево, но реально. Удалите по завершении.DOP-C02 охватывает широкий профессиональный спектр — CloudFormation StackSets для IaC в нескольких учетных записях/регионах, Service Catalog, правила AWS Config + устранение проблем, Systems Manager OpsCenter + Patch Manager, автоматизацию AWS Health Dashboard, проверки Trusted Advisor, AWS Backup, EventBridge Pipes, Step Functions для межсервисной оркестрации и X-Ray для распределенной трассировки.
Мы придерживаемся сквозного конвейера CI/CD, потому что это единственная наиболее часто проверяемая архитектура на экзамене — каждый другой паттерн DOP-C02 (правила Config, обеспечивающие устранение проблем, оповещения Synthetics через SNS, развертывание StackSets через CodePipeline) строится на этой основе. Сначала освойте цепочку от исходного кода до развертывания; затем добавьте StackSets для нескольких учетных записей и межрегиональную оркестрацию, как только основы станут автоматическими.
Для поверхностей, не предусмотренных здесь, разделы Просмотр, Справочник и Editorial на этой странице сертификации содержат концептуальное описание. Последующая лабораторная работа, которая добавит CloudFormation StackSets + Config Rules + Systems Manager Patch Manager, завершит область управления операциями в масштабе.