最后审核时间:2026年5月
使用原生 Terraform 构建 DEA-C01 考试中的 AWS 服务——每次构建一个代码块,并紧扣考试领域。相同的代码可在 OpenTofu 上运行。
到本实验结束时,您将使用纯 Terraform 预置每个 AWS 数据湖共享的基础——一个带有分层生命周期策略的 S3 存储桶、一个 Glue Data Catalog 数据库、一个从 S3 中的对象发现模式的 Glue 爬虫,以及一个 Athena 工作组,让您无需预置服务器即可查询数据湖。这就是 DEA-C01 称之为“基于 S3 的数据湖”的架构,它在大约四分之一的考试问题中出现。
每个资源都是纯 Terraform — 相同的代码在 OpenTofu 上无需修改即可运行。将这些代码片段放入一个 main.tf 文件中,运行 terraform init,然后逐步运行 terraform apply。
>= 1.5 或 OpenTofu >= 1.6。us-east-1 区域操作(任何区域都适用;我们默认使用 us-east-1)。此处所有资源在空闲时均为 $0:
唯一需要注意的费用是将 Glue 爬虫保留在计划任务上。如果您在第 4 步中将 schedule 设置为 cron 表达式并忘记销毁,爬虫将永远运行 — 每次运行仍只需几美分,但如果每天运行一年,费用就会累积。完成后请销毁。
标准开场。Glue 和 Athena 是区域服务——选择您的原始数据所在的区域,因为在 PB 级别的数据传输中,跨区域数据传输费用会迅速增加。我们默认使用 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-dea-c01"
ManagedBy = "terraform"
}
}
}S3 存储桶是数据湖的整个基础。DEA-C01 专门测试存储类生命周期 — 您可以通过将冷数据随着时间的推移从 Standard → Standard-IA → Glacier Flexible → Glacier Deep Archive 进行转换,从而节省 80% 以上的成本。我们启用加密,锁定公共访问,并设置一个三层生命周期规则,该规则反映了 DEA-C01 最常测试的成本模式。
转换时间是 30 天 → IA,90 天 → Glacier Flexible Retrieval,180 天 → Deep Archive。这些数字是考试的最低要求(您不能在 30 天前转换为 IA — 这是 S3 的硬性限制,DEA-C01 会对此进行测试)。对于混合了近期和存档数据的数据湖,此生命周期可在不更改应用程序的情况下节省 60-90% 的存储成本。
resource "aws_s3_bucket" "lake" {
bucket_prefix = "certlabpro-dea-c01-"
}
resource "aws_s3_bucket_public_access_block" "lake" {
bucket = aws_s3_bucket.lake.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" "lake" {
bucket = aws_s3_bucket.lake.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_lifecycle_configuration" "lake" {
bucket = aws_s3_bucket.lake.id
rule {
id = "tier-cold-data"
status = "Enabled"
filter { prefix = "raw/" }
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 90
storage_class = "GLACIER"
}
transition {
days = 180
storage_class = "DEEP_ARCHIVE"
}
}
}Glue Data Catalog 是所有其他 AWS 分析服务读取的中央元数据存储 — Athena、EMR、Redshift Spectrum、Lake Formation 和 SageMaker Feature Store 都共享这一个目录。DEA-C01 无情地测试这种中央目录模型:您只需预置一次目录,账户中的每个分析界面都会自动使用它。
Glue 中的 database 是一个命名空间(可以把它想象成 PostgreSQL 中的 schema);table 是描述如何将 S3 中的对象读取为结构化数据的元数据。我们在此处创建数据库;第 4 步中的爬虫将在其下填充表。
resource "aws_glue_catalog_database" "main" {
name = "certlabpro_dea_c01"
description = "Glue Catalog database for the certlabpro DEA-C01 lab."
location_uri = "s3://${aws_s3_bucket.lake.bucket}/raw/"
}Glue 爬虫会遍历 S3 路径,从文件内容中推断列名和类型,并将模式写入第 3 步中的目录数据库。每当有新文件落地时,您重新运行爬虫,表就会自动获取新的分区或模式演变。DEA-C01 在“数据存储和管理”领域测试这种发现模式 — 这是数据工程师手动编写 DDL 与让 Glue 完成此工作的区别。
我们附加的 IAM 角色赋予爬虫从第 2 步的存储桶中读取并向第 3 步的目录中写入的权限。AWS 发布了一个名为 AWSGlueServiceRole 的托管策略,涵盖了大部分功能;我们附加它,并为我们的特定存储桶添加内联 S3 读取访问权限。我们特意没有在这里设置 schedule — 如果您希望每天刷新目录,可以稍后添加 schedule = "cron(0 5 * * ? *)"。
resource "aws_iam_role" "glue_crawler" {
name = "certlabpro-dea-c01-glue-crawler"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "glue.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "glue_service" {
role = aws_iam_role.glue_crawler.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole"
}
resource "aws_iam_role_policy" "glue_lake_read" {
name = "read-lake-bucket"
role = aws_iam_role.glue_crawler.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject", "s3:ListBucket"]
Resource = [aws_s3_bucket.lake.arn, "${aws_s3_bucket.lake.arn}/*"]
}]
})
}
resource "aws_glue_crawler" "raw_data" {
name = "certlabpro-dea-c01-raw-data"
database_name = aws_glue_catalog_database.main.name
role = aws_iam_role.glue_crawler.arn
s3_target {
path = "s3://${aws_s3_bucket.lake.bucket}/raw/"
}
schema_change_policy {
update_behavior = "UPDATE_IN_DATABASE"
delete_behavior = "LOG"
}
}Athena 使用 SQL 查询第 3-4 步中的目录 — 无服务器,按扫描的 TB 量付费。DEA-C01 的“数据操作”领域严格测试了 Athena 的两个特定属性:每个查询的数据扫描限制(此处限制为 1 GB,以防止失控查询意外扫描 100 TB),以及独立的结果存储桶(Athena 将查询输出写回 S3;将结果与源存储桶混合是考试中反复出现的反模式)。
工作组是治理的单位 — 您可以有一个具有严格扫描限制的 production 工作组,以及一个具有更高限制的 analytics-power-users 工作组,然后将 IAM 主体附加到任何适合的工作组。随着最后这部分的就位,数据湖基础已完成:数据落在 s3://<bucket>/raw/ 中,第 4 步中的爬虫对其进行编目,Athena 在此工作组设置的成本防护栏内对其进行查询。
resource "aws_s3_bucket" "athena_results" {
bucket_prefix = "certlabpro-dea-c01-athena-results-"
}
resource "aws_s3_bucket_public_access_block" "athena_results" {
bucket = aws_s3_bucket.athena_results.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_athena_workgroup" "main" {
name = "certlabpro-dea-c01"
state = "ENABLED"
configuration {
enforce_workgroup_configuration = true
publish_cloudwatch_metrics_enabled = true
bytes_scanned_cutoff_per_query = 1073741824 # 1 GB per query — runaway-query guardrail
result_configuration {
output_location = "s3://${aws_s3_bucket.athena_results.bucket}/output/"
encryption_configuration {
encryption_option = "SSE_S3"
}
}
}
}terraform destroy 将销毁本实验中的所有内容。两点注意事项:
force_destroy = false(安全默认值),因此如果任何一个包含对象(第 2 步的数据湖存储桶将收集原始文件;Athena 将结果写入第 5 步的存储桶),destroy 将会失败。在销毁之前,通过控制台(或 aws s3 rm s3://<bucket> --recursive)清空这两个存储桶。DEA-C01 涵盖的分析范围比本实验的五个纯 Terraform 步骤所能展示的要广 — Kinesis Data Streams + Kinesis Data Firehose 用于流式摄取,Amazon EMR 用于分布式 Spark,AWS Lambda 用于无服务器转换,Step Functions 用于管道编排,Redshift 用于数据仓库,MSK 用于托管 Kafka,OpenSearch 用于日志分析,QuickSight 用于 BI 仪表板,AWS DMS 用于数据库迁移,以及 Lake Formation 用于细粒度数据湖权限。
我们坚持使用最受考验的单一基础 — S3 + Glue Catalog + Glue Crawler + Athena — 因为它是所有其他 DEA-C01 模式构建的基础。Kinesis Firehose 写入此 S3 存储桶;EMR 从此 Glue Catalog 读取;Lake Formation 限制此 Athena 工作组。一旦您能够清晰地构建此基础,其余部分都是附加功能。
第二个涵盖 Kinesis Firehose → S3 → Glue → Athena(同一链的流式变体)的动手实验将是一个自然的后续。其余概念性内容位于本认证页面的浏览、手册和 Editorial 部分。