Easy Guide to Setting Up Scalable Apps with AWS Management Console, CLI, and Terraform

In this tutorial we will launch a simple website hosted on EC2 instance which will scale up and down based on the CPU utilisation and traffic will be balanced among the instances group hosting the website.

Make sure to follow to the end where few points to enhance security and optimise costs can be found.

Using Management Console:

To test autoscaling:

  • Login to the instance and install Stress utility using command:

  •         sudo yum install stress-ng
            sudo stress-ng -c 80
    

    In few minute you would see another instance is launched, keep on refreshing the browser window and you will notice the load is being distributed between the two instances.

  • Finally to clean up:

    • Delete the Autoscaling Group

    • Delete the Load Balancer

    • Make sure the instances are terminated

    • Optionally you can delete the Launch Template and Target Groups


Using AWS CLI:

As a pre-requisite, AWS CLI must be installed and configured in your local machine, check This Link for details.

1- Create a Launch Template

aws ec2 create-launch-template --launch-template-name MyLT --launch-template-data '{"ImageId":"IMAGE_ID", "UserData":"BASE64_ENCODED_USER_DATA","SecurityGroupIds":["SECURITY_GROUP_ID"],"InstanceType":"t2.micro"}'

IMAGE_ID : The image ID for the AMI

SECURITY_GROUP_ID : ID of the security group which allows HTTP on Port 80

BASE64_ENCODED_USER_DATA: search online for “Base64 Encoder” and use it to encode below user data to Base64 code:

#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello World from $(hostname -f)</h1>" > /var/www/html/index.html

2- Create a Target Group:

aws elbv2 create-target-group --name TARGET_GROUP_NAME --protocol HTTP --port 80 --vpc-id <vpc_id> --ip-address-type ipv4

TARGET_GROUP_NAME : the name of the new target group

Note down the ARN of the target group as it will be needed in following commands

3- Create Autoscaling Group

aws autoscaling create-auto-scaling-group --auto-scaling-group-name MyASG --launch-template "LaunchTemplateName=MyLT" --target-group-arns TARGET_GROUP_ARN --min-size 1 --max-size 2 --desired-capacity 1 --availability-zones "us-east-1a" "us-east-1b" " us-east-1c"

TARGET_GROUP_ARN : The ARN of the Target Group created in previous step 2.

4- Create an Application Load Balancer

aws elbv2 create-load-balancer --name MyALB --subnets SUBNET_ID SUBNET_ID SUBNET_ID --security-groups SECURITY_GROUP_ID

SUBNET_ID : Subnet IDs on the selected AZs

SECURITY_GROUP_ID : ID of the security group which allows HTTP on Port 80

Note down the ARN of the newly created Load Balancer

5- Create a Listener on the ALB to forward HTTP requests to the Target Group:

aws elbv2 create-listener \
    --load-balancer-arn LB_ARN \
    --protocol HTTP \
    --port 80 \
    --default-actions Type=forward,TargetGroupArn=TARGET_GROUP_ARN

LB_ARN : The ARN of the load balancer created in previous step 4

TARGET_GROUP_ARN : The ARN of the Target Group created in previous step 2

Now you can test by the app by using a web browser, the DNS name of the load balancer can be obtained by:

aws elbv2 describe-load-balancers

6- Clean up:

aws autoscaling delete-auto-scaling-group --auto-scaling-group-name MyAsg --force-delete
aws ec2 delete-launch-template --launch-template-name MyLT
aws elbv2 delete-load-balancer --load-balancer-arn LB_ARN
aws elbv2 delete-target-group --target-group-arn TARGET_GROUP_ARN

Run below commands to delete the created resources, ensure updating the LB_ARN and TARGET_GROUP_ARN.

As a final verification, double check on the console that everything is deleted.


Using Terraform:

Files available on GitHub Repo


Points to enhance Security and Optimise Cost:

  • Launch EC2 instances in Private subnets, and ALB in Public subnet. The configure NAT Gateway to enable egress internet access for the instances.

  • Ensure to allow access to the EC2 instance through the ALB only, this can be done by locking the ASG ingress traffic to the ALB security group.

  • Enable TLS/SSL at the ALB to ensure encryption in transit.

  • If the application on the EC2 instance require further access to other resources in AWS, ensure to assign instance profile following least privilege access policies.

  • To optimise cost, select the appropriate instance size in relation to the workload.

  • Configure ASG to scale up and down using Target Tracking policy.

I hope you found this article useful, and make sure to clean up any running resources :)