AWS CloudFormation:在嵌套堆栈之间传递值
AWS CloudFormation: Passing Values between Nested Stacks
更多 AWS 问题!好的,所以这个想法是一个主模板调用所有嵌套的堆栈。在这里的帮助下,我弄清楚了如何将参数从 master 传递到嵌套堆栈。现在我想弄清楚如何将值从嵌套堆栈传递到嵌套堆栈。我相信这应该通过出口和进口来完成,但我认为我不太正确。我不确定是我的导入还是导出有误。
我得到的错误是:
No export named TestStack1-VpcStackID found. Rollback requested by user.
大师:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Master template",
"Parameters" : {
"availabilityZone" : {
"Default" : "us-east-1d",
"Description" : "Enter AvailabilityZone.",
"Type" : "String"
},
"VpcCidrBlock" : {
"Default" : "10.0.0.0/16",
"Description" : "VPC CIDR Block.",
"Type" : "String"
},
"PublicSubnetCidrBlock" : {
"Default" : "10.0.0.0/24",
"Description" : "Public subnet CIDR block.",
"Type" : "String"
}
},
"Resources" : {
"VpcStack" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"Parameters" : {
"VpcCidrBlock" : {
"Ref" : "VpcCidrBlock"
}
},
"TemplateURL" : "https://s3.amazonaws.com/url/templates/vpcStack.json",
"TimeoutInMinutes" : "5"
}
},
"PublicRouteStack" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"Parameters" : {
"PublicSubnetCidrBlock" : {
"Ref" : "PublicSubnetCidrBlock"
},
"VpcStack" : {
"Fn::ImportValue" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
}
},
"TemplateURL" : "https://s3.amazonaws.com/url/templates/publicRouteStack.json",
"TimeoutInMinutes" : "5"
}
}
}
}
VpcStack(嵌套 - 我认为我输出不正确):
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "VPC template",
"Parameters" : {
"VpcCidrBlock" : {
"Description" : "Vpc CIDR Block.",
"Type" : "String"
}
},
"Resources" : {
"VpcStack" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"CidrBlock" : {
"Ref" : "VpcCidrBlock"
},
"Tags" : [
{
"Key" : "Application",
"Value" : {
"Ref" : "AWS::StackName"
}
}
]
}
}
},
"Outputs" : {
"VpcStack" : {
"Description" : "VPC Stack ID.",
"Value" : {
"Ref" : "VpcStack"
},
"Export" : {
"Name" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
}
}
}
}
PublicStubnetStack(我认为这是失败的地方):
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Public Subnet Stack",
"Parameters" : {
"PublicSubnetCidrBlock" : {
"Default" : "10.0.0.0/24",
"Description" : "Public subnet CIDR block.",
"Type" : "String"
},
"VpcStack" : {
"Description" : "VPC Stack.",
"Type" : "String"
}
},
"Resources" : {
"PublicSubnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : {
"Ref" : "VpcStack"
},
"CidrBlock" : {
"Ref" : "PublicSubnetCidrBlock"
},
"Tags" : [
{
"Key" : "Application",
"Value" : {
"Ref" : "AWS::StackName"
}
},
{
" Key" : "Network",
"Value" : "Public"
}
]
}
}
},
"Outputs" : {
"PublicSubnet" : {
"Description" : "Public Subnet ID.",
"Value" : {
"Ref" : "PublicSubnet"
},
"Export" : {
"Name" : {
"Fn::Sub" : "${AWS::StackName}-PublicSubnetID"
}
}
}
}
}
抱歉发布了这么多,我对 AWS 还很陌生,正在努力快速掌握它。
问题
您的问题是您将值导出为
"Export" : {
"Name" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
}
您正在使用 ${AWS::StackName}
变量,它将 当前堆栈 名称替换为您的导出变量名称。请注意,这是嵌套堆栈 .
的堆栈名称
然而,在您的包装器模板中,您试图将值导入为:
"Fn::ImportValue" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
同样,您正在用变量 ${AWS::StackName}
替换 当前堆栈 ,在本例中 是您的包装堆栈 .
请注意,当您使用嵌套堆栈时,您实际上是在创建一个新堆栈,因此堆栈名称会根据您所在的模板而变化。
分辨率
不要使用 import/export 作为变量。
在嵌套模板中,从输出中删除 Export
元素。你不需要它们。只需使用堆栈参数将值从包装器堆栈传递到嵌套堆栈,并使用堆栈输出将值从嵌套堆栈传回到包装器堆栈。
在您的包装器堆栈中,像这样使用 VpcStack
的输出:
"PublicRouteStack" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"Parameters" : {
"PublicSubnetCidrBlock" : {
"Ref" : "PublicSubnetCidrBlock"
},
"VpcStack" : {
"Fn::GetAtt" : [ "VpcStack", "Outputs.VpcStack" ]
}
},
"TemplateURL" : "https://s3.amazonaws.com/url/templates/publicRouteStack.json",
"TimeoutInMinutes" : "5"
}
}
请注意,在这种情况下,我通过 Fn::GetAtt
函数使用 VpcStack
嵌套堆栈中名为 VpcStack
的 output。
PS。为了清楚起见,您应该更改一些名称。尽量避免在所有地方重复使用相同的名称。它有助于让事情变得清晰。
更多 AWS 问题!好的,所以这个想法是一个主模板调用所有嵌套的堆栈。在这里的帮助下,我弄清楚了如何将参数从 master 传递到嵌套堆栈。现在我想弄清楚如何将值从嵌套堆栈传递到嵌套堆栈。我相信这应该通过出口和进口来完成,但我认为我不太正确。我不确定是我的导入还是导出有误。
我得到的错误是:
No export named TestStack1-VpcStackID found. Rollback requested by user.
大师:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Master template",
"Parameters" : {
"availabilityZone" : {
"Default" : "us-east-1d",
"Description" : "Enter AvailabilityZone.",
"Type" : "String"
},
"VpcCidrBlock" : {
"Default" : "10.0.0.0/16",
"Description" : "VPC CIDR Block.",
"Type" : "String"
},
"PublicSubnetCidrBlock" : {
"Default" : "10.0.0.0/24",
"Description" : "Public subnet CIDR block.",
"Type" : "String"
}
},
"Resources" : {
"VpcStack" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"Parameters" : {
"VpcCidrBlock" : {
"Ref" : "VpcCidrBlock"
}
},
"TemplateURL" : "https://s3.amazonaws.com/url/templates/vpcStack.json",
"TimeoutInMinutes" : "5"
}
},
"PublicRouteStack" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"Parameters" : {
"PublicSubnetCidrBlock" : {
"Ref" : "PublicSubnetCidrBlock"
},
"VpcStack" : {
"Fn::ImportValue" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
}
},
"TemplateURL" : "https://s3.amazonaws.com/url/templates/publicRouteStack.json",
"TimeoutInMinutes" : "5"
}
}
}
}
VpcStack(嵌套 - 我认为我输出不正确):
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "VPC template",
"Parameters" : {
"VpcCidrBlock" : {
"Description" : "Vpc CIDR Block.",
"Type" : "String"
}
},
"Resources" : {
"VpcStack" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"CidrBlock" : {
"Ref" : "VpcCidrBlock"
},
"Tags" : [
{
"Key" : "Application",
"Value" : {
"Ref" : "AWS::StackName"
}
}
]
}
}
},
"Outputs" : {
"VpcStack" : {
"Description" : "VPC Stack ID.",
"Value" : {
"Ref" : "VpcStack"
},
"Export" : {
"Name" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
}
}
}
}
PublicStubnetStack(我认为这是失败的地方):
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Public Subnet Stack",
"Parameters" : {
"PublicSubnetCidrBlock" : {
"Default" : "10.0.0.0/24",
"Description" : "Public subnet CIDR block.",
"Type" : "String"
},
"VpcStack" : {
"Description" : "VPC Stack.",
"Type" : "String"
}
},
"Resources" : {
"PublicSubnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : {
"Ref" : "VpcStack"
},
"CidrBlock" : {
"Ref" : "PublicSubnetCidrBlock"
},
"Tags" : [
{
"Key" : "Application",
"Value" : {
"Ref" : "AWS::StackName"
}
},
{
" Key" : "Network",
"Value" : "Public"
}
]
}
}
},
"Outputs" : {
"PublicSubnet" : {
"Description" : "Public Subnet ID.",
"Value" : {
"Ref" : "PublicSubnet"
},
"Export" : {
"Name" : {
"Fn::Sub" : "${AWS::StackName}-PublicSubnetID"
}
}
}
}
}
抱歉发布了这么多,我对 AWS 还很陌生,正在努力快速掌握它。
问题
您的问题是您将值导出为
"Export" : {
"Name" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
}
您正在使用 ${AWS::StackName}
变量,它将 当前堆栈 名称替换为您的导出变量名称。请注意,这是嵌套堆栈 .
然而,在您的包装器模板中,您试图将值导入为:
"Fn::ImportValue" : {
"Fn::Sub" : "${AWS::StackName}-VpcStackID"
}
同样,您正在用变量 ${AWS::StackName}
替换 当前堆栈 ,在本例中 是您的包装堆栈 .
请注意,当您使用嵌套堆栈时,您实际上是在创建一个新堆栈,因此堆栈名称会根据您所在的模板而变化。
分辨率
不要使用 import/export 作为变量。
在嵌套模板中,从输出中删除 Export
元素。你不需要它们。只需使用堆栈参数将值从包装器堆栈传递到嵌套堆栈,并使用堆栈输出将值从嵌套堆栈传回到包装器堆栈。
在您的包装器堆栈中,像这样使用 VpcStack
的输出:
"PublicRouteStack" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"Parameters" : {
"PublicSubnetCidrBlock" : {
"Ref" : "PublicSubnetCidrBlock"
},
"VpcStack" : {
"Fn::GetAtt" : [ "VpcStack", "Outputs.VpcStack" ]
}
},
"TemplateURL" : "https://s3.amazonaws.com/url/templates/publicRouteStack.json",
"TimeoutInMinutes" : "5"
}
}
请注意,在这种情况下,我通过 Fn::GetAtt
函数使用 VpcStack
嵌套堆栈中名为 VpcStack
的 output。
PS。为了清楚起见,您应该更改一些名称。尽量避免在所有地方重复使用相同的名称。它有助于让事情变得清晰。