# 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:

<iframe src="https://app.tango.us/app/embed/16f96d43-8707-4729-a284-7dcd70f702b6" style="min-height:640px" sandbox="allow-scripts allow-top-navigation-by-user-activation allow-popups allow-same-origin" width="100%" height="100%"></iframe>

To test autoscaling:

* Login to the instance and install Stress utility using command:
    
* ```plaintext
          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](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) for details.

1- Create a Launch Template

```bash
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:

```bash
#!/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:

```bash
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

```bash
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

```bash
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:

```bash
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:

```bash
aws elbv2 describe-load-balancers
```

6- Clean up:

```bash
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](https://github.com/MoeAhmed11/Cloud-Projects/tree/b4279af957482cd8bd4cfc8e221cd3553b1650f4/Autoscaling)

%[https://gist.github.com/MoeAhmed11/8eece9a9cb055c5f06fc91e45fd21c1e] 

---

### 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 :)
