- IaC
- 云原生
- 基础设施
【免费下载链接】terraform-provider-aws
The AWS Provider enables Terraform to manage AWS resources.
aws_s3_account_public_access_block是 terraform-provider-aws 提供的数据源,用于读取某个 AWS 账户级别的 S3 公共访问阻止(Public Access Block)配置。本文以官方数据源文档为骨架,结合仓库中 S3 Control 服务的源码实现与验收测试,讲解该数据源的使用方式、参数与导出属性、底层 API 调用链,以及与同名资源aws_s3_account_public_access_block的配合场景。读完本文,你将掌握如何在 Terraform 配置中查询账户级 S3 公共访问阻止状态,并能理解其背后的实现原理。
数据源概述
S3 公共访问阻止(Public Access Block)是 AWS 提供的一组账户级安全开关,用于阻止通过 ACL 或存储桶策略向公众开放 S3 数据。aws_s3_account_public_access_block数据源返回当前(或指定)AWS 账户级别的公共访问阻止配置,属于 S3 Control(s3control)服务范畴,在文档中归类于 "S3 Control" 子类别。
该数据源与同名资源互补:资源 aws_s3_account_public_access_block 资源文档 负责"写入/管理"配置,而数据源负责"读取"配置,二者都作用于账户级配置,而非单个存储桶。如果你需要的是某个具体桶的公共访问阻止配置,应使用数据源aws_s3_bucket_public_access_block。
从源码结构看,该数据源注册于 internal/service/s3control/account_public_access_block_data_source.go,通过@SDKDataSource("aws_s3_account_public_access_block", name="Account Public Access Block")注解声明,并标注@Region(global=true),表示该配置是**全局性(非区域性)**的,与具体 Region 无关。
快速开始:最小示例
数据源的最小用法非常简单,不传任何参数即可读取当前 Terraform Provider 所配置 AWS 账户的公共访问阻止配置:
data "aws_s3_account_public_access_block" "example" { }在读取到配置后,可以在其他资源中引用导出属性,例如:
data "aws_s3_account_public_access_block" "example" {} output "current_block_public_acls" { value = data.aws_s3_account_public_access_block.example.block_public_acls } output "current_block_public_policy" { value = data.aws_s3_account_public_access_block.example.block_public_policy }当账户从未设置过公共访问阻止配置时,AWS 会返回NoSuchPublicAccessBlockConfiguration错误,Terraform 读取该数据源时会报错并提示"reading S3 Account Public Access Block",此时可以先用资源设置配置,再通过数据源读取。
Argument Reference:参数说明
该数据源仅支持一个可选参数:
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
account_id | String | 否 | 要查询的 AWS 账户 ID。默认为 Terraform AWS Provider 自动确定的账户 ID(即当前凭据所属账户) |
源码中该参数的实现位于 account_public_access_block_data_source.go,它被声明为Optional且不Computed,并挂接了verify.ValidAccountID校验函数,因此传入非法格式的账户 ID 会在配置校验阶段直接被拒绝,而不是等到 API 调用时才报错。
指定其他账户的示例:
data "aws_s3_account_public_access_block" "other" { account_id = "123456789012" }Attribute Reference:导出属性
该数据源在参数之外导出以下属性:
| 属性 | 类型 | 说明 |
|---|---|---|
id | String | AWS 账户 ID |
block_public_acls | Bool | 是否已启用"阻止公共 ACL"(返回true或false) |
block_public_policy | Bool | 是否已启用"阻止公共存储桶策略"(返回true或false) |
ignore_public_acls | Bool | 是否已启用"忽略公共 ACL"(返回true或false) |
restrict_public_buckets | Bool | 是否已启用"限制公共存储桶策略"(返回true或false) |
这四个布尔开关的含义(与同名资源文档 website/docs/r/s3_account_public_access_block.html.markdown 中的描述一致)如下:
block_public_acls:阻止通过公共 ACL 公开访问。启用后,若 ACL 允许公共访问,PUT Bucket acl和PUT Object acl调用将失败;若请求携带公共 ACL,PUT Object调用也会失败。该设置不影响已存在的 ACL。block_public_policy:阻止通过公共存储桶策略公开访问。启用后,若存储桶策略允许公共访问,Amazon S3 将拒绝PUT Bucket policy调用。该设置不影响已存在的存储桶策略。ignore_public_acls:忽略桶内已有的公共 ACL。启用后,Amazon S3 会忽略该账户下所有存储桶及其对象的公共 ACL,但不会清除已有 ACL,也不阻止新的公共 ACL 被写入。restrict_public_buckets:限制公共存储桶策略的生效范围。启用后,只有存储桶所有者和 AWS 服务可以访问带公共策略的存储桶,且公共策略中的公共访问和跨账户访问(包括对特定账户的非公共委托)都会被阻止。该设置不影响此前存储的策略。
在数据源的 schema 中,这四个属性全部被声明为Computed且类型为Bool(源码 L32-L47),即只能读取、不能由用户设置。
与同名资源的配合使用
一个 AWS 账户最多只能存在一份S3 公共访问阻止配置。因此在实际项目中,典型的用法是先通过资源声明并管理配置,再通过数据源读取当前生效值用于审计或派生配置:
resource "aws_s3_account_public_access_block" "example" { block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } data "aws_s3_account_public_access_block" "example" { depends_on = [aws_s3_account_public_access_block.example] } output "verified_block_public_acls" { value = data.aws_s3_account_public_access_block.example.block_public_acls }这里使用depends_on确保数据源在资源写入配置之后才读取,避免读到变更前的旧状态。
仓库中的验收测试 account_public_access_block_data_source_test.go 正是采用这一配对模式:先用资源aws_s3_account_public_access_block.test写入配置(全部设置为false),再声明数据源data.aws_s3_account_public_access_block.test读取,并通过resource.TestCheckResourceAttrPair逐一断言资源与数据源的block_public_acls、block_public_policy、ignore_public_acls、restrict_public_buckets四个属性值完全一致(见 测试源码 L26-L31)。该测试同时也验证了数据源从真实 API 返回值到 Terraform 状态字段的映射是正确的。
源码级原理:数据源是如何读取配置的
账户 ID 的确定逻辑
数据源的读取函数dataSourceAccountPublicAccessBlockRead(account_public_access_block_data_source.go L53-L75)执行以下步骤:
- 通过
meta.(*conns.AWSClient).S3ControlClient(ctx)获取 S3 Control 服务的 AWS SDK for Go v2 客户端; - 默认取
meta.(*conns.AWSClient).AccountID(ctx)作为账户 ID,即当前 Provider 凭据所属账户; - 如果配置中显式设置了
account_id,则用其覆盖默认值; - 调用
findPublicAccessBlockByAccountID发起底层查询。
底层 API 调用链
findPublicAccessBlockByAccountID(实现在 account_public_access_block.go L198-L220)构造GetPublicAccessBlockInput{AccountId: ...}并调用 S3 Control 的GetPublicAccessBlockAPI。该函数对错误做了两类特殊处理:
- 当返回码为
NoSuchPublicAccessBlockConfiguration时(错误码常量定义在 internal/service/s3control/errors.go),将其包装为retry.NotFoundError,表示该账户尚未配置公共访问阻止; - 当响应或
PublicAccessBlockConfiguration字段为空时,返回tfresource.NewEmptyResultError(),同样视为"未找到"。
查询成功后,读取函数依次执行d.SetId(accountID)和四个布尔字段的d.Set,把 AWS 返回的PublicAccessBlockConfiguration结构体字段(BlockPublicAcls、BlockPublicPolicy、IgnorePublicAcls、RestrictPublicBuckets)映射进 Terraform 状态,从而完成数据源读取。
读写双方共享同一套查找逻辑
值得注意的是,数据源与同名资源共用findPublicAccessBlockByAccountID这一查找函数(该函数在 internal/service/s3control/exports_test.go 中被导出供测试使用)。资源的 Create 流程在调用PutPublicAccessBlock后,会通过retry.Op(...).UntilFoundN(inARow)等待配置连续两次可被读取(account_public_access_block.go L103-L112);Update 流程则使用waitPublicAccessBlockEqual轮询直到读取到的配置与目标完全一致(reflect.DeepEqual比较,见 L222-L255)。这些等待逻辑都基于 S3 控制面最终一致性模型,其传播超时定义为 2 分钟(s3PropagationTimeout,见 internal/service/s3control/consts.go)。数据源虽然本身不需要写入等待,但理解这套轮询机制有助于解释"刚配置完立刻读取数据源可能短暂不一致"的现象。
注意事项
- 账户级单例约束:每个 AWS 账户只能有一份 S3 公共访问阻止配置,因此请勿在同一账户上重复声明多个
aws_s3_account_public_access_block资源,否则会产生永久性 diff(详见资源文档中的 NOTE 提示)。 - 全局资源与 Region:该数据源(及其对应资源)带
@Region(global=true)标记,是全局生效的配置,不随某个特定 Region 变化。关于全局资源在增强 Region 支持机制下的行为,可参考 enhanced-region-support 指南。 - 自定义端点:如果需要为该数据源配置自定义 API 端点,应使用 Provider 的
s3control端点配置(对应 website/docs/index.html.markdown 中关于端点配置的说明),而不是s3端点配置。 - 数据源与资源职责分离:数据源只读不写,任何对配置的修改都应通过资源
aws_s3_account_public_access_block完成;数据源适合用于查询、审计、以及在配置之间传递状态(如组织内多账户策略检查)。
小结
aws_s3_account_public_access_block数据源是查询 AWS 账户级 S3 公共访问阻止状态的轻量入口:它接受可选的account_id参数,导出block_public_acls、block_public_policy、ignore_public_acls、restrict_public_buckets四个布尔属性以及作为 ID 的账户 ID。在仓库中,它由 S3 Control 服务的 SDKv2 数据源实现支撑,底层通过GetPublicAccessBlockAPI 读取配置,并与同名资源共享查找与错误处理逻辑。将它与同名资源配合使用,可以构建"声明配置 + 读取验证"的完整安全治理工作流。
- IaC
- 云原生
- 基础设施
【免费下载链接】terraform-provider-aws
The AWS Provider enables Terraform to manage AWS resources.
相关推荐
使用 aws_iam_account_alias 数据源读取 AWS 账户别名
使用 aws_iam_account_alias 数据源读取 AWS 账户别名 在 Terraform 配置中,很多场景(如构建 IAM 用户登录 URL、S3
IaC云原生基础设施Terraform AWS Provider 数据源 `aws_elb_service_account`:精准获取 ELB Classic 服务账户 ID 以配置 S3 访问日志桶策略
Terraform AWS Provider 数据源 aws_elb_service_account :精准获取 ELB Classic 服务账户 ID 以配置
IaC云原生基础设施使用 Terraform AWS Provider 数据源 aws_cognito_user_pool 读取 Cognito 用户池配置
使用 Terraform AWS Provider 数据源 aws_cognito_user_pool 读取 Cognito 用户池配置 本指南基于 terra
IaC云原生基础设施
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考