Setting up CloudFormation

While working with CloudFormation, you define the AWS resources you need and then wire them together as per your architecture's requirements: 

{
"AWSTemplateFormatVersion" : "",
"Description" : "",
"Parameters" : {
},
"Mappings" : {
},
"Conditions" : {
},
"Resources" : {
},
"Outputs" : {
}
}

The template JSON file includes the following sections; only the Resources section is mandatory while the rest are all optional:

  • AWSTemplateFormatVersion: Defines the capabilities of the template. Only one version has been defined so far.
  • Description: Free text; use it to include comments for your template. It should always follow AWSTemplateFormatVersion. The max size of this free text is 1,024 characters.
  • Parameters: It is used to pass values to the template while creating the stack, and helps customize the template each time you create a stack.
  • Mappings: As the name suggests, it is map of key-values pairs. For example, this can be used to select the correct AMI base image for a region where the stack is being created; the key will be the region and the value will be the AMI ID of the base image.
  • Conditions: Since JSON cannot have any logic embedded in it, a section was created to implement the basic conditional logic evaluation within the JSON template. The conditional logic functions available are AND, OR, EQUALS, IF and NOT.
  • Resources: This is the section in which you define your AWS resources and wire them together. This section is mandatory.
  • Outputs: In this section, you declare the values to be returned upon creation of each AWS resource. This is useful, for example, to find the ELB URL or a RDS endpoint.

Since a full CloudFormation template for our production deployment architecture can run into hundreds of lines of JSON code, we will only present the creation of key AWS resources; however, the complete script, a1ecommerceaws.json, is available for download in the source code repository.  

  • VPC: Here, a different CIDR block is used for production instead of the default 172.31.0.0/16. You can skip this if you want to keep the default CIDR block, but remember to change the reference to the VPC in the subnets:
"VPC":{
"Type":"AWS::EC2::VPC",
"Properties":{"CidrBlock":"10.44.0.0/16",
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"InstanceTenancy" :{"Ref":"EC2Tenancy"},
"Tags":[{"Key":"Application",
"Value":{"Ref":"AWS::StackName" }
},
{"Key":"Network","Value":"Public" },
{"Key":"Name","A1Ecommerce Production"}
]
0 }
},
  • Subnets: As an example only one sample is presented here for the public subnet. Remember to replace CidrBlock with 172.31.16.0/24 and VPC ID with the default VPC identifier, for example vpc-e4ef7882. The DependsOn is not required if you wish to create the subnets in the default VPC. Similarly, create the other subnets:
"PublicSubnet":{
"DependsOn":["VPC"],
"Type":"AWS::EC2::Subnet",
"Properties":{
"VpcId":{"Ref":"VPC"},
"CidrBlock":"10.44.0.0/24",
"AvailabilityZone":"us-west-2a",
"Tags":[
{"Key":"Application",
"Value":{"Ref":"AWS::StackName"}
},
{"Key":"Network","Value":"Public"},
{"Key":"Name","Value":"Public Subnet"}
]
}
}
  • Security Group: As an example, the ELB security group is specified here. Similarly, create the other security groups:
"ELBSecurityGroup":{
"DependsOn":["VPC"],
"Type":"AWS::EC2::SecurityGroup",
"Properties":{
"GroupDescription":"ELB Base Security Group",
"VpcId":{"Ref":"VPC"},
"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":"ELB Security Group"}
]
}
},
"ELBSecurityGroupEgress80":{
"DependsOn":["ELBSecurityGroup"],
"Type":"AWS::EC2::SecurityGroupEgress",
"Properties":{
"GroupId":{"Ref":"ELBSecurityGroup"},
"IpProtocol":"tcp","FromPort":"8080",
"ToPort":"8080",
"DestinationSecurityGroupId":{
"Fn::GetAtt": [ "WebSecurityGroupPublic","GroupId" ]
}
}
},
"ELBSecurityGroupEgress443":{
"DependsOn":["ELBSecurityGroup"],
"Type":"AWS::EC2::SecurityGroupEgress",
"Properties":{"GroupId":{"Ref":"ELBSecurityGroup"},
"IpProtocol":"tcp","FromPort":"8443",
"ToPort":"8443",
"DestinationSecurityGroupId":{
"Fn::GetAtt": [ "WebSecurityGroupPublic","GroupId" ]
}
}
}
  • RDS: An RDS subnet needs to be created so that the RDS service can run in the correct availability zones, us-west-2a and us-west-2c:
"RDSSubnetGroup":{
"Type" : "AWS::RDS::DBSubnetGroup",
"Properties":{
"DBSubnetGroupDescription":"Availability Zones for CanvasDB ",
"SubnetIds" : [ { "Ref" : "PrivateSubnet" },
{ "Ref" : "DbPrivateSubnet" }
]
"A1EcommerceMasterDB" : {
"Type" : "AWS::RDS::DBInstance",
"Properties" : {
"DBName" :"a1ecommerce",
"DBInstanceIdentifier" : "a1ecommerce",
"AllocatedStorage" : "5",
"DBInstanceClass" : "db.t1.micro",
"BackupRetentionPeriod" : "7",
"Engine" : "MySQL",
"MasterUsername" : "a1dbroot",
"MasterUserPassword" : "a1dbroot",
"MultiAZ" : "rue",
"Tags" : [{ "Key" : "Name", "Value" : "A1Ecommerce Master Database" }],
"DBSubnetGroupName":{"Ref":"RDSSubnetGroup"},
"VPCSecurityGroups": [ { "Fn::GetAtt": [ "PrivateSecurityGroup", "GroupId" ] } ],
},
"DeletionPolicy" : "Snapshot"
}
  • ELB: The ELB is straightforward. It routes the incoming traffic to the two subnets in the two availability zones and is assigned the ELB security group:
"ElasticLoadBalancer":{
"Type":"AWS::ElasticLoadBalancing::LoadBalancer",
"DependsOn":["PublicSubnet","HASubnet"
],
"Properties":{
"Subnets":[{"Ref":"PublicSubnet"},
{"Ref":"HASubnet"}
],
"CrossZone":"true",
"Listeners":[{
"LoadBalancerPort":"8080",
"InstancePort":"8080",
"Protocol":"HTTP"
},
{
"LoadBalancerPort":"8443",
"InstancePort":"8443",
"Protocol":"TCP"
}
],
"ConnectionDrainingPolicy":{
"Enabled":"true","Timeout":"60"
},
"SecurityGroups":[{
"Ref":"ELBSecurityGroup"
}
],
"HealthCheck":{
"Target":"HTTP:8080/index.html",
"HealthyThreshold":"3",
"UnhealthyThreshold":"5",
"Interval":"30",
"Timeout":"5"
}
}
}
  • Launch Configuration: The ImageId is your base AMI instance that the Auto Scaling group will launch. Replace the image ID with your own AMI:
"LaunchConfig":{
"Type":"AWS::AutoScaling::LaunchConfiguration",
"Properties":{
"KeyName":{
"Ref":"KeyPairName"
},
"ImageId":"i-3a58b4cd"
"SecurityGroups" : [ { "Ref" : "WebSecurityGroupPublic" } ],
"InstanceType":{
"Ref":"EC2InstanceASG"
},
}
}
  • Scaling Configuration: There are two scaling configurations, one to scale up and the other to scale down. Auto scaling will add/remove new EC2 instances as defined in the ScalingAdjustment field whenever the alarm goes off. Due to lack of space, only WebServerScaleUpPolicy is presented:
"WebServerScaleUpPolicy":{
"Type":"AWS::AutoScaling::ScalingPolicy",
"Properties":{
"AdjustmentType":"ChangeInCapacity",
"AutoScalingGroupName":{
"Ref":"WebServerGroup"
},
"Cooldown":"60",
"ScalingAdjustment":"1"
}
},
"WebServerScaleDownPolicy":{
.
.
}
  • Scaling Alarms: Next are the alarms that are the qualifiers for the Auto Scaling group to add or remove EC2 instances. In this example, a new EC2 instance is added whenever the average CPU load is > 90% for a period of 5 minutes, and an EC2 instance is removed whenever the average CPU load is < 70% for a period of 5 minutes. Due to lack of space, only CPUAlarmHigh is presented here:
"CPUAlarmHigh":{
"Type":"AWS::CloudWatch::Alarm",
"Properties":{
"AlarmDescription":"Scale-up if CPU > 90% for 5 minutes",
"MetricName":"CPUUtilization",
"Namespace":"AWS/EC2",
"Statistic":"Average",
"Period":"300",
"EvaluationPeriods":"2",
"Threshold":"90",
"AlarmActions":[
{"Ref":"WebServerScaleUpPolicy"}
],
"Dimensions":[{
"Name":"AutoScalingGroupName",
"Value":{"Ref":"WebServerGroup" }
}
],
"ComparisonOperator":"GreaterThanThreshold"
}
},
"CPUAlarmLow":{
.
.
},
  • Auto Scaling Group: Finally, the Auto Scaling group itself is configured to send messages to the SNS topic upon the launch and termination of EC2 instances:
"WebServerGroup":{
"Type":"AWS::AutoScaling::AutoScalingGroup",
"DependsOn":[
"LaunchConfig","ElasticLoadBalancer"
],
"Properties":{
"AvailabilityZones" : [
{"Fn::GetAtt" : [ "HASubnet" , "AvailabilityZone"] },
{"Fn::GetAtt" : [ "PublicSubnet" , "AvailabilityZone"] }
],
"LaunchConfigurationName":{
"Ref":"LaunchConfig"
},
"MinSize":"1",
"MaxSize":"1",
"LoadBalancerNames":[
{"Ref":"ElasticLoadBalancer"}
],
"VPCZoneIdentifier":[
{ "Ref" : "HASubnet" },
{ "Ref" : "PublicSubnet" }
],
"NotificationConfiguration":{
"TopicARN":{"Ref":"A1SNSInfraAlert"
},
"NotificationTypes":[
"autoscaling:EC2_INSTANCE_LAUNCH",
"autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
"autoscaling:EC2_INSTANCE_TERMINATE",
"autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
]
}
}
},
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.214.194