如何在同一个 CloudFormation 模板中声明多个相似的资源组?
How to declare multiple and similar groups of resources in the same CloudFormation template?
我有一个具有三层的服务,每一层都有一个包含一些实例的自动缩放组。这些层的不同(在启动配置、实例数量等方面)由单个参数(“角色”)控制。因此,我使用如下参数调用模板:
{
...
"Parameters": {
...
"Role": {
"AllowedValues": [
"inbound",
"filter",
"outbound"
],
...
},
},
"Conditions" : {
"IsStaging" : { "Fn::Equals" : [ { "Ref": "Environment" }, "eu-staging"] },
"IsInbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "inbound"] },
"IsFilter" : { "Fn::Equals" : [ { "Ref": "Role" }, "filter"] },
"IsOutbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "outbound"] }
},
"Resources": {
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsFilter", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
}
}
现在我想在同一个 CloudFormation 模板中声明这三个层(以便它与现有管道作业透明集成,并受益于 CloudFormation 功能,例如回滚)。此外,我想避免重写三次资源,每层一次如下:
{
...
"Parameters": {
...
"Role": {
"AllowedValues": [
"inbound",
"filter",
"outbound"
],
...
},
},
"Conditions" : {
"IsStaging" : { "Fn::Equals" : [ { "Ref": "Environment" }, "eu-staging"] },
"IsInbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "inbound"] },
"IsFilter" : { "Fn::Equals" : [ { "Ref": "Role" }, "filter"] },
"IsOutbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "outbound"] }
},
"Resources": {
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsInbound", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsFilter", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsOutbound", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
}
}
我怎样才能做到这一点而不需要我为三层重写相同的代码?
如果您只想使用一个模板,则不能没有 CloudFormation {CFN) macros。
处理重复的常用方法是使用nested stacks。这将需要您将这三个服务的通用代码放在一个单独的模板中,并且它们在父模板中使用它们的特定参数三次包含它们。
我有一个具有三层的服务,每一层都有一个包含一些实例的自动缩放组。这些层的不同(在启动配置、实例数量等方面)由单个参数(“角色”)控制。因此,我使用如下参数调用模板:
{
...
"Parameters": {
...
"Role": {
"AllowedValues": [
"inbound",
"filter",
"outbound"
],
...
},
},
"Conditions" : {
"IsStaging" : { "Fn::Equals" : [ { "Ref": "Environment" }, "eu-staging"] },
"IsInbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "inbound"] },
"IsFilter" : { "Fn::Equals" : [ { "Ref": "Role" }, "filter"] },
"IsOutbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "outbound"] }
},
"Resources": {
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsFilter", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
}
}
现在我想在同一个 CloudFormation 模板中声明这三个层(以便它与现有管道作业透明集成,并受益于 CloudFormation 功能,例如回滚)。此外,我想避免重写三次资源,每层一次如下:
{
...
"Parameters": {
...
"Role": {
"AllowedValues": [
"inbound",
"filter",
"outbound"
],
...
},
},
"Conditions" : {
"IsStaging" : { "Fn::Equals" : [ { "Ref": "Environment" }, "eu-staging"] },
"IsInbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "inbound"] },
"IsFilter" : { "Fn::Equals" : [ { "Ref": "Role" }, "filter"] },
"IsOutbound" : { "Fn::Equals" : [ { "Ref": "Role" }, "outbound"] }
},
"Resources": {
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsInbound", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsFilter", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
...
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
...
"SecurityGroupEgress": [
{"Fn::If": ["IsOutbound", { "CidrIp": "10.243.74.0/24", "IpProtocol": "tcp", "FromPort": "9094", "ToPort": "9094" }, { "Ref": "AWS::NoValue" } ]}
],
"Tags": [
{
"Key": "Name",
"Value": { "Fn::Join" : [ "-", [ "smtp-service-security-group", {"Ref": "Role"} ] ] }
},
...
],
}
},
}
}
我怎样才能做到这一点而不需要我为三层重写相同的代码?
如果您只想使用一个模板,则不能没有 CloudFormation {CFN) macros。
处理重复的常用方法是使用nested stacks。这将需要您将这三个服务的通用代码放在一个单独的模板中,并且它们在父模板中使用它们的特定参数三次包含它们。