This yaml template is created for DevOps - Infrastructure Automation on AWS Project. By using this template we will deploy below resources
Based on our previous learnings from last 6 cloudformation series blogs we are going to create a real time basic web application teir to have some handons and understand how its implementation works in realtime.
If you are a beginner and want to start your journey towards infra-as-code developer as part of your devops role buckle up 🚴♂️ and lets get started and understand core cloudformation concepts by implementing it...🎬
❗️❗️❗️ Pre-Requisite ❗️❗️❗️
1️⃣ Add visual studio code extension [Mandatory]
2️⃣ Adding VS Code Indentation Extension For Cloudformation Templates [Optional]
3️⃣ Deploy VPC, IGW & Associate [Mandatory]
4️⃣ Deploy only public subnet template from below blog [Mandatory].Make sure to create 2 public subnets
Parameters:
CustomVPC:
Description: Select One VPC available in your existing account
Type: AWS::EC2::VPC::Id
Default: <"Your VPC ID">
CustomInternetGateway:
Description: Select One internet gateway available in your existing account
Type: String
Default: <"Your Internet Gateway ID">
Resources:
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "us-east-1a"
MapPublicIpOnLaunch: true
VpcId: !Ref CustomVPC
CidrBlock: 10.0.0.0/25
Tags:
- Key: Name
Value: PublicSubnet1
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "us-east-1b"
MapPublicIpOnLaunch: true
VpcId: !Ref CustomVPC
CidrBlock: 10.0.0.128/25
Tags:
- Key: Name
Value: PublicSubnet2
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref CustomVPC
Tags:
- Key: Name
Value: PublicRouteTable
PublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref CustomInternetGateway
PublicSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
PublicSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
Outputs:
outputPublicSubnets1:
Description: A reference to the created Public subnet
Value: !Ref PublicSubnet1
Export:
Name: PublicSubnet1
outputPublicSubnets2:
Description: A reference to the created Public subnet
Value: !Ref PublicSubnet2
Export:
Name: PublicSubnet2
🔊 To view double subnet github code click here
5️⃣ EC2 instance with Security group [Reference]
🎨 Diagrammatic Representation 🎨
Template Components Planning Before Build
🔳 Parameters
✦ CustomVPC :- Using this parameter for VPC "AWS::EC2::VPC::Id" we can list existing VPC list into the account and select anyone from them. Apart from this list we can also you default value if no value is selected in the parameter.
✦ PublicSubnet: Using this parameter for Subnet "List" we can list existing subnet list from the account and select anyone from them. Apart from this list we can also you default value if no value is selected in the parameter.
Parameters:
CustomVPC:
Description: Select One VPC available in your existing account
Type: AWS::EC2::VPC::Id
Default: "<your default VPC ID>"
PublicSubnet1:
Description: Select one public subnet available in your existing account
Type: AWS::EC2::Subnet::Id
Default: "<your default public subnet id>"
PublicSubnet2:
Description: Select one public subnet available in your existing account
Type: AWS::EC2::Subnet::Id
Default: "<your default public subnet id>"
🔳 Resources
✦ InstanceSecurityGroup:- Over here you can see we are opening two ports 22 for SSH and 80 for http for our Ubuntu web server which we have created.
➖ GroupName:- This property is used to mention security group name.
➖ GroupDescription:- This property is used to mention security group description and its mandatory property for this resource.
➖ SecurityGroupIngress:- This property is used to add ingress rules for [udp/tcp] ports enabled secured access to your resources.
➖ Tags:- One of the most important property used in all resources. Always make sure to attach tags for all your resources.
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref CustomVPC
GroupName: "AllowEc2Traffic"
GroupDescription: "Enable SSH access and HTTP access on the inbound port for EC2"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: InstanceSecurityGroup
✦ UbuntuInstances :- As part of this resource we use type "AWS::EC2::Instance".
➖ ImageId:- This property is used to mention EC2 image ID based on which you want to launch your EC2 Instance.
➖ KeyName:- This property is used to mention keynameby using which you can connect to your EC2 instance.
➖ InstanceType:- This property is used to mention which type of instance you want to launch smal/medium/large based on your requirement.
➖ SecurityGroupIds:- This property is used to add list of security group you want to attach to your EC2 instance for enabling access control based on your security requirements.
➖ Tags:- One of the most important property used in all resources. Always make sure to attach tags for all your resources.
➖ User Data: User data is user data/commands that you can specify at the time of launching your instance. These data/command executes after your EC2 instance starts.
You don’t need to SSH into your EC2 instance and run those command one by one. Rather all you need is to specify the whole script in the user data section and they get executed once your instance boots up. You can use AWS CloudFormation to automatically install, configure, and start applications on Amazon EC2 instances. Doing so enables you to easily replicate deployments and update existing installations without connecting directly to the instance, which can save you a lot of time and effort.
UbuntuInstance1:
Type: AWS::EC2::Instance
Properties:
KeyName: CustomVPC
ImageId: ami-04505e74c0741db8d
SubnetId: !Ref PublicSubnet1
InstanceType: t2.micro
SecurityGroupIds:
- !Ref InstanceSecurityGroup
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
sudo su
sudo apt-get update -y
sudo apt-get install -y apache2
sudo ufw allow -y 'Apache'
sudo systemctl start apache2
sudo systemctl enable apache2
Tags:
- Key: Name
Value: UbuntuInstance1
UbuntuInstance2:
Type: AWS::EC2::Instance
Properties:
KeyName: CustomVPC
ImageId: ami-04505e74c0741db8d
InstanceType: t2.micro
SubnetId: !Ref PublicSubnet2
SecurityGroupIds:
- !Ref InstanceSecurityGroup
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
sudo su
sudo apt-get update -y
sudo apt-get install -y apache2
sudo ufw allow -y 'Apache'
sudo systemctl start apache2
sudo systemctl enable apache2
Tags:
- Key: Name
Value: UbuntuInstance2
✦ ELBTargetGroup:- Real work of target group is to inform a loadbalancer to whom he should route traffic like EC2/Fixed IP Address/lambda.Over here you can see in targets property it is referring to our web server created above.
➖ HealthCheckIntervalSeconds: The approximate amount of time, in seconds, between health checks of an individual target.
➖ HealthCheckTimeoutSeconds: The amount of time, in seconds, during which no response from a target means a failed health check.
➖ HealthyThresholdCount: The number of consecutive health checks successes required before considering an unhealthy target healthy.
➖ UnhealthyThresholdCount: The number of consecutive health check failures required before considering a target unhealthy.
➖ VpcId: Id of your existing VPC.
➖ TargetType: The type of target that you must specify when registering targets with this target group. You can specific alb/instance/ip/lambda.
➖ Targets: As part of this property we are mentioning the instance id's to be added as targets.
ELBTargetGroup1:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId: !Ref CustomVPC
TargetType: instance
Targets:
- Id: !Ref UbuntuInstance1
Port: 80
ELBTargetGroup2:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId: !Ref CustomVPC
TargetType: instance
Targets:
- Id: !Ref UbuntuInstance2
Port: 80
✦ ELBSecurityGroup:- Creating Security group and enabling ingress with http and ssh port.
➖ GroupName:- This property is used to mention security group name.
➖ GroupDescription:- This property is used to mention security group description and its mandatory property for this resource.
➖ SecurityGroupIngress:- This property is used to add ingress rules for [udp/tcp] ports enabled secured access to your resources.
➖ Tags:- One of the most important property used in all resources. Always make sure to attach tags for all your resources.
ELBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: "ELBTraffic"
GroupDescription: "Enable HTTP access on the inbound port for ELB"
VpcId: !Ref CustomVPC
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
Tags:
- Key: Name
Value: ELBSecurityGroup
✦ ElasticLoadBalancer:- Elastic Load Balancing (ELB) automatically distributes incoming application traffic across multiple targets and virtual appliances in one or more Availability Zones (AZs).As part of this resource we use type "AWS::ElasticLoadBalancingV2::LoadBalancer".
➖ Subnets: The IDs of the public subnets. You can specify only one subnet per Availability Zone.
➖ SecurityGroups: List IDs of the security groups for the load balancer.
ElasticLoadBalancer:
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
Properties:
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref ELBSecurityGroup
✦ ElbListener:- A listener is a process that checks for connection requests, using the protocol and port that you configure. The rules that you define for a listener determine how the load balancer routes requests to its registered targets. As part of this resource we use type "AWS::ElasticLoadBalancingV2::Listener".
➖ DefaultActions: The actions for the default rule. You cannot define a condition for a default rule.
➖ LoadBalancerArn: Refer Amazon Resource Name (ARN) of the load balancer the we have created in above code block.
ElbListener1:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ELBTargetGroup1
LoadBalancerArn: !Ref ElasticLoadBalancer
Port: '8000'
Protocol: HTTP
ElbListener2:
Type: 'AWS::ElasticLoadBalancingV2::Listener'
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ELBTargetGroup2
LoadBalancerArn: !Ref ElasticLoadBalancer
Port: '9000'
Protocol: HTTP
🔳 Outputs
Its always a best practice to print output for your resources.
✦ outputmyUbuntuInstance: A reference to the created EC2 Instance.
✦ outputInstanceSecurityGroup:- A reference to the created Security Group.
✦ outputELBTargetGroup: A reference to the created Target Group.
✦ outputELBSecurityGroup: A reference to the created Security Group.
✦ outputElasticLoadBalancer: A reference to the created Elastic Load Balancer.
✦ outputElasticListener: A reference to the created Elastic Load Balancer Listener.
Outputs:
outputInstanceSecurityGroup:
Description: A reference to the created security group
Value: !Ref InstanceSecurityGroup
outputUbuntuInstance:
Description: A reference to the created EC2 Instance
Value: !Ref UbuntuInstance1
outputUbuntuInstance:
Description: A reference to the created EC2 Instance
Value: !Ref UbuntuInstance2
outputELBTargetGroup:
Description: A reference to the created Target Group
Value: !Ref ELBTargetGroup1
outputELBTargetGroup:
Description: A reference to the created Target Group
Value: !Ref ELBTargetGroup2
outputELBSecurityGroup:
Description: A reference to the created Security Group
Value: !Ref ELBSecurityGroup
outputElasticLoadBalancer:
Description: A reference to the created Elastic Load Balancer
Value: !Ref ElasticLoadBalancer
outputElasticListener:
Description: A reference to the created Elastic Load Balancer Listener
Value: !Ref ElbListener1
outputElasticListener:
Description: A reference to the created Elastic Load Balancer Listener
Value: !Ref ElbListener2
🔊 To view entire github code click here
1️⃣ Lets validate our template 👨💻
aws cloudformation validate-template --template-body file://<file path>
2️⃣ After successful template verification lets create stack using our template 👨💻
aws cloudformation create-stack --stack-name webapp --template-body file://<file path>
3️⃣ Check if the stack we created via template is completed successfully 👨💻
aws cloudformation list-stack-resources --stack-name webapp
4️⃣ Describe stack and its resources to view its properties 👨💻
aws cloudformation describe-stacks --stack-name webapp
aws cloudformation describe-stack-resources --stack-name webapp
5️⃣ Check events for stack formation 👨💻
aws cloudformation describe-stack-events --stack-name webapp
❗️❗️Important AWS Documentation To Be Viewed❗️❗️
⛔️ Target Groups
⛔️ LoadBalancer
⛔️ ELB Listener
⛔️ EC2
⛔️ Parameters
⛔️ Outputs
🥁🥁 Conclusion 🥁🥁
In this blog I am going to deploy resources which are very important as part of your web stack deployments in which we will create
✦ 2 Ubuntu EC2 instance with Security group.
✦ 2 Target group and its association with EC2.
✦ Elastic Load Balancer, 2 ELB listener, ELB Security Group and its association with both Target Groups.
I have used AWS CLI command to deploy these template and trust me AWS CLI is the realtime hero and I would suggest you to get acquainted towards it. Going forward I will be releasing further parts to this CloudFormation journey
📢Stay tuned for my next blog.....
🎊So, did you find my content helpful? If you did or like my other content, feel free to buy me a coffee. Thanks. 🎊
💫Cloudformation Series Sequence💫
🔰 Deploy VPC With Internet Gateway & Associate I
🔰 Public, Private Subnet & Route Table Creation & Association II
🔰 Private Subnet,Nat Gateway, Elastic Ip, Private Route Table & Associate III
🔰 NACL, Inbound & Outbound Routes, Security Group & Associate With Subnet IV
🔰 EC2 With Security Group & User Data & Mapping V
🔰 Target Group, Elastic Load Balancer & ELB Listener VI
🔰 Build Web Application Layer With AWS CloudFormation VII
⌛️Realtime Usecases Cloudformation Templates⏳
💨 Schedule Automatic Detection Of Unused AWS EBS Volumes & Notify
💨 Schedule Automatic Detection Of Non Associated AWS Elastic IP's In AWS Account On Weekly Basis And Notify
💨 Schedule Automatic Deregistration Of AWS AMI On Weekly Basis And Notify