terraform-provider-aws 数据源 aws_organizations_policies 完全指南:批量枚举组织策略与 ID 管理
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
导读
aws_organizations_policies是 terraform-provider-aws 为 AWS Organizations 服务提供的数据源(Data Source),用于按策略类型(Policy Type)一次性枚举组织内全部策略,并返回它们的 ID 列表。它最常见的用法是与aws_organizations_policy数据源组合,实现"先批量列出策略 ID、再逐个读取策略详情"的管道式编排。读完本文,你将掌握该数据源的完整参数契约、底层 AWS API 调用链与分页实现,以及在实际配置中与策略资源、policies_for_target数据源的搭配技巧。
数据源概览:用途与定位
在 AWS Organizations 中,策略(Policy)分为多种类型,例如服务控制策略(SCP)、标签策略(Tag Policy)、备份策略(Backup Policy)等。当需要在不预先知道策略 ID 的情况下读取或操作所有策略时,aws_organizations_policies数据源就派上了用场:它以策略类型为过滤条件,返回该类型下所有策略的 ID 列表(ids)。
该数据源在 Provider 源码中的定义为dataSourcePolicies(),位于 internal/service/organizations/policies_data_source.go,并通过@SDKDataSource("aws_organizations_policies", name="Policies")注解注册。与之配套的还有两个紧密相关的数据源/资源:
- 数据源
aws_organizations_policy(internal/service/organizations/policy_data_source.go):根据policy_id读取单个策略的详情,如 ARN、内容、名称、类型等; - 数据源
aws_organizations_policies_for_target(internal/service/organizations/policies_for_target_data_source.go):枚举附加到某个指定组织单元或账号上的策略。
aws_organizations_policies与前两者的本质区别在于:它是全局按类型枚举,不关心策略挂载在哪个目标(Root、OU、账号)上,因此适合做全组织范围的策略盘点。
基础用法:批量列出 SCP 策略 ID
官方文档给出的基础示例(website/docs/d/organizations_policies.html.markdown)如下:
data "aws_organizations_policies" "example" { filter = "SERVICE_CONTROL_POLICY" } data "aws_organizations_policy" "example" { for_each = toset(data.aws_organizations_policies.example.ids) policy_id = each.value }这段配置的运行逻辑是:
data "aws_organizations_policies"以filter = "SERVICE_CONTROL_POLICY"拉取组织内全部 SCP 的 ID,输出到ids属性;toset(...)将 ID 列表转为集合,作为for_each的迭代来源;data "aws_organizations_policy"对每一个 ID 执行一次读取,each.value即为单个策略 ID,从而拿到每个策略的 ARN、内容(content)、名称、描述、类型、是否 AWS 托管(aws_managed)等完整属性。
该数据源导出的唯一计算属性是ids——由全部匹配策略的 ID 组成的字符串列表。需要留意的是,ID 形式形如p-xxxxxxxxxx,这也是后续使用aws_organizations_policy数据源或执行terraform import时需要的标识符。
参数参考:filter 的取值与含义
数据源的 Schema 定义在 internal/service/organizations/policies_data_source.go,全文只有一个必需参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
filter | string | 是 | 要返回的策略类型,直接映射为 AWS API 的PolicyType枚举 |
filter的合法取值(与 AWS SDK v2 中awstypes.PolicyType枚举一一对应)为:
AISERVICES_OPT_OUT_POLICY— AI 服务退出(Opt-out)策略;BACKUP_POLICY— 备份策略;CHATBOT_POLICY— Chatbot 策略;DECLARATIVE_POLICY_EC2— EC2 声明式策略;RESOURCE_CONTROL_POLICY— 资源控制策略(RCP);SERVICE_CONTROL_POLICY— 服务控制策略(SCP);TAG_POLICY— 标签策略。
在读取实现dataSourcePoliciesRead(internal/service/organizations/policies_data_source.go)中,filter被直接转换为 AWS API 请求参数:
filter := d.Get(names.AttrFilter).(string) input := &organizations.ListPoliciesInput{ Filter: awstypes.PolicyType(filter), }也就是说,filter字符串被原样强转为PolicyType枚举后传入ListPolicies调用;如果传入未列出的取值,会在 AWS API 侧返回参数校验错误。因此配置时务必使用上文列出的精确枚举字符串。
属性参考:返回字段
除了入参之外,数据源还导出以下计算属性:
| 属性 | 类型 | 说明 |
|---|---|---|
ids | list(string) | 匹配策略类型的全部策略 ID 列表 |
在实现中,d.SetId(filter)将数据源自身的 Terraform ID 设置为filter的值,而ids则通过对 API 返回的PolicySummary切片逐项提取Id字段得到(见 internal/service/organizations/policies_data_source.go):
d.Set(names.AttrIDs, tfslices.ApplyToAll(policies, func(v awstypes.PolicySummary) string { return aws.ToString(v.Id) }))这里的PolicySummary是 AWS 返回的轻量摘要对象,仅包含Id、Arn、Name、Type、Description、AwsManaged等概要信息,不包含策略正文。这也是为什么要继续配合aws_organizations_policy数据源读取content等详情字段的原因。
底层实现:AWS API 调用链与分页
从源码可以完整还原该数据源的调用链:
- 通过
meta.(*conns.AWSClient).OrganizationsClient(ctx)获取 Organizations 服务的 AWS SDK v2 客户端; - 构造
organizations.ListPoliciesInput{Filter: ...}; - 调用内部辅助函数
findPolicies(internal/service/organizations/policies_data_source.go),其内部使用 AWS SDK 的ListPoliciesPaginator分页器:
pages := organizations.NewListPoliciesPaginator(conn, input) for pages.HasMorePages() { page, err := pages.NextPage(ctx) ... output = append(output, page.Policies...) }ListPolicies是分页 API,单次最多返回一定数量的策略(默认每页 20 条),findPolicies通过分页器自动翻页并合并所有页面的Policies,从而保证组织内策略数量再多也能被完整枚举,无需在 Terraform 配置中手动处理分页。
需要说明的运行前提:该数据源要求调用身份为组织的管理账号(Management Account),普通成员账号无法调用ListPolicies枚举组织级策略。这一点在官方接入测试中也有体现——测试用例的PreCheck调用了acctest.PreCheckOrganizationManagementAccount(见 internal/service/organizations/policies_data_source_test.go),若当前凭据不是管理账号,Provider 会直接跳过/拒绝执行。同时,若组织尚未初始化,AWS API 会抛出AWSOrganizationsNotInUseException一类的错误,配置前需确认组织已创建并完成必要的初始化流程。
实战组合:先建策略,再批量读取
结合aws_organizations_policy资源(internal/service/organizations/policy.go),可以构造"创建 → 枚举 → 详情"的完整闭环。仓库中的接入测试(internal/service/organizations/policies_data_source_test.go)给出了一个可复现的配置范式:
resource "aws_organizations_policy" "test" { name = "example" type = "SERVICE_CONTROL_POLICY" content = jsonencode({ Version = "2012-10-17" Statement = { Effect = "Deny" Action = "*" Resource = "*" } }) } data "aws_organizations_policies" "test" { filter = aws_organizations_policy.test.type }要点解析:
aws_organizations_policy资源的type属性默认值即为SERVICE_CONTROL_POLICY(见 internal/service/organizations/policy.go),这里直接引用aws_organizations_policy.test.type作为数据源的filter,可以避免硬编码枚举值带来的不一致风险;content参数要求为 JSON 字符串,Provider 侧通过validation.StringIsJSON做校验,并对等价 JSON 差异做DiffSuppressFunc抑制(internal/service/organizations/policy.go);- 测试通过
acctest.CheckResourceAttrGreaterThanOrEqualValue(datasourceName, "ids.#", 1)断言ids列表长度至少为 1,验证"创建后立即能被枚举到"的闭环行为。
将上述资源与开头的基础示例组合,即可实现"所有 SCP 的全量详情导出",典型场景包括:全组织策略审计、策略内容比对、批量生成策略文档,或在迁移到新组织时盘点既有策略基线。
使用边界与易混淆数据源辨析
在实际项目中,很容易把以下三个 Organizations 数据源搞混,这里做一次集中辨析:
| 数据源 | 枚举维度 | 典型场景 |
|---|---|---|
aws_organizations_policies | 按策略类型全局枚举 | 盘点组织内全部 SCP / Tag Policy 等 |
aws_organizations_policies_for_target | 按挂载目标(Root / OU / 账号)枚举 | 查看某个 OU 上直接附加了哪些策略 |
aws_organizations_policy | 按单个policy_id读取详情 | 获取某策略的 ARN、content、name 等 |
此外还有两个使用注意事项:
- 数据源不返回策略内容:
ids只给 ID,详情必须二次读取aws_organizations_policy,这也是官方示例采用for_each嵌套的原因; - AWS 托管策略的干扰:
ListPolicies返回的PolicySummary带有AwsManaged标记。aws_organizations_policy数据源/资源对 AWS 托管策略的处理是拒绝导入并给出明确警告(见 internal/service/organizations/policy.go 与 internal/service/organizations/policy_data_source.go)。因此当组织内存在FullAWSAccess这类 AWS 托管 SCP 时,批量循环读取前建议结合aws_managed属性做过滤,避免对托管策略执行本不该执行的写入操作。
小结
aws_organizations_policies数据源虽小,却是 Organizations 策略自动化管理的关键入口。它用一次filter参数完成组织级策略 ID 的批量枚举,底层借助 AWS SDK 分页器保证完整性,天然适合与aws_organizations_policy数据源组合实现"枚举 → 详情"的全量读取管线。理解其 API 调用链(policies_data_source.go)、参数枚举范围以及与policies_for_target的差异,能帮助你在实际项目中写出更精准、更高效的策略管理配置。
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考