For some reason, I thought I could stack multiple ingress and egress rules in a single AWS::EC2::SecurityGroup (AWS CloudFormation template) this way:
# Wrong !!
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Open HTTP (port 80) and SSH (port 22)"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Sub "${MyIp}"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Even though this did not throw an error, the AWS console’s view of Ingress (Inbound) showed only one rule, not the two I declared:

Where’s my port 22 ingress rule?!!
Through trial and error, I realized I had formatted the template wrong. SecurityGroupIngress
and SecurityGroupEgress
properties are lists. I was treating them as individual entries. In other words, I need to list the multiple Ingress rules under a single SecurityGroupIngress
entry. Like this:
# Correct, Option A
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Open HTTP (port 80) and SSH (port 22)"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Sub "${MyIp}"
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Which did create the (two) Ingress and (one) Egress rules, as expected:


Another option is to declare AWS::EC2::SecurityGroupIngress
and AWS::EC2::SecurityGroupEgress
, attaching them to the SecurityGroup.
Note: Amazon suggests using this method “… only when necessary, typically to allow security groups to reference each other in ingress and egress rules. Otherwise, use the embedded ingress and egress rules of the security group” (such as with Option A, demonstrated above.)
# Correct, Option B
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Open HTTP (port 80) and SSH (port 22)"
VpcId: !Ref VPC
SecurityGroupIngressMySSH:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: "Allow SSH connections from MyIp"
GroupId: !Ref SecurityGroup
CidrIp: !Sub "${MyIp}"
IpProtocol: tcp
FromPort: 22
ToPort: 22
SecurityGroupIngressHTTP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: "Allow HTTP inbound traffic"
GroupId: !Ref SecurityGroup
CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 80
ToPort: 80
SecurityGroupEgress:
Type: AWS::EC2::SecurityGroupEgress
Properties:
Description: "Allow all outbound traffic"
GroupId: !Ref SecurityGroup
CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 80
ToPort: 80
Leave a Reply