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).


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.


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",
                "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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.