Recursive Security Groups with Cloudformation

with tags AWS cloudformation ec2 securitygroups -

So it seems there’s very little out there to document how to set an ec2 security group to grant access to itself using cloudformation. And it had me scratching my head for ages.

You would think that something like this would work?

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "security group granting access to itself",
  "Resources" : {
      "SecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable access to itself",
        "SecurityGroupIngress" : [ {
          "FromPort" : "80",
          "ToPort" : "80",
          "IpProtocol" : "TCP",
          "SourceSecurityGroupName" : { "Ref" : "SecurityGroup" }
        }]
      }
    }
  }
}

but this results in the ever so helpful Template validation error

Circular dependency between resources: [SecurityGroup]

How it is still possible to create this using cloudformation but you need to seperate out the group and its ingress and egress (if using a vpc) rules

Since as SourceSecurityGroupName only works in ec2 classic and SourceSecurityGroupId only works inside a VPC you’ll need to switch between templates as needed

EC2-Classic

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "security group granting access to itself",
  "Resources" : {
    "SG": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "A Group that allows access to itself"
      }
    },
    "SGIngress": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupName" : {
          "Ref" : "SG"
        },
        "IpProtocol": "tcp",
        "FromPort": "80",
        "ToPort": "80",
        "SourceSecurityGroupName": {
          "Ref": "SG"
        }
      }
    }
  }
}

VPC

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "security group granting access to itself",
  "Resources" : {
    "SG": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "VpcId" : "vpc-xxxxxxxx"
        "GroupDescription": "A Group that allows access to itself"
      }
    },
    "SGIngress": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupID" : {
          "Ref" : "SG"
        },
        "IpProtocol": "tcp",
        "FromPort": "80",
        "ToPort": "80",
        "SourceSecurityGroupID": {
          "Ref": "SG"
        }
      }
    }
  }
}

Written by
Later article
Boxen
Older article
First!