介绍
你的团队需要私有存储来保存报告。在本实验中,你将使用 Terraform 创建第一个存储桶,将其配置与 AWS 和 Terraform 状态进行比较,然后审查并执行销毁操作。另一个团队拥有一份独立的参考报告,必须保持其不变。
你应已了解 Terraform 资源、init、plan、apply、状态和 destroy,并能够熟练编辑文件及使用 AWS CLI 查询 S3。Terraform、AWS provider 和 CLI 访问均已准备就绪。使用 Terminal 执行命令,使用 AWS View 观察存储;无需个人 AWS 账户或访问密钥。每个实验均独立开始。
与认证考试的关联
| 认证 | 考试任务 | 实践内容 |
|---|---|---|
| Cloud Practitioner (CLF-C02) | 任务 3.1 | 使用基础设施即代码实现可重复的部署,并通过 CLI 查询进行检查。 |
| Developer – Associate (DVA-C02) | 任务 3.3,技能 3.3.4 | 实现和部署 IaC 资源定义的基础实践。 |
| DevOps Engineer – Professional (DOP-C02) | 任务 2.1 | 使用 IaC 定义资源并管理其创建和删除的基础实践。 |

创建报告存储桶
在这一步中,你将把 Terraform 资源定义与当前 AWS 账户关联起来,并创建一个私有报告存储桶。
首先,进入已准备好的根目录,查询你的区域和调用者身份。根目录是一份独立的 Terraform 配置,拥有自己的状态。调用者账户告诉你 provider 的请求作用于哪个账户;ARN 则标识发起请求的身份。
cd /home/labex/project/first-aws-resource
aws configure get region
aws sts \
get-caller-identity
terraform version
区域为 us-east-1。Terraform 显示的版本为 1.17.2。已准备好的访问配置独立于任何个人 AWS 账户。
提供的 provider.tf 选择版本为 6.14.0 的 AWS provider,配置已准备好的连接,并将 Terraform 固定为 1.17.2。provider 将资源操作转换为 AWS API 请求。实验已提供其配置,让你能够专注于资源管理。
使用以下配置创建 main.tf。cat 和 <<'EOF' 会将结束标记 EOF 之前的全部内容写入指定文件。aws_s3_bucket 是 AWS 资源类型;reports 是 Terraform 中的本地标签。两者共同构成地址 aws_s3_bucket.reports。bucket 属性是 AWS 存储桶名称,与该地址不同。标签用于记录资源的用途。
cat > main.tf <<'EOF'
resource "aws_s3_bucket" "reports" {
bucket = "terraform-first-reports"
tags = {
Project = "TerraformReports"
}
}
output "report_bucket" {
value = aws_s3_bucket.reports.id
}
EOF
初始化此根目录并验证其配置:
terraform init
terraform validate
init 会从已准备好的缓存中安装固定版本的 provider,并写入 .terraform.lock.hcl。在实际项目中,应将此依赖锁定文件与配置一起保存:它记录了选定的 provider 及软件包校验和。它不同于 Terraform 状态,后者将资源地址映射到已部署资源的 ID。由于缓存针对当前 Linux 环境准备,init 可能会警告锁定文件的校验和仅覆盖 linux_amd64;初始化仍会完成。如果项目还要在其他平台上使用,也需要包含那些平台的校验和。
在创建任何资源之前,先审查计划:
terraform plan
预期看到 Plan: 1 to add, 0 to change, 0 to destroy.。某些属性显示为 (known after apply),因为 AWS 会在创建过程中分配或返回这些属性。确认存储桶名称和项目标签。计划只预览操作,不会创建存储桶。
应用配置,并在确认提示中输入 yes:
terraform apply
预期看到 Apply complete! Resources: 1 added, 0 changed, 0 destroyed.。report_bucket 输出为 terraform-first-reports。在 AWS View 中,新建的空存储桶会出现在 team-reference-reports 旁边。不要改动该参考存储桶及其中的 keep.txt 对象。

完成命令后,使用 Continue 继续。检查会分别查询 AWS 和状态映射;仅命令执行成功还不足以通过检查。
比较配置、状态和 AWS
在这一步中,你将把 Terraform 的资源地址与实际的私有存储桶对应起来,然后确认配置已收敛。
输出值通过资源引用读取存储桶 ID。state list 显示受管理的地址;state show 显示状态中记录的属性。这些命令只检查映射,不会更改 AWS。
terraform output report_bucket
terraform state list
terraform state show aws_s3_bucket.reports
找到 aws_s3_bucket.reports 及其 ID terraform-first-reports。配置描述期望的资源,AWS 中保存实际资源,状态将两者连接起来。仅有状态条目并不能证明资源仍然存在。
直接查询 AWS。对于 S3 的 us-east-1 区域,get-bucket-location 返回 null。ACL 应仅向作为所有者的规范用户授予访问权限;不应有面向公共组的授权。本实验创建私有存储桶,不添加公开的存储桶策略。
aws s3api \
get-bucket-location \
--bucket terraform-first-reports
aws s3api \
get-bucket-acl \
--bucket terraform-first-reports
aws s3api \
get-bucket-tagging \
--bucket terraform-first-reports
确认 Project 标签为 TerraformReports。验证那份与本实验资源无关的报告仍可读取。--query 表达式只选择其字节长度,命令不会改变存储的对象。
aws s3api \
head-object \
--bucket team-reference-reports \
--key keep.txt \
--query ContentLength
terraform plan
计划应显示 No changes.。这表示 provider 没有发现受管理资源需要进行的配置变更。它不能证明所有可能的安全属性,也不能验证报告数据;这些都需要单独检查。你可以进一步阅读 Terraform 状态和 S3 访问控制。
仅删除受管理的资源
在这一步中,你将审查并执行销毁计划,然后证明受管理的存储桶及状态映射已移除,同时参考报告仍然保留。
terraform plan -destroy 预览删除此根目录状态中的资源。它并不意味着“删除账户中的所有存储桶”。继续之前,请阅读资源地址和存储桶 ID:
terraform plan -destroy
预期看到 Plan: 0 to add, 0 to change, 1 to destroy.。参考存储桶不在计划中,因为此根目录不管理它。目标存储桶为空;后续实验会解释为什么存储的数据和版本需要单独决定如何保留。
销毁受管理的存储桶,并在确认提示中输入 yes:
terraform destroy
预期看到 Destroy complete! Resources: 1 destroyed.。现在检查状态并查询剩余的存储桶:
terraform state list
aws s3api \
list-buckets \
--query 'Buckets[].Name'
aws s3api \
head-object \
--bucket team-reference-reports \
--key keep.txt \
--query ContentLength
状态列表为空。成功返回的存储桶列表中没有 terraform-first-reports;team-reference-reports 及其报告仍然存在。在最终检查完成前保留 AWS 访问配置,以免将身份验证错误误认为删除成功。如果你选择再次创建该资源,仍可使用保留下来的配置和锁定文件。

总结
你使用固定版本的 AWS provider 创建了一个私有 S3 存储桶,通过 AWS 查询比较了配置和状态,检查了已收敛的计划,并且仅销毁了受管理的资源。独立的参考报告保持完好。在下一个实验中,你将使用输入值和资源引用来管理报告内容。



