Walls
Walls

Reputation: 4010

CloudFormation SecurityGroup Circular Reference

I am working with two simple web apps that need to talk to each other. Within AWS CloudFormation I have a template that creates an EC2 instance and installs both applications on the same server (eventually I'll split them up, but for now they live on the same EC2 instance).

As part of the EC2 instance, I have to define the SecurityGroup to use. For now I have been using a default one, but I would like to build one dynamically. In the group I allow SSH in from my machine, and a few ports from the box to itself.

When using the default group, after the fact I can add in the server's public ip to its own security group to allow it to communicate to itself. The problem is during the CloudFormation template, I am getting a circular reference between the SecurityGroup and the EC2 instance. The instance needs a SecurityGroup to start, and that group needs to contain the Public IP rule for the EC2 box.

Is there a better way to do this, or somehow lock in something along the lines of "localhost" to allow these traffic in for now?

Upvotes: 7

Views: 10024

Answers (2)

Anupam Mahapatra
Anupam Mahapatra

Reputation: 833

We can self reference a security group during creation as such:

---
Description: Create a VPC with a SG which references itself
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  vpctester:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 172.16.0.0/23
      EnableDnsSupport: false
      EnableDnsHostnames: false
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: vpctester
  sgtester:
    Type: AWS::EC2::SecurityGroup
    DependsOn: vpctester
    Properties:
      GroupDescription: vpc tester sg
      VpcId:
        Ref: vpctester
  sgtesteringress:
    Type: AWS::EC2::SecurityGroupIngress
    DependsOn: sgtester
    Properties:
      GroupId:
        Ref: sgtester
      IpProtocol: tcp
      FromPort: '0'
      ToPort: '65535'
      SourceSecurityGroupId:
        Ref: sgtester

Please read my post for more info: https://dev.to/anupamncsu/self-referencing-security-groups-on-aws-59gb

Upvotes: 1

Daniel Conde Marin
Daniel Conde Marin

Reputation: 7742

You have a couple of options:

  1. You can have a self referencing security group for this, which will mean the EC2 instance will be allowed to communicate to itself since is on that security group. There is a caveat, and that is don't use embedded ingress and egress rules in the AWS::EC2::SecurityGroup, instead use AWS::EC2::SecurityGroupEgress and AWS::EC2::SecurityGroupIngress separate, as noted here.

Would look like:

"Resources" : {
    "SelfRefSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Has access to itself",
        "VpcId" : "vpc-xxxxxx"
      }
    },
    "MySecurityGroupIngress" : {
         "Type" : "AWS::EC2::SecurityGroupIngress",
         "Properties" : {
             "GroupId" : { "Ref" : "SelfRefSecurityGroup" },
             "IpProtocol" : "tcp",
             "ToPort" : "65535",
             "FromPort" : "0",
             "SourceSecurityGroupId" : { "Ref" : "SelfRefSecurityGroup" }
         },
         "DependsOn" : "SelfRefSecurityGroup"
     }
  1. Best option: Create 2 host entries in the box (or better yet set the dns entries using a Route53 private hosted zone):

    webapp1.com 127.0.0.1

    webapp2.com 127.0.0.1

I wouldn't advice having the box talk to itself via its public IP. Probably you'll even incur in cost! (https://aws.amazon.com/ec2/pricing/on-demand/) Plus the added maintenance of the SG.

Upvotes: 18

Related Questions