Although you have defined an EC2 Auto Scaling group resource, you cannot yet deploy your CloudFormation template as the Auto Scaling group references a resource called ApplicationAutoscalingLaunchConfiguration, which is yet to be defined.
An EC2 Auto Scaling launch configuration defines the configuration that is applied to each instance at launch time, and provides a common approach to ensuring each instance in your Auto Scaling group is consistent.
The following example demonstrates configuring an Auto Scaling launch configuration within your CloudFormation template:
...
...
Parameters:
ApplicationDesiredCount:
Type: Number
Description: Desired EC2 instance count
ApplicationImageId:
Type: String
Description: ECS Amazon Machine Image (AMI) ID
ApplicationSubnets:
Type: List<AWS::EC2::Subnet::Id>
Description: Target subnets for EC2 instances
Resources:
ApplicationAutoscalingLaunchConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: !Ref ApplicationImageId
InstanceType: t2.micro
KeyName: admin
IamInstanceProfile: !Ref ApplicationAutoscalingInstanceProfile
SecurityGroups:
- !Ref ApplicationAutoscalingSecurityGroup
UserData:
Fn::Base64:
Fn::Sub: |
#!/bin/bash
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} \
--resource ApplicationAutoscalingLaunchConfiguration \
--region ${AWS::Region}
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} \
--resource ApplicationAutoscaling \
--region ${AWS::Region}
ApplicationCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: todobackend-cluster
ApplicationAutoscaling:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
LaunchConfigurationName: !Ref ApplicationAutoscalingLaunchConfiguration
MinSize: 0
MaxSize: 4
DesiredCapacity: !Ref ApplicationDesiredCount
VPCZoneIdentifier: !Ref ApplicationSubnets
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-ApplicationAutoscaling-instance
PropagateAtLaunch: "true"
Notice that you specify a AWS::AutoScaling::LaunchConfiguration resource type and configure the following properties for your launch configuration:
- ImageId: The AMI of the image that the EC2 instance will be launched from. For our use case, you will use the AMI that you created in the previous chapter. This property references a new parameter called ApplicationImageId, so you need to add this parameter with the AMI ID of your custom machine image to the dev.cfg file.
- InstanceType: The instance family and type of the EC2 instance.
- KeyName: The EC2 key pair that will be permitted SSH access to each EC2 instance.
- IamInstanceProfile: The IAM instance profile to attach to the EC2 instance. As you learned in earlier chapters, in order to support operation as an ECS container instance, the IAM instance profile must grant permissions for the EC2 instance to interact with the ECS service. In the previous example, you reference a resource called ApplicationAutoscalingInstanceProfile, which you will create later in this chapter.
- SecurityGroups: The EC2 security groups to attach to each instance. These define the ingress and egress security rules that are applied to network traffic, and, at a minimum, must permit communications to the ECS service, CloudWatch logs service, and other associated AWS services. Again, you reference a resource called ApplicationAutoscalingSecurityGroup, which you will create later in this chapter.
- UserData: Defines the user data script that is run upon instance creation. This must be supplied as a Base64-encoded string, and you can use the Fn::Base64 intrinsic function to have CloudFormation automatically perform this conversion. You define a bash script that first runs the cfn-init command, which will download and execute CloudFormation Init metadata associated with the ApplicationAutoscalingLaunchConfiguration reference resource, and then runs the cfn-signal command to signal to CloudFormation whether or not cfn-init ran successfully (note that cfn-signal references the AutoscalingGroup resource, rather than the ApplicationAutoscalingLaunchConfiguration resource).
Notice the use of the Fn::Sub function followed by the pipe operator (|), which enables you to enter free-form text that will honour all line breaks and allows you to reference the correct stack name and AWS region using the AWS::StackName and AWS::Region pseudo-parameters.
ApplicationDesiredCount=1
ApplicationImageId=ami-ec957491
ApplicationSubnets=subnet-a5d3ecee,subnet-324e246f