当我在 AWS CloudFormation 堆栈中使用 Fn::ImportValue 时,收到了“No Export named XYZ found”错误。
解决方法
先决条件:
- 对于要导出值的堆栈,请在 CloudFormation 模板的 Outputs 部分中使用 Export: 标志。
- 在引用导出的值的堆栈中使用 Fn::ImportValue。
要解决使用导入和导出值时堆栈引用的问题,请执行以下操作。
如果使用嵌套堆栈,则使用 DependsOn
默认情况下,CloudFormation 会并行创建所有嵌套堆栈。当 CloudFormation 并行创建子堆栈,并且子堆栈从另一个堆栈导入输出时,堆栈创建可能会失败。导出值可能无法及时供子堆栈使用 Fn::ImportValue 进行导入。
要解决此问题,请使用 DependsOn 属性。此属性在使用 Fn::ImportValue 的堆栈和使用 Export: 属性导出值的堆栈之间创建了显式依赖关系。这样,CloudFormation 只有在创建了导出值的堆栈之后才会创建使用 Fn::ImportValue 的堆栈。
示例: 在嵌套堆栈中,ChildStack01 在 Outputs 部分导出一个值,而 ChildStack02 使用 Fn::ImportValue 从 ChildStack01 导入该值。在以下 YAML 模板中,ChildStack02 使用 DependsOn 属性:
AWSTemplateFormatVersion: 2010-09-09Resources:
ChildStack01:
Type: 'AWS::CloudFormation::Stack'
Properties:
TemplateURL: 'https://s3.amazonaws.com/cloudformation-templates-us-east-1/VPC.template'
TimeoutInMinutes: '60'
ChildStack02:
Type: 'AWS::CloudFormation::Stack'
DependsOn: ChildStack01
Properties:
TemplateURL: 'https://s3.amazonaws.com/cloudformation-templates-us-east-1/Subnet.template'
TimeoutInMinutes: '60'
**注意:**对于跨堆栈引用,使用 Fn::ImportValue 从另一个模板导入值。对于同一堆栈中的引用,使用 Fn::Ref 和 Fn::GetAtt 返回指定参数或资源的值。
验证导入堆栈中的导出名称
要验证导出值是否准确,请采取以下操作:
- 确认导出名称已列在您的 AWS 账户中。
- 当将导出名称从一个堆栈导入到另一个堆栈时,请确认在两个堆栈中使用相同的导出名称。
- 在使用 Fn::ImportValue 创建堆栈之前,请参阅验证导出和导入堆栈的堆栈配置部分。
确保导出的值与导入值所在的 AWS 区域或账户相同
您只能在单个账户和区域内使用跨堆栈引用。但同一账户和区域内的其他堆栈只能导入导出的值。
要解决此问题,在使用 Fn::ImportValue 创建堆栈之前,请参阅验证导出和导入堆栈的堆栈配置部分。
确保在堆栈导入导出的值之前创建或发布导出的值
对于非嵌套堆栈,必须首先部署导出值的堆栈。堆栈必须处于 Create_Complete 或 Update_Complete 状态。
在使用 Fn::ImportValue 创建堆栈之前,请参阅验证导出和导入堆栈的堆栈配置部分。
验证导出和导入堆栈的堆栈配置
要验证导出值是否准备好导入,请使用 CloudFormation 控制台或 AWS 命令行界面(AWS CLI)。
**注意:**导入和导出堆栈必须在同一个区域和账户中。
要使用 CloudFormation 控制台,请完成下面的步骤:
- 打开 CloudFormation 控制台。
- 从导航窗格,选择导出。
- 确认已列出堆栈的导出值。
要使用 AWS CLI,请完成下面的步骤:
-
要列出可用的导出,请运行以下 list-exports 命令:
aws cloudformation list-exports --region us-east-1
**注意:**将 us-east-1 替换为您的区域。
-
在输出中,验证导出中 Name 的值是否与 Fn::ImportValue 值相同。
输出类似于以下示例:
aws cloudformation list-exports --region us-east-1 --output yamlExports:
- ExportingStackId: arn:aws:cloudformation:us-east-1:123456789012:stack/private-vpc/99764070-b56c-xmpl-bee8-062a88d1d800
Name: private-vpc-subnet-a
Value: subnet-01a234bcdefghij56
注意:如果在运行 AWS CLI 命令时收到错误,请参阅排查 AWS CLI 错误。此外,确保您使用的是最新版本的 AWS CLI。
当堆栈导入输出值后,您无法删除正在导出该输出值的堆栈,也无法修改导出的输出值。您必须先删除所有导入,然后才能删除导出堆栈或修改输出值。有关如何使用解决方法的信息,请参阅如何使用 AWS Systems Manager Parameter Store 中的参数在 CloudFormation 堆栈之间共享值?请注意,导出名称在区域内必须是唯一的。
堆栈中导入信息的 import 语句与以下示例类似:
Resources:
WebServerInstance:
Type: 'AWS::EC2::Instance'
Properties:
InstanceType: t2.micro
ImageId: ami-a1b23456
NetworkInterfaces:
AssociatePublicIpAddress: 'true'
DeviceIndex: '0'
DeleteOnTermination: 'true'
SubnetId: Fn::ImportValue: 'private-vpc-subnet-a'