Cloud Formation template add ingress rule to existing security group
Problem scope
I have an application built using multiple cloud formation templates. They need to interact with each other but are too large/complicated to build in one template.
Detail of scenario
Imagine there were only two template (there are significantly more)
- Template A
- Template B
Template A creates a security group (security group A) with itself as the only ingress rule. It is applied to a series of hosts in this template that perform the same function.
Template B creates another security group (Security group B) and a number of hosts (in an elastic beanstalk).
Question
How can I add an ingress rule to Security Group A for traffic from Security Group B using cloud formation?
What have I tried
I have looked through the documentation, I want to create a security group Ingress rule and associate it with security group A but that doesn't seem to be viable as far as I can see - http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html
Other alternatives
I could just use the CIDR range of the hosts that are in Security Group B as that is known before any of this is built (all in VPC's with separate subnets) however I feel there must be a better more secure way than accepting traffic from a cidr range.
Solution 1:
Yes, it can be done.
You need to pass the security group identifier (for Security Group A) into the template for Template B as a parameter. From there, you can reference Security Group A in a AWS::EC2::SecurityGroupIngress
resource.
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Parameters" : {
"SecurityGroupA" : {
"Description" : "Security group to add Ingress rule to",
"Type" : "AWS::EC2::SecurityGroup::Id"
}
},
"Resources" : {
"LocalSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup"
},
"InboundRule": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties":{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"SourceSecurityGroupId": {
"Fn::GetAtt": [ "LocalSecurityGroup", "GroupId" ]
},
"GroupId": {
"Fn::GetAtt": [ "SecurityGroupA", "GroupId" ]
}
}
}
}
}
Note that this example uses the security group ID, which is the case when your security groups are in a VPC. If they are in EC2-Classic, then you would use the GroupName
instead.