使用 Terraform AWS Provider 的 aws_networkfirewall_resource_policy 数据源检索 Network Firewall 资源策略
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
导读
aws_networkfirewall_resource_policy是 terraform-provider-aws 中 Network Firewall 服务提供的一个只读数据源,用于检索挂载在 AWS Network Firewall 防火墙策略(Firewall Policy)或规则组(Rule Group)上的资源策略(Resource Policy)JSON 文档。本文以 数据源官方文档 为核心,结合仓库内资源实现与集成测试代码,系统讲解该数据源的参数、属性、完整实战用法以及底层的 AWS API 调用链,帮助你在跨账户共享 Network Firewall 资源的场景中准确读取并复用现有策略。
Network Firewall 资源策略与数据源的作用
AWS Network Firewall 的资源策略是一种基于 AWS Resource Access Manager(RAM)的共享机制,它允许账户 A 将自身的防火墙策略或规则组共享给账户 B,使账户 B 的防火墙能够引用这些资源。这类策略通过PutResourcePolicyAPI 写入,本质上是一份 JSON 格式的 IAM 策略文档。
在 terraform-provider-aws 中,这一能力被拆分成一对配套的抽象:
- 资源(Resource):
aws_networkfirewall_resource_policy,负责创建、更新、删除资源策略,定义见 资源文档; - 数据源(Data Source):
aws_networkfirewall_resource_policy,只负责读取(检索)已经存在的资源策略,即本文主题。
两者在服务包注册表中同时登记(见 service_package_gen.go 与 service_package_gen.go),共享同一组resource_arn/policy字段语义。数据源通常用于以下场景:
- 跨账户 Terraform 工作区中,读取对方账户共享出来的策略内容,用于审计或条件判断;
- 在配置防火墙、防火墙策略或规则组之前,确认目标资源上是否已存在策略以及策略内容;
- 将现有策略作为变量传递给其他配置,例如判断是否已授权某项
network-firewall:*操作。
数据源基础用法
官方文档给出的最小可运行示例非常简洁:
data "aws_networkfirewall_resource_policy" "example" { resource_arn = var.resource_policy_arn }其中var.resource_policy_arn是你希望查询策略的防火墙策略或规则组的 ARN。数据源执行后,可以通过data.aws_networkfirewall_resource_policy.example.policy获取到完整的策略 JSON,通过data.aws_networkfirewall_resource_policy.example.id获取到与resource_arn相同的标识。
参数参考(Argument Reference)
数据源支持以下两个参数:
| 参数 | 是否必填 | 说明 |
|---|---|---|
region | 可选 | 资源将被管理的区域,默认使用 provider 配置中设定的区域。仅在该数据源需要跨区域查询资源策略时使用。 |
resource_arn | 必填 | 标识资源策略的 ARN,即防火墙策略或规则组的 ARN。 |
从实现层面看,resource_arn在数据源 Schema 中被定义为必填字段,并使用 ARN 校验函数verify.ValidARN进行合法性校验(见 resource_policy_data_source.go),传入非法格式的 ARN 会在 plan 阶段直接报错,而不是等到运行时才暴露。
属性参考(Attribute Reference)
除了上述参数外,数据源还会导出以下两个属性:
| 属性 | 说明 |
|---|---|
id | 标识该资源策略的 ARN,与resource_arn取值相同。 |
policy | 资源上的策略 JSON 文档,即该 ARN 对应资源的 Resource Policy 全文。 |
需要注意:policy返回的是策略的 JSON 字符串。它与 aws_networkfirewall_resource_policy 资源 写入时的policy字段格式一致(均为 JSON 文档),因此可以直接作为该资源的输入或用于对比校验。
完整实战示例:资源与数据源配合使用
单独使用数据源需要提前存在一个已绑定策略的资源。更常见的做法是像仓库内的集成测试那样,先用资源创建防火墙策略并写入资源策略,再通过数据源读取回来进行校验。以下示例改编自 resource_policy_data_source_test.go:
data "aws_partition" "current" {} data "aws_caller_identity" "current" {} # 1. 创建防火墙策略 resource "aws_networkfirewall_firewall_policy" "test" { name = "example-policy" firewall_policy { stateless_fragment_default_actions = ["aws:drop"] stateless_default_actions = ["aws:pass"] } } # 2. 为防火墙策略写入资源策略(RAM 共享授权) resource "aws_networkfirewall_resource_policy" "test" { resource_arn = aws_networkfirewall_firewall_policy.test.arn policy = jsonencode({ Statement = [{ Action = [ "network-firewall:AssociateFirewallPolicy", "network-firewall:ListFirewallPolicies", ] Effect = "Allow" Resource = aws_networkfirewall_firewall_policy.test.arn Principal = { AWS = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:root" } }] Version = "2012-10-17" }) } # 3. 通过数据源读取策略,供审计或后续逻辑使用 data "aws_networkfirewall_resource_policy" "test" { resource_arn = aws_networkfirewall_resource_policy.test.resource_arn } output "retrieved_policy" { value = data.aws_networkfirewall_resource_policy.test.policy }策略中 Action 的约束
在构造资源策略时,策略的Action元素必须覆盖该类型资源要求的全部操作,否则 AWS 会拒绝写入。根据 资源文档 的说明:
- 当目标是**防火墙策略(Firewall Policy)**时,
Action必须包含network-firewall:ListFirewallPolicies、network-firewall:CreateFirewall、network-firewall:UpdateFirewall、network-firewall:AssociateFirewallPolicy; - 当目标是**规则组(Rule Group)**时,
Action必须包含network-firewall:ListRuleGroups、network-firewall:CreateFirewallPolicy、network-firewall:UpdateFirewallPolicy。
策略文档推荐使用jsonencode函数构造,以保证输出为紧凑、无多余空白的合法 JSON(资源写入时底层会通过structure.NormalizeJsonString做规范化处理,见 resource_policy.go)。
底层实现原理:数据源如何读取策略
数据源的核心逻辑位于dataSourceResourcePolicyRead(见 resource_policy_data_source.go),整个读取流程可拆解为四步:
- 获取客户端:从
meta.(*conns.AWSClient)中取出 Network Firewall 服务客户端(NetworkFirewallClient); - 调用查找函数:从
resource_arn参数取值,调用findResourcePolicyByARN(ctx, conn, resourceARN); - 处理错误:若读取失败,返回形如
reading NetworkFirewall Resource Policy (<arn>): ...的诊断信息; - 写回状态:将
resource_arn设为id,同时把返回的策略与resource_arn写回d.Set。
真正发起 API 请求的是查找函数findResourcePolicyByARN(见 resource_policy.go),其关键行为包括:
- 构造
DescribeResourcePolicyInput{ResourceArn: arn}并调用DescribeResourcePolicyAPI; - 捕获
ResourceNotFoundException,将其转换为retry.NotFoundError,供上层判断“资源不存在”; - 若响应体或
Policy字段为空,返回tfresource.NewEmptyResultError(),避免把空值写入状态; - 正常情况下返回策略字符串指针
*string。
也就是说,数据源的每一次读取都会实时调用 AWS 的DescribeResourcePolicyAPI,返回的是云上最新状态,而非 Terraform 状态文件中的缓存值。
集成测试:数据源行为验证
仓库为数据源提供了完整的集成测试TestAccNetworkFirewallResourcePolicyDataSource_basic(见 resource_policy_data_source_test.go),从测试断言中可以提炼出数据源的几条可验证行为:
policy属性内容应与写入的策略一致(测试用正则匹配"Action":["network-firewall:AssociateFirewallPolicy","network-firewall:ListFirewallPolicies"]片段);resource_arn属性与资源写入的 ARN 严格相等(通过TestCheckResourceAttrPair与aws_networkfirewall_firewall_policy.test.arn做配对校验);- 测试运行需要真实 AWS 凭证(
acctest.ParallelTest+acctest.PreCheck),属于标准 acceptance test 模式,详见仓库的 running-and-writing-acceptance-tests.md。
常见问题与注意事项
- 查询不存在的资源 ARN:底层会把
ResourceNotFoundException转为 NotFound 语义。在数据源场景下,若目标资源不存在,plan会报错;若目标资源存在但尚未绑定任何资源策略,DescribeResourcePolicy会返回空策略或直接返回 NotFound,均会反映为读取失败,需要先在目标资源上创建资源策略。 id与resource_arn的关系:数据源的id就是资源 ARN,二者等价,可用于TestCheckResourceAttrPair或作为引用传给其他资源。- 跨区域读取:
region参数允许数据源在非 provider 默认区域查询;若配置了region,请确保该区域确实存在目标资源,否则 API 会返回区域不匹配或资源不存在的错误。 - 策略的 JSON 规范化:AWS 返回的策略可能与写入时在空白字符、字段排序上存在差异。若需要将数据源读出的
policy与本地期望策略做字符串相等比较,建议先通过jsonencode(jsondecode(...))规范化后再对比,避免因格式差异产生误判。
总结
aws_networkfirewall_resource_policy数据源是 Network Firewall 资源策略共享场景中的标准读取入口:通过resource_arn定位资源,实时调用DescribeResourcePolicy返回策略全文,并以id/policy两个属性向 Terraform 暴露结果。结合 数据源文档、资源文档 以及 数据源实现 与 集成测试,你可以在跨账户共享防火墙策略与规则组的工作流中,可靠地读取、审计并复用现有资源策略。
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考