最后审核时间:2026年5月
使用原生 Terraform 构建 CLF-C02 考试中的 AWS 服务——每次构建一个代码块,并紧扣考试领域。相同的代码可在 OpenTofu 上运行。
在本实验结束时,您将使用纯 Terraform 预置最小且切合实际的首个 AWS 工作负载——一个私有加密 S3 存储桶、一个最小权限 IAM 角色、一个免费套餐 EC2 实例,以及一个在 AWS 向您发送账单之前向您发送电子邮件的账单告警。每个资源都映射到 CLF-C02 考试的四个领域之一。
每个资源都是纯 Terraform——相同的代码在 OpenTofu 上无需修改即可运行。没有变量、没有模块、没有远程状态。将以下代码片段放入单个 main.tf 文件中,运行一次 terraform init,然后逐步运行 terraform apply。
>= 1.5 或 OpenTofu >= 1.6。us-east-1,因为它是计费数据集中所在区域。本实验中的所有资源都符合新账户的 AWS 免费套餐(自注册之日起 12 个月内有效):
t3.micro 实例:每月 750 小时免费。超出免费套餐后,即使 24/7 运行,整个堆栈的成本也每月低于 10 美元。即便如此,免费套餐到期后,闲置资源仍会收费——完成后请销毁。我们在步骤 4 中构建的账单告警是您忘记销毁时的安全网。
每个工作负载都始于告诉 Terraform 我们期望它自身的哪个版本以及将使用哪个 AWS 提供商。我们将 AWS 提供商版本固定为 ~> 5.60,并默认使用 us-east-1——这是 AWS 最早的区域,计费数据集中于此,并且大多数服务首先在此区域发布。
将其放入新的 main.tf 文件中作为开始。实验中所有后续内容都将放在同一个文件中。
提供商中的 default_tags 块会将相同的标签附加到我们将创建的每个可标记资源。AWS Cost Explorer + 成本分配报告按标签对支出进行分组——第一天就正确配置这是您能做的最经济的成本控制投资,它直接映射到 CLF-C02 的“计费和定价”领域。
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-clf-c02"
ManagedBy = "terraform"
Environment = "lab"
}
}
}S3 几乎是所有 AWS 工作负载的存储层——每个 CLF-C02 领域都提及它。我们创建一个存储桶,锁定公共访问(自 2023 年以来新存储桶默认为开启,但明确指定更好),并使用 AES256 开启服务器端加密。
这三个资源——存储桶、公共访问阻止和加密——共同构成了任何 S3 存储桶的“最低负责任默认配置”。CLF-C02 考试将其视为“共享责任模型”:AWS 为我们提供了一个安全平台,但我们配置加密 + 访问控制。存储桶属于“客户责任”的一部分。
resource "aws_s3_bucket" "app_data" {
bucket_prefix = "certlabpro-clf-c02-"
}
resource "aws_s3_bucket_public_access_block" "app_data" {
bucket = aws_s3_bucket.app_data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_server_side_encryption_configuration" "app_data" {
bucket = aws_s3_bucket.app_data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}EC2 是每个 CLF-C02 考生都应熟知的 AWS 服务。我们使用最小的符合免费套餐资格的实例类型 (t3.micro),并为其分配一个 IAM 实例配置文件,以便它可以从我们在步骤 2 中创建的存储桶读取数据——而无需在实例中嵌入 AWS 凭证。这是“应用程序到 AWS”身份验证的规范 AWS 模式,并出现在多种 CLF-C02 考题变体中。
data 块动态获取最新的 Amazon Linux 2023 AMI——如果固定到特定的 AMI ID,当 AWS 弃用该镜像时将导致实验中断。安全组拒绝所有入站流量;在实际工作负载中,我们会添加入站规则,但对于本实验,锁定实例是正确的默认设置。
data "aws_ami" "al2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-kernel-6.1-x86_64"]
}
}
resource "aws_iam_role" "ec2_app" {
name = "certlabpro-clf-c02-ec2-app"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ec2.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy" "ec2_app_s3_read" {
name = "read-app-data-bucket"
role = aws_iam_role.ec2_app.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject", "s3:ListBucket"]
Resource = [aws_s3_bucket.app_data.arn, "${aws_s3_bucket.app_data.arn}/*"]
}]
})
}
resource "aws_iam_instance_profile" "ec2_app" {
name = "certlabpro-clf-c02-ec2-app"
role = aws_iam_role.ec2_app.name
}
resource "aws_security_group" "ec2_app" {
name = "certlabpro-clf-c02-ec2-app"
description = "Locked down by default; add ingress rules per workload."
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "app" {
ami = data.aws_ami.al2023.id
instance_type = "t3.micro"
iam_instance_profile = aws_iam_instance_profile.ec2_app.name
vpc_security_group_ids = [aws_security_group.ec2_app.id]
metadata_options {
http_endpoint = "enabled"
http_tokens = "required" # IMDSv2 only — required for SCS-C03 best practice
}
}CLF-C02 考试的 16% 专注于“计费、定价和支持”。您可以在此领域构建的最具体内容是 CloudWatch 账单告警:AWS 将账户级别的预估费用作为指标发布,我们设置一个阈值,一旦超过该阈值,我们就会收到通知。告警发布到 SNS 主题,然后通过电子邮件通知我们。
计费指标告警必须在 us-east-1 区域创建,无论您的工作负载运行在何处——这就是我们在步骤 1 中默认使用 us-east-1 的原因。您还需要在账户控制台中“计费 → 计费偏好设置 → 接收账单告警”处启用一次“账单告警”。Terraform 无法切换此设置;它是一个基础设施即代码之外的账户级别设置。
terraform apply 之后,AWS 会向 email_endpoint 中的地址发送一封确认邮件——点击“确认订阅”一次,然后当阈值触发时,您将实际收到告警。
resource "aws_sns_topic" "billing_alerts" {
name = "certlabpro-clf-c02-billing-alerts"
}
resource "aws_sns_topic_subscription" "billing_alerts_email" {
topic_arn = aws_sns_topic.billing_alerts.arn
protocol = "email"
endpoint = "you@example.com" # replace with your real email
}
resource "aws_cloudwatch_metric_alarm" "monthly_bill_over_10" {
alarm_name = "certlabpro-clf-c02-monthly-bill-over-10-usd"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "EstimatedCharges"
namespace = "AWS/Billing"
period = 21600 # 6 hours — billing metric is slow-moving
statistic = "Maximum"
threshold = 10
alarm_description = "Estimated monthly AWS charges exceeded $10 USD."
alarm_actions = [aws_sns_topic.billing_alerts.arn]
dimensions = {
Currency = "USD"
}
}标准的 terraform destroy 会销毁本实验中的所有内容。两点注意事项:
Project = certlabpro-clf-c02,并确认没有遗留资源。CLF-C02 涵盖了广泛的服务目录——RDS、Lambda、VPC 详情、CloudFront、Route 53、ECS、EKS、Aurora、Elastic Beanstalk、AppSync 等等。我们在此基础实验中特意不预置这些服务。
CLF-C02 的目标是广泛的概念流畅度,而非深入的逐服务预置。上述四个步骤触及了四个考试领域中的每个领域的一个资源——“云概念”(IAM + S3 作为平台和存储基元)、“安全与合规”(最小权限 IAM、静态加密、IMDSv2)、“云技术和服务”(EC2 作为规范的计算服务)和“计费、定价和支持”(CloudWatch 账单告警)。这与考试要求相符。
有关逐服务的覆盖范围,请参阅此认证页面的 浏览 和 Editorial 部分——它们用一行描述和考试领域关联引用了 CLF-C02 范围内的所有服务。本实验的实操价值在于了解四个支柱如何在第一天相互连接,而非浏览所有 200 多个 AWS 服务。