Simplifying AWS Auto Scaling Groups Setup with Shell Scripting
Introduction
Auto Scaling Groups (ASGs) are a fundamental component of AWS infrastructure for ensuring high availability and efficient resource utilization. ASGs automatically adjust the number of instances in response to changing demand, providing scalability and fault tolerance. In this blog post, we will explore how to set up an Auto Scaling Group on AWS using shell scripting and the AWS Command Line Interface (CLI). We will walk through a shell script that automates the creation of a custom VPC, subnets, security groups, an internet gateway, route tables, target groups, load balancer, launch template, and the auto scaling group. By the end of this blog post, you will have a clear understanding of ASGs and how to utilize shell scripting to simplify their setup.
Understanding Auto Scaling Groups
An Auto Scaling Group is a logical grouping of Amazon EC2 instances that share similar characteristics and are managed as a unit. ASGs dynamically scale the number of instances based on predefined scaling policies and conditions. This enables applications to handle varying workloads efficiently, ensuring optimal resource utilization and cost savings. ASGs can be associated with load balancers, allowing them to distribute traffic evenly among instances.
Adding Scaling Policies
The script uses the aws autoscaling put-scaling-policy command to add a scaling policy to the Auto Scaling Group. The policy type is set to TargetTrackingScaling, which allows you to define a target value for a specific metric. In this example, the policy targets CPU utilization and adjusts the number of instances to maintain a target CPU utilization of 60%. The scaling policy is defined in a JSON file, config.json, which is referenced in the command.
Understanding the Script
VPC and Subnet Creation:
The script begins by creating a custom VPC using the
aws ec2 create-vpccommand.It then creates two custom subnets using the
aws ec2 create-subnetcommand.The availability zones for the subnets are specified as
us-east-1aandus-east-1f.The script prompts the user to enter the VPC ID and subnet IDs for further configuration.
Making Subnets Public:
The script proceeds to make the subnets public by creating an internet gateway and associating it with the VPC.
It creates a route table and adds a default route to the internet gateway using the
aws ec2 create-internet-gateway,aws ec2 attach-internet-gateway,aws ec2 create-route-table, andaws ec2 create-routecommands.The script also associates the route table with the subnets and enables the automatic mapping of public IP addresses when instances are launched.
Creating Security Group:
The script creates a custom security group using the
aws ec2 create-security-groupcommand.Inbound rules for TCP (port 22 for SSH), ICMP, and HTTP (port 80) protocols are added using the
aws ec2 authorize-security-group-ingresscommand.
Creating Target Groups for the Load Balancer:
The script creates three target groups (
general,image, andvideo) using theaws elbv2 create-target-groupcommand.Each target group is configured with HTTP protocol, port 80, and health check settings.
Creating Load Balancer and Listener:
The script creates a load balancer using the
aws elbv2 create-load-balancercommand and prompts the user to enter the load balancer ARN.It then creates a listener for port 80 using the
aws elbv2 create-listenercommand and associates it with the default target group (general).
Adding Routing Rules:
The script adds routing rules to the listener using the
aws elbv2 create-rulecommand.Two rules are created: one for paths starting with '/images/' and another for paths starting with '/videos/'.
The rules forward the traffic to the corresponding target groups (
imageandvideo).
Creating Launch Template:
The script creates a launch template using the
aws ec2 create-launch-templatecommand.The launch template specifies the configuration for the instances that will be launched by the ASG.
The script prompts the user to enter the launch template ID for further configuration.
Creating Auto Scaling Group:
The script creates an auto scaling group using the
aws autoscaling create-auto-scaling-groupcommand.It specifies the desired capacity, minimum and maximum sizes of the group, the launch template, and the target groups to associate with.
The
--vpc-zone-identifierflag is used to specify the subnets in which the instances should be launched.
Adding a Scaling Policy:
The script adds a scaling policy to the auto scaling group using the
aws autoscaling put-scaling-policycommand.The policy is defined as a target-tracking scaling policy, which adjusts the desired capacity of the ASG to maintain a specific target value for a predefined metric.
The policy configuration is specified in a JSON file (
config.json) passed using thefile://syntax.
Shell script
#!/bin/sh
echo "We are first going to create aur custom VPC------------";
#VPC Creation
echo "The VPC ID of newly created VPC is:";
aws ec2 create-vpc --cidr-block 172.35.0.0/16 --query Vpc.VpcId --output text
#Subnet Creation
echo "Now we are going to create our own 2 custom Subnets---------------";
echo "Enter The VPC ID from above";
read vpcId;
echo "Enter 1ST CIDR block ";
read cidr;
echo "The Subnet ID of 1st newly created Subnet:";
aws ec2 create-subnet --vpc-id $vpcId --cidr-block $cidr --availability-zone us-east-1a --output text
echo "Enter Subnet ID from above";
read subId;
echo "Enter 2nd CIDR Block";
read cidr2;
echo "The Subnet ID of 2nd newly created Subnet:";
aws ec2 create-subnet --vpc-id $vpcId --cidr-block $cidr2 --availability-zone us-east-1f --output text
echo "Enter Subnet ID from above";
read subId1;
#Making 1st VPC and Subnet public using Internet Gateway and Route Table
echo "Making the VPC and Subnet public----------";
echo "Internet Gateway ID of newly created internet gateway";
aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text
echo "Enter Internet Gateway ID";
read igId;
#Attach the internet gateway to VPC
aws ec2 attach-internet-gateway --vpc-id $vpcId --internet-gateway-id $igId
#Creating Route Table
echo "Route Table ID of newly created Route Table:";
aws ec2 create-route-table --vpc-id $vpcId --query RouteTable.RouteTableId --output text
echo "Enter Route Table ID from above:";
read rId;
#Route all traffic to the internet gateway
aws ec2 create-route --route-table-id $rId --destination-cidr-block 0.0.0.0/0 --gateway-id $igId
#Associate route with the created subnet
aws ec2 associate-route-table --subnet-id $subId --route-table-id $rId
#Map public IP when instance is launched automatically
aws ec2 modify-subnet-attribute --subnet-id $subId --map-public-ip-on-launch
#Making 2nd VPC and Subnet public using Internet Gateway and Route Table
echo "Making the VPC and Subnet public----------";
#Route all traffic to the internet gateway
aws ec2 create-route --route-table-id $rId --destination-cidr-block 0.0.0.0/0 --gateway-id $igId
#Associate route with the created subnet
aws ec2 associate-route-table --subnet-id $subId1 --route-table-id $rId
#Map public IP when instance is launched automatically
aws ec2 modify-subnet-attribute --subnet-id $subId1 --map-public-ip-on-launch
# Creating custom Security Group
echo "Creating Security Group----------";
echo "Security group ID of newly created Security Group";
aws ec2 create-security-group --group-name "my-secs-grps" --description "my custom security group" --vpc-id $vpcId
echo "Enter Security group ID:";
read sgId;
echo "Adding TCP,SSH,HTTP Protocol as inbound rule--------------";
#Add Rule to security group
aws ec2 authorize-security-group-ingress --group-id $sgId --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id $sgId --protocol icmp --port -1 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id $sgId --protocol tcp --port 80 --cidr 0.0.0.0/0
#Creating a Target Groups for the Load Balancer
echo "Creating General target group ----------------------------";
echo "ARN for General TG";
aws elbv2 create-target-group \
--name general \
--protocol HTTP \
--port 80 \
--target-type instance \
--vpc-id $vpcId \
--health-check-interval-seconds 5 \
--health-check-timeout-seconds 2 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 2
echo "Creating Image target group ----------------------------";
echo "ARN for Image TG";
aws elbv2 create-target-group \
--name image \
--protocol HTTP \
--port 80 \
--target-type instance \
--vpc-id $vpcId \
--health-check-interval-seconds 5 \
--health-check-timeout-seconds 2 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 2
echo "Creating Video target group ----------------------------";
echo "ARN for Video TG";
aws elbv2 create-target-group \
--name video \
--protocol HTTP \
--port 80 \
--target-type instance \
--vpc-id $vpcId \
--health-check-interval-seconds 5 \
--health-check-timeout-seconds 2 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 2
echo "Enter the ARN of the default Target Group"
read genarn
echo "Enter ARN of Image Target Group"
read imgarn
echo "Enter ARN of Video Target Group"
read vidarn
#Creating Load Balancer
echo "Creating Load Balancer--------";
echo "ARN of Load Balancer--------";
aws elbv2 create-load-balancer --name bruh \
--subnets $subId $subId1 --security-groups $sgId
echo "Enter ARN number of Load Balancer";
read lbarn;
#Adding listener for Target Group
echo "Adding listener to port 80 by HTTP for General TG------------";
echo "Port 80 Listener ARN:";
aws elbv2 create-listener \
--load-balancer-arn $lbarn \
--protocol HTTP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=$genarn
#Adding Routing Rules
echo "Adding Rules for Port 80 Listener";
echo "Enter Port 80 Listener ARN:";
read p80arn;
aws elbv2 create-rule --listener-arn $p80arn --priority 3 \
--conditions Field=path-pattern,Values='/images/*' \
--actions Type=forward,TargetGroupArn=$imgarn
aws elbv2 create-rule --listener-arn $p80arn --priority 2 \
--conditions Field=path-pattern,Values='/videos/*' \
--actions Type=forward,TargetGroupArn=$vidarn \
#Creating LAunch Template
echo "Launch Template ID of new created Launch Template-----"
aws ec2 create-launch-template \
--launch-template-name ALBLaunchTemplate \
--version-description WebVersion1 \
--launch-template-data '{"NetworkInterfaces":[{"AssociatePublicIpAddress":true,"DeviceIndex":0,"SubnetId":"subnet-91b79bf7","Groups":["sg-0fb1fe868a48ee7ab"],"DeleteOnTermination":true}],"ImageId":"ami-0ed9277fb7eb570c9","InstanceType":"t2.micro"}'
echo "Enter Launch Template ID"
read ltId
#Creating Auto Scaling Group
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name ALBAutoScaling \
--launch-template LaunchTemplateId=$ltId \
--target-group-arns $imgarn \
--target-group-arns $vidarn \
--target-group-arns $genarn \
--health-check-type ELB \
--health-check-grace-period 600 \
--max-size 3 \
--min-size 1 \
--desired-capacity 2 \
--vpc-zone-identifier "subnet-962251a7,subnet-91b79bf7,subnet-6545b929"
#Add Scaling Policy to the Auto Scaling Group
aws autoscaling put-scaling-policy \
--policy-name cpu60-target-tracking-scaling-policy \
--auto-scaling-group-name ALBAutoScaling \
--policy-type TargetTrackingScaling \
--target-tracking-configuration file://config.json
Conclusion
Automating the creation of Auto Scaling Groups using shell scripting and the AWS CLI can greatly simplify the management of scalable applications. In this blog post, we explored a script that automates the creation of an ASG on AWS. By leveraging this script, you can easily set up and manage your application's scalability with minimal manual intervention.

