Not sure if here or SO is the better place to ask this…
I'm trying to split up our CloudFormation templates to make them more usable and smaller.
I've hit an issue where I wish to use a "basic" security group template that is essentially empty, then reference that along with parameters for each security group I need to make.
My issue comes with filling in the "SecurityGroupIngress/Egress" parts, as these contain json arrays, and as far as I can see, you can only pass in strings or numbers via parameters.
Here's an example;
Parent Stack:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "CloudFormation template to create all Security Groups",
"Resources": {
"CommonSecurityGroupStack" : {
"Type" : "AWS::CloudFormation::Stack",
"DependsOn": [
],
"Properties" : {
"TemplateURL" : "https://s3.template.url/template.name",
"TimeoutInMinutes" : "60",
"Parameters": {
"VPC" : { "Ref": "VPC" },
"VpcCidrRange": { "Ref": "VpcCidrRange" },
"SecurityGroupIngress": { "Something here" },
"SecurityGroupName": "CommonSecurityGroup"
}
}
}
}
}
Nested Stack:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "CloudFormation template to create a security group",
"Parameters": {
"VPC": {
"Description": "Name of the VPC",
"Type": "String"
},
"GroupDescription": {
"Description": "Description of Security Group",
"Type": "String"
},
"SecurityGroupIngress" : {
"Description": "List of rules for the Security Group Ingress"
},
"VpcCidrRange": {
"Description": "CIDR IP range",
"Type": "String",
"MinLength": "9",
"MaxLength": "18",
"Default": "0.0.0.0/0",
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription": "must be a valid CIDR range of the form x.x.x.x/x."
},
"SecurityGroupName": {
"Description": "Name of the Security Group",
"Type": "String"
}
},
"Resources": {
"SecurityGroup": {
"DependsOn": [],
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": { "Ref": "GroupDescription" },
"VpcId": {
"Ref": "VPC"
},
"SecurityGroupIngress": {"Ref" : "SecurityGroupIngress"},
"Tags": [
{
"Key": "Name",
"Value": { "Ref": "SecurityGroupName" }
}
]
}
}
}
}
I need a way of passing in something to the equivalent of the following, into the stack as a parameter to fill in the SecurityGroupIngress
property.
[
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": {
"Ref": "VpcCidrRange"
}
},
{
"IpProtocol": "tcp",
"FromPort": "443",
"ToPort": "443",
"CidrIp": {
"Ref": "VpcCidrRange"
}
}
]
Best Answer
Unfortunately, CloudFormation is not that sophisticated. You're limited on the data types that can be used as parameters:
Instead, try the following:
AWS::EC2::SecurityGroupIngress
resources, andReferences: