title: Configure interdependent security groups in AWS VPC
body: <p>In the AWS VPC, I added a security group for the database access that allows any request from a specific CIDR IP on port 3306. This CIDR IP includes private subnets as well as public subnets. A public subnet is allowed so that database can explicitly be connected to developers machines using bastion host (EC2 instance configured on VPC's public subnet and assigned an IP from Amazon's pool of public IPs).</p>
  <p>Ideally, services on a private subnet should able to connect to a database.</p>
  <ol>
  <li>Rather than defining the network mask from where the connection is allowed in one security group, is there any elegant way to do it (probably by creating two security groups as defined in this <a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html" rel="nofollow noreferrer">AWS document</a>)?</li>
  <li>Database should connect only on 3306 port but services should be allowed to use any port for the database access. How to configure a security group to achieve this? For example, one security group that allows requests on only 3306 port (this security group can be attached to the database). And, another security that allows connection to all ports (this security group can be attached to microservices instances). Somehow this microservice security group should be mapped to a database security group in such a way that no matter on what port request is coming from it should in turn call database security group on 3306 port. Can this be done?</li>
  </ol>
  <p>Tried something along this line:</p>
  <pre><code>DBConnectableSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        VpcId: ...
        GroupDescription: Allows for connection to the DB cluster.
  
  ServerlessDBSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        VpcId: ...
       GroupDescription: Defines rules for connecting to the DB cluster. 
  
  OutboundRule:
      Type: AWS::EC2::SecurityGroupEgress
      Properties:
        IpProtocol: tcp
        FromPort: 0
        ToPort: 65535
        DestinationSecurityGroupId: !GetAtt ServerlessDBSecurityGroup.GroupId
        GroupId: !GetAtt DBConnectableSecurityGroup.GroupId
  
  InboundRule:
      Type: AWS::EC2::SecurityGroupIngress
      Properties:
        IpProtocol: tcp
        FromPort: 3306
        ToPort: 3306
        SourceSecurityGroupId: !GetAtt DBConnectableSecurityGroup.GroupId
        GroupId: !GetAtt ServerlessDBSecurityGroup.GroupId
  </code></pre>
  <hr />
  <p><strong>App-SG -- Inbound Rule</strong></p>
  <p><a href="https://i.stack.imgur.com/Rl820.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Rl820.png" alt="App-SG -- Inbound Rule" /></a></p>
  <p><strong>DB-SG -- Inbound Rule (source is pointing to App-SG)</strong></p>
  <p><a href="https://i.stack.imgur.com/Oel2M.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Oel2M.png" alt="DB-SG -- Inbound RUle" /></a></p>
  <p><strong>App-SG and DB-SG -- Outbound Rule</strong></p>
  <p><a href="https://i.stack.imgur.com/IOVZc.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/IOVZc.png" alt="App-SG -- Outbound Rule" /></a></p>
  <p>Now I associate <code>App-SG</code> with an application. This application can successfully connect to the database on port <code>3306</code> (same as configured in Inbound Rule of <code>DB-SG</code>).</p>
  <p>I associate <code>App-SG</code> with another application. This application uses a different port to connect to the database, port <code>3310</code>. As <code>App-SG</code> allows all ports, I expect this to connect to the database but this does not work and the connection is refused.</p>