使用 aws_cloudformation_export 数据源在 Terraform 中读取 CloudFormation 栈导出值
2026/9/17 22:19:25 网站建设 项目流程

使用 aws_cloudformation_export 数据源在 Terraform 中读取 CloudFormation 栈导出值

【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws

本文以 terraform-provider-aws 中的aws_cloudformation_export数据源(Data Source)为核心,讲解如何通过 Terraform 读取 AWS CloudFormation 栈 Outputs 中带Export属性的导出值,用于跨栈引用(Cross Stack References)场景。读完本文,你将掌握该数据源的参数与返回属性、与aws_cloudformation_stack数据源 / 资源的选型差异、底层 AWS SDK 调用原理(基于ListExports分页读取),并能参考仓库内真实测试用例写出可运行的配置。

背景:CloudFormation Export 与跨栈引用

AWS CloudFormation 允许在模板的 Outputs 部分(即Outputs段)声明栈的输出值,并通过可选的Export属性为某个输出指定一个全局名称。一旦输出被导出,其他 CloudFormation 栈就可以通过Fn::ImportValue引用该名称,从而在栈之间共享资源标识(如 VPC ID、子网 ID、安全组 ID 等)。

aws_cloudformation_export数据源把这一能力开放给 Terraform:它按导出名称读取当前区域内的栈导出值,并将value(导出值)与exporting_stack_id(导出该值的栈 ARN)暴露给 Terraform 配置使用。其官方定位是“提供 CloudFormation 导出(即跨栈引用)的元数据”,对应数据源名为aws_cloudformation_export

一个关键使用前提:同一次 Terraform 运行内慎用

原文档给出了一条非常重要的注意项:

如果你试图在同一次 Terraform 运行中直接消费另一个 CloudFormation 栈刚产出的导出值,请优先使用普通插值(normal interpolation)或 CloudFormation Outputs(即aws_cloudformation_stack数据源),而不是本数据源。

原因在于:本数据源依赖 AWS 侧的ListExportsAPI 返回已发布到云端的导出记录。当一个aws_cloudformation_stack资源在同一 plan/apply 中才被创建或更新时,其导出在 AWS 端可能尚未发布、或处于最终一致性的时间窗口内,此时读取会得到空结果或旧值。因此:

  • 跨栈、跨目录、跨运行消费长期存在的导出 → 使用aws_cloudformation_export
  • 同栈内、同一运行内依赖栈输出 → 使用aws_cloudformation_stack数据源的outputs映射,或直接使用普通插值引用资源属性。

关于同栈输出的读取方式,可对照仓库中 aws_cloudformation_stack 数据源文档,它提供outputs属性直接返回栈的所有输出键值对。

完整示例:把导出的子网 ID 用于 EC2 实例

原文档给出的示例完整继承如下。它先从名为mySubnetIdExportName的导出中读取子网 ID,再把它注入到aws_instancesubnet_id参数:

data "aws_cloudformation_export" "subnet_id" { name = "mySubnetIdExportName" } resource "aws_instance" "web" { ami = "ami-abb07bcb" instance_type = "t2.micro" subnet_id = data.aws_cloudformation_export.subnet_id.value }

要点说明:

  • 导出名称mySubnetIdExportName必须与 CloudFormation 栈中Export.Name完全一致(导出名在区域范围内全局唯一);
  • 通过data.aws_cloudformation_export.subnet_id.value引用导出值;
  • 数据源本身不创建任何云端资源,仅执行只读查询。

结合测试用例理解导出端配置

仓库中的验收测试 export_data_source_test.go 给出了导出端模板的真实写法。静态值场景在aws_cloudformation_stack资源的template_body中声明了一个带Export的输出:

{ "Resources": { "waiter": { "Type": "AWS::CloudFormation::WaitConditionHandle", "Properties": { } } }, "Outputs": { "waiter": { "Value": "waiter", "Description": "VPC ID", "Export": { "Name": "导出名称" } } } }

资源引用场景则创建了一个 VPC 并把其 ID 导出(YAML 模板,对应测试testAccExportDataSourceConfig_resourceReference):

Parameters: CIDR: Type: String Resources: myvpc: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref CIDR Outputs: MyVpcId: Value: !Ref myvpc Description: VPC ID Export: Name: 导出名称

配合data "aws_cloudformation_export" "test" { name = ... }读取后,测试断言valueoutputs.MyVpcId一致。这两段模板可以直接作为导出端配置的实战参考。

参数说明(Argument Reference)

该数据源支持以下参数:

参数类型必填说明
namestring导出名称,即 CloudFormation 控制台中显示的导出名,或在 CLI 中执行cloudformation list-exportsName字段的值
regionstring数据源管理的区域,默认使用 provider 配置中设置的区域

关于region:导出是区域级概念(不同区域的导出相互独立),因此跨区域读取时需显式指定region参数;未指定时沿用 provider 的region配置。

返回属性说明(Attribute Reference)

除上述参数外,数据源还会导出以下属性:

属性类型说明
valuestring由导出名称标识的导出值,来源同cloudformation list-exports返回的Value字段
exporting_stack_idstring包含该导出输出名与值的栈的 ARN

在仓库的第二个验收测试TestAccCloudFormationExportDataSource_resourceReference中,就是用TestCheckResourceAttrPair断言exporting_stack_id与栈资源 ID、value与栈输出outputs.MyVpcId一一对应的:

resource.TestCheckResourceAttrPair(dataSourceName, "exporting_stack_id", resourceName, names.AttrID), resource.TestCheckResourceAttrPair(dataSourceName, names.AttrValue, resourceName, "outputs.MyVpcId"),

这直接印证了exporting_stack_id是“导出该值的 CloudFormation 栈 ARN”,value是“该栈输出导出的具体值”。

底层实现:基于 ListExports 分页读取

数据源的实现位于 export_data_source.go,Schema 定义如下:

  • nameRequired(必填),类型TypeString
  • valueexporting_stack_id:均为Computed(只读计算结果),类型TypeString

读取逻辑dataSourceExportRead的关键流程为:

  1. 通过meta.(*conns.AWSClient).CloudFormationClient(ctx)获取 CloudFormation 客户端;
  2. 构造cloudformation.ListExportsInput{}
  3. 使用cloudformation.NewListExportsPaginator对结果分页遍历,逐页比对page.Exports中每一项的Name是否与参数name相等;
  4. 命中后写入exporting_stack_idvalue
  5. 若遍历完所有分页仍找不到匹配项(value == nil),则返回tfresource.NewEmptyResultError()空结果错误;
  6. 设置资源 ID 为cloudformation-exports-<region>-<name>格式(见d.SetId(fmt.Sprintf("cloudformation-exports-%s-%s", ...)))。

可以看出:导出名称查找是全量分页扫描而非按名称精确查询,因此ListExports返回列表的规模会直接影响查询耗时;对超大规模导出列表的场景,这一实现特性值得注意。数据源通过// @SDKDataSource("aws_cloudformation_export", name="Export")注解注册,并在 service_package_gen.go 中被声明为 SDK 数据源(Region: inttypes.ResourceRegionDefault(),即默认跟随 provider 区域),与aws_cloudformation_stackaws_cloudformation_type同属 CloudFormation 服务包(internal/service/cloudformation/)。

选型对比:export、stack 数据源与普通插值

场景推荐方式理由
消费其他栈(或历史栈)已发布的导出值aws_cloudformation_export按导出名精确读取valueexporting_stack_id
读取某个栈的全部输出/参数/模板aws_cloudformation_stack数据源提供outputsparameterstemplate_body等完整元数据
同一次 Terraform 运行内、同栈内的值传递普通插值或outputs映射避免云端导出未发布的最终一致性问题

简单来说:需要“值 + 出处(栈 ARN)”且目标是已存在的导出时选aws_cloudformation_export;需要更丰富的栈元数据时选aws_cloudformation_stack;同一运行内的依赖直接用 Terraform 引用链。

小结

aws_cloudformation_export是 Terraform 与 CloudFormation 跨栈引用之间的一座桥:它在aws_cloudformation_stack数据源之外,提供按导出名定向读取valueexporting_stack_id的能力,底层通过 CloudFormationListExportsAPI 分页实现,导出名在区域内全局唯一。使用时要牢记“同一运行内慎用”的前提,并可在仓库的 export_data_source_test.go 中找到可直接套用的导出模板与断言写法。

【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询