无法将参数从子 CloudFormation 模板发送到另一个子模板
Can't send parameters from a child CloudFormation template to another child template
我正在制作一个使用 AWS::CloudFormation::Stack
资源生成其他嵌套堆栈的 CloudFormation 模板的怪物。这样做的目的是经典的职责和管理分离。
总体目标是从头开始构建应用程序环境(从 VPC 开始,到应用程序实例结束)。
到目前为止,大部分都有效。但是我在引用用于创建 EC2 实例的子网 CF 模板和安全组 CF 模板的输出时遇到了障碍。
它是这样工作的:
主模板-->构建VPC-->调用子模板构建子网-->调用子模板构建安全组-->调用子模板构建EC2实例
我需要将子网和安全组模板的输出传递给 EC2 实例模板,以便将实例配置到架构的正确部分。 VPC ID ref 和 KeyPairs 正常通过,但 subnetID 和 securitygroupID 没有。
这是调用安全 group/subnet 模板的主模板部分:
"DevNetworkStack": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": [
"SNVPC",
"SNIGW"
],
"Properties": {
"TemplateURL": {
"Fn::FindInMap": [
"TemplateURLs",
"DevNetworkStack",
"URL"
]
},
"TimeoutInMinutes": "30",
"Parameters": {
"VPCID": {
"Ref": "SNVPC"
},
"SNIGW": {
"Ref": "SNIGW"
}
}
}
},
"DevSecurityGroupsStack": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": "DevNetworkStack",
"Properties": {
"TemplateURL": {
"Fn::FindInMap": [
"TemplateURLs",
"DevSecurityGroupsStack",
"URL"
]
},
"TimeoutInMinutes": "30",
"Parameters": {
"VPCID": {
"Ref": "SNVPC"
}
}
}
},
这些工作正常。他们创造,一切都很好。模板提供如下输出:
"Outputs": {
"DevAdminSubnetID": {
"Description": "DevAdminSubnetID",
"Value": {
"Ref": "DevAdminSubnet"
}
},
...
"Outputs": {
"DevAdminSecurityGroupID": {
"Description": "DevAdminSecurityGroupID",
"Value": {
"Ref": "DevAdminSecurityGroup"
}
},
我可以在 CF 控制台中看到输出。
现在,下一个模板正在尝试使用安全组 ID 和子网 ID。但是没用。
主模板调用下一个子模板为:
"DevAdminStack": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": [
"DevNetworkStack",
"DevSecurityGroupsStack",
"EC2DevRoleInstanceProfile",
"S3DevUserDataBucket",
"S3DevHomeDirsDataBucket"
],
"Properties": {
"TemplateURL": {
"Fn::FindInMap": [
"TemplateURLs",
"DevAdminStack",
"URL"
]
},
"TimeoutInMinutes": "30",
"Parameters": {
"AdminKeyPair": {
"Ref": "AdminServersKeyPair"
},
"VPCID": {
"Ref": "SNVPC"
},
"DevAdminSecurityGroupID": [
{
"Fn::GetAtt": [
"DevSecurityGroupsStack",
"Outputs.DevAdminSecurityGroupID"
]
}
],
"DevAdminSubnetID": [
{
"Fn::GetAtt": [
"DevNetworkStack",
"Outputs.DevAdminSubnetID"
]
}
]
}
}
}
...子模板如下所示(为简洁起见删除了一些部分,因为我现在只是在测试)
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Dev-Admin",
"Mappings": {
"RegionMap": {
"DevAdminServer": {
"AMI": "ami-6fc9770e",
"InstanceType": "t2.micro"
}
}
},
"Parameters": {
"AdminKeyPair": {
"Type": "AWS::EC2::KeyPair::KeyName"
},
"VPCID": {
"Type": "AWS::EC2::VPC::Id"
},
"DevAdminSecurityGroupID": {
"Type": "AWS::EC2::SecurityGroup::Id"
},
"DevAdminSubnetID": {
"Type": "AWS::EC2::Subnet::Id"
}
},
"Resources": {
"DevAdminServer": {
"Type": "AWS::EC2::Instance",
"Metadata": {
"Comment": "Sets up administrative tools for the server",
"AWS::CloudFormation::Init": {
"config": {
"packages": {
"yum": {}
},
"files": {},
"services": {}
}
}
},
"Properties": {
"ImageId": {
"Fn::FindInMap": [
"RegionMap",
"DevAdminServer",
"AMI"
]
},
"SecurityGroupIds": [
{
"Ref": "DevAdminSecurityGroupID"
}
],
"SubnetId": {
"Ref": "DevAdminSubnetID"
},
"InstanceType": {
"Fn::FindInMap": [
"RegionMap",
"DevAdminServer",
"InstanceType"
]
},
"KeyName": {
"Ref": "AdminKeyPair"
},
"Tags": [
{
"Key": "Application",
"Value": {
"Ref": "AWS::StackId"
}
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[]
]
}
}
}
}
}
}
但是此资源创建失败并出现错误:
属性 参数的值必须是具有字符串(或简单类型)属性的对象
我知道是最后两个变量(subnetID 和 securitygroupID)引起了问题,因为我删除了它们并且配置子模板工作正常。
我做错了什么?
DevAdminSecurityGroupID
和 DevAdminSubnetID
的值在您的主模板中定义为 JSON 数组 []
,但它们应该是字符串(在 Fn::GetAtt
内函数展开):
"DevAdminSecurityGroupID":
{
"Fn::GetAtt": [
"DevSecurityGroupsStack",
"Outputs.DevAdminSecurityGroupID"
]
},
"DevAdminSubnetID":
{
"Fn::GetAtt": [
"DevNetworkStack",
"Outputs.DevAdminSubnetID"
]
}
我正在制作一个使用 AWS::CloudFormation::Stack
资源生成其他嵌套堆栈的 CloudFormation 模板的怪物。这样做的目的是经典的职责和管理分离。
总体目标是从头开始构建应用程序环境(从 VPC 开始,到应用程序实例结束)。
到目前为止,大部分都有效。但是我在引用用于创建 EC2 实例的子网 CF 模板和安全组 CF 模板的输出时遇到了障碍。
它是这样工作的:
主模板-->构建VPC-->调用子模板构建子网-->调用子模板构建安全组-->调用子模板构建EC2实例
我需要将子网和安全组模板的输出传递给 EC2 实例模板,以便将实例配置到架构的正确部分。 VPC ID ref 和 KeyPairs 正常通过,但 subnetID 和 securitygroupID 没有。
这是调用安全 group/subnet 模板的主模板部分:
"DevNetworkStack": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": [
"SNVPC",
"SNIGW"
],
"Properties": {
"TemplateURL": {
"Fn::FindInMap": [
"TemplateURLs",
"DevNetworkStack",
"URL"
]
},
"TimeoutInMinutes": "30",
"Parameters": {
"VPCID": {
"Ref": "SNVPC"
},
"SNIGW": {
"Ref": "SNIGW"
}
}
}
},
"DevSecurityGroupsStack": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": "DevNetworkStack",
"Properties": {
"TemplateURL": {
"Fn::FindInMap": [
"TemplateURLs",
"DevSecurityGroupsStack",
"URL"
]
},
"TimeoutInMinutes": "30",
"Parameters": {
"VPCID": {
"Ref": "SNVPC"
}
}
}
},
这些工作正常。他们创造,一切都很好。模板提供如下输出:
"Outputs": {
"DevAdminSubnetID": {
"Description": "DevAdminSubnetID",
"Value": {
"Ref": "DevAdminSubnet"
}
},
...
"Outputs": {
"DevAdminSecurityGroupID": {
"Description": "DevAdminSecurityGroupID",
"Value": {
"Ref": "DevAdminSecurityGroup"
}
},
我可以在 CF 控制台中看到输出。
现在,下一个模板正在尝试使用安全组 ID 和子网 ID。但是没用。
主模板调用下一个子模板为:
"DevAdminStack": {
"Type": "AWS::CloudFormation::Stack",
"DependsOn": [
"DevNetworkStack",
"DevSecurityGroupsStack",
"EC2DevRoleInstanceProfile",
"S3DevUserDataBucket",
"S3DevHomeDirsDataBucket"
],
"Properties": {
"TemplateURL": {
"Fn::FindInMap": [
"TemplateURLs",
"DevAdminStack",
"URL"
]
},
"TimeoutInMinutes": "30",
"Parameters": {
"AdminKeyPair": {
"Ref": "AdminServersKeyPair"
},
"VPCID": {
"Ref": "SNVPC"
},
"DevAdminSecurityGroupID": [
{
"Fn::GetAtt": [
"DevSecurityGroupsStack",
"Outputs.DevAdminSecurityGroupID"
]
}
],
"DevAdminSubnetID": [
{
"Fn::GetAtt": [
"DevNetworkStack",
"Outputs.DevAdminSubnetID"
]
}
]
}
}
}
...子模板如下所示(为简洁起见删除了一些部分,因为我现在只是在测试)
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Dev-Admin",
"Mappings": {
"RegionMap": {
"DevAdminServer": {
"AMI": "ami-6fc9770e",
"InstanceType": "t2.micro"
}
}
},
"Parameters": {
"AdminKeyPair": {
"Type": "AWS::EC2::KeyPair::KeyName"
},
"VPCID": {
"Type": "AWS::EC2::VPC::Id"
},
"DevAdminSecurityGroupID": {
"Type": "AWS::EC2::SecurityGroup::Id"
},
"DevAdminSubnetID": {
"Type": "AWS::EC2::Subnet::Id"
}
},
"Resources": {
"DevAdminServer": {
"Type": "AWS::EC2::Instance",
"Metadata": {
"Comment": "Sets up administrative tools for the server",
"AWS::CloudFormation::Init": {
"config": {
"packages": {
"yum": {}
},
"files": {},
"services": {}
}
}
},
"Properties": {
"ImageId": {
"Fn::FindInMap": [
"RegionMap",
"DevAdminServer",
"AMI"
]
},
"SecurityGroupIds": [
{
"Ref": "DevAdminSecurityGroupID"
}
],
"SubnetId": {
"Ref": "DevAdminSubnetID"
},
"InstanceType": {
"Fn::FindInMap": [
"RegionMap",
"DevAdminServer",
"InstanceType"
]
},
"KeyName": {
"Ref": "AdminKeyPair"
},
"Tags": [
{
"Key": "Application",
"Value": {
"Ref": "AWS::StackId"
}
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[]
]
}
}
}
}
}
}
但是此资源创建失败并出现错误:
属性 参数的值必须是具有字符串(或简单类型)属性的对象
我知道是最后两个变量(subnetID 和 securitygroupID)引起了问题,因为我删除了它们并且配置子模板工作正常。
我做错了什么?
DevAdminSecurityGroupID
和 DevAdminSubnetID
的值在您的主模板中定义为 JSON 数组 []
,但它们应该是字符串(在 Fn::GetAtt
内函数展开):
"DevAdminSecurityGroupID":
{
"Fn::GetAtt": [
"DevSecurityGroupsStack",
"Outputs.DevAdminSecurityGroupID"
]
},
"DevAdminSubnetID":
{
"Fn::GetAtt": [
"DevNetworkStack",
"Outputs.DevAdminSubnetID"
]
}