DEV Community

Cover image for Configuring Security Groups/IAM Roles - CloudFormation for infrastructure set up -02
Gayan Fonseka for AWS Community Builders

Posted on • Edited on

2 1

Configuring Security Groups/IAM Roles - CloudFormation for infrastructure set up -02

This is a continuation of the previous article where I set up the Virtual Private Network required to host the application using CloudFormation. Feel free to read the need and how to set up the VPC at the below link,

Get rid of old habits- Use CloudFormation for infrastructure set up -01

Now that we have set up various subnets as Public and Private subnets we need to control incoming and outgoing traffic to ensure that our application is secured and able to cater to the user requests. For this purpose, we will have to enable a certain type of traffic through certain ports. E.g. TCP over port 5000 for the application, TCP over port 3306 for MySQL. AWS has provided this facility through security groups that act as a virtual firewall for our EC2 instances that will host our application. Given below is the CloudFormation YAML for security group configuration.

#########################################
# All Security Groups of ABC VPC #
#########################################
---
Resources:
#Security Groups
WebDMZSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Web Ec2 and ALB SG
GroupName: WebDMZSG
VpcId: !ImportValue AbVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 5000
ToPort: 5000
CidrIp: 0.0.0.0/0
- IpProtocol: icmp
FromPort: 8
ToPort: -1
CidrIp: 10.0.0.0/16
DataBaseSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Data Base SG
GroupName: DataBaseSG
VpcId: !ImportValue AbVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !GetAtt WebDMZSG.GroupId
ALBSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
VpcId: !ImportValue AbVPC
GroupName: InternetAlbSG
GroupDescription: Enable HTTP/HTTPS access
SecurityGroupIngress:
- IpProtocol: 'tcp'
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
- IpProtocol: 'tcp'
FromPort: '443'
ToPort: '443'
CidrIp: 0.0.0.0/0
VpcLinkSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
VpcId: !ImportValue AbVPC
GroupName: VpcSG
GroupDescription: Enable HTTP/HTTPS access
SecurityGroupIngress:
- IpProtocol: 'tcp'
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
- IpProtocol: 'tcp'
FromPort: '443'
ToPort: '443'
CidrIp: 0.0.0.0/0
ExConnALBSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
VpcId: !ImportValue AbVPC
GroupName: InternalSG
GroupDescription: Enable HTTP/HTTPS access
SecurityGroupIngress:
- IpProtocol: 'tcp'
FromPort: '80'
ToPort: '80'
SourceSecurityGroupId: !GetAtt VpcLinkSecurityGroup.GroupId
- IpProtocol: 'tcp'
FromPort: '443'
ToPort: '443'
SourceSecurityGroupId: !GetAtt VpcLinkSecurityGroup.GroupId

As you can see, I have created security groups enabling traffic for EC2 instances in the app subnets, database subnet, public load balancer, VPC link, and the private load balancer. This basically covers all the areas for which we need to enable traffic.

As the next step, we will have to export some of these configurations as output values to be used in the coming stacks. I'll be doing that in the below code.

Outputs:
#Security Groups
WebSG:
Description: Ec2 security group
Value: !Ref WebDMZSG
Export:
Name: Ec2SG
DB:
Description: DataBase security group
Value: !Ref DataBaseSG
Export:
Name: DBSG
InternetALB:
Description: Internet facing Load Balancer security group
Value: !Ref ALBSecurityGroup
Export:
Name: ALBSG
InternalALB:
Description: Internal Load Balancer security group
Value: !Ref ExConnALBSecurityGroup
Export:
Name: ExConnALBSG
VPCLink:
Description: API Gw Vpc Link security group
Value: !Ref VpcLinkSecurityGroup
Export:
Name: VpcLinkSG

I am not going into details as most of these CloudFormation code snippets are self-explanatory. The description section has a brief on what each part does.

There are two ways to gain access to the EC2 instances in a private subnet. One of them is using the bastion host and the other is to use Systems Manager (SSM) provided by AWS. I prefer to use SSM and you can read more on this at "Toward a bastion less world". The reason I mentioned this is, in the upcoming section where I share the code to configure the IAM roles, you'll see me using policies that are related to SSM and I don't want you to be confused.

####################################################################
# All IAM Configurations of ABC (Roles, Profiles, Policies) #
####################################################################
---
Resources:
Ec2Instanceprofile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref Ec2Role
Ec2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
Path: /
Ec2RolePolicies:
Type: AWS::IAM::Policy
Properties:
PolicyName: ec2policies
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: 's3:*'
Resource: '*'
- Effect: Allow
Action:
- 'ssm:DescribeAssociation'
- 'ssm:GetDeployablePatchSnapshotForInstance'
- 'ssm:GetDocument'
- 'ssm:DescribeDocument'
- 'ssm:GetManifest'
- 'ssm:GetParameter'
- 'ssm:GetParameters'
- 'ssm:ListAssociations'
- 'ssm:ListInstanceAssociations'
- 'ssm:PutInventory'
- 'ssm:PutComplianceItems'
- 'ssm:PutConfigurePackageResult'
- 'ssm:UpdateAssociationStatus'
- 'ssm:UpdateInstanceAssociationStatus'
- 'ssm:UpdateInstanceInformation'
Resource: '*'
- Effect: Allow
Action:
- 'ssmmessages:CreateControlChannel'
- 'ssmmessages:CreateDataChannel'
- 'ssmmessages:OpenControlChannel'
- 'ssmmessages:OpenDataChannel'
Resource: '*'
- Effect: Allow
Action:
- 'ec2messages:AcknowledgeMessage'
- 'ec2messages:DeleteMessage'
- 'ec2messages:FailMessage'
- 'ec2messages:GetEndpoint'
- 'ec2messages:GetMessages'
- 'ec2messages:SendReply'
Resource: '*'
Roles:
- !Ref Ec2Role
#Output resources
Outputs:
RoleOutput:
Description: Output of S3 full access Role and SSM using Instance Profile
Value: !Ref Ec2Instanceprofile
Export:
Name: Ec2InstanceProfile
view raw iam_roles.yaml hosted with ❤ by GitHub

Now we have the VPC, subnets, the required security groups, and IAM roles configured using CloudFormation to host our applications. In the next article, I'll be adding some compute resources to each of these subnets so you can host your application. Also, in an article to follow, I'll share how to run these templates and get the infrastructure setup in AWS along with the complete code hosted in Github. Thanks for reading.

AWS Q Developer image

Your AI Code Assistant

Implement features, document your code, or refactor your projects.
Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Create a simple OTP system with AWS Serverless cover image

Create a simple OTP system with AWS Serverless

Implement a One Time Password (OTP) system with AWS Serverless services including Lambda, API Gateway, DynamoDB, Simple Email Service (SES), and Amplify Web Hosting using VueJS for the frontend.

Read full post