How to Build a Highly Available, Secure, and Fault-Tolerant Application on AWS
By: Andrew Bestbier
Tags: Software Development, Cloud Computing, Scalability, Programming, AWS

EC2 Instances

Now for a more fun part — adding EC2 instances to our public subnets. We will do this part in a few steps as there will be a few moving parts:

Spinning up an EC2 instance with CloudFormation. Adding a security group to that EC2 instance so that we can access it. Taking down our EC2 instance and using launch configurations and autoscaling groups instead. Placing our instances in our VPC.

Adding an EC2 instance

We can spin up our first EC2 instance by adding the following code to our tutorial.yaml file:

Let’s break down what’s happening:

Naming our resource FirstInstance . Specifying the resource type to be an instance. Specifying the instance image as an Amazon Linux 2 instance in the London region (see the AWS docs for the ID you should pick for your region). Setting the instance size as a t2.micro . Adding some UserData that specifies the commands that will be run on our instance when it is first launched. In this case, the httpd library is installed and started so that our server can serve a simple website. We then echo some text into an HTML file.

If you deploy your template to CloudFormation and navigate to the AWS EC2 service, you should see your running instance:

Next, click on the Public IP (pink arrow above) to view the website served by our instance ( 3.9.118.10 , in my case). You should see the following error:

Huh? Why?

Well, it turns out that your instance has a security group assigned to it which acts as a firewall around it. By default, this security group will not let traffic into your instance:

So, to get around this, we can create a security group in CloudFormation that does allow HTTP traffic in and then assigns this to our instance (AWS docs).

Adding a security group

Add the following to your template and note the change to your instance:

Let’s break down what’s happening:

Modifying our instance to reference a security group resource. Naming our new security group InstanceSecurityGroup . Specifying the resource type to be a security group. Allowing traffic in on port 80 (for HTTP traffic). Specifying that the incoming requests can come from any source as the CIDR is 0.0.0.0/0 . Note that this is actually quite dangerous and we will lock this down later.

Next, deploy your template to CloudFormation which will terminate your old instance and launch a new one with a new security group. Click on the new IP address and you should see our website:

Using launch configurations and auto-scaling groups

One of the most powerful aspects of AWS is the ability to auto-scale horizontally.

Instead of launching a single instance like we just did, we can launch multiple instances automatically depending on the incoming traffic load. To do this, we will use launch configuration and an auto-scaling group.

An auto-scaling group (or ASG), as the name implies, is a group of resources that scales in and out.

A launch configuration is a resource that describes how an instance should be launched (but does not launch an instance itself). An auto-scaling group takes a launch configuration and spins up instances using it as a template.

In your tutorial.yaml specification, delete your instance resource, keep the security group, and add the following:

Let’s break down what’s happening:

Naming our resource AppLaunchConfig . Specifying the resource type to be an application launch configuration. The rest is exactly the same as for our (now deleted) EC2 instance. Naming our resource AutoScalingGroup . Specifying the resource type to be an auto-scaling group. Specifying the launch configuration the auto-scaling group will use. Setting the availability zones our instances will be launched into. Setting the desired capacity to 3 so that three instances will be launched.

Deploy your template to CloudFormation, navigate to AWS EC2 and you should see your three instances:

Place our auto-scaling group in our VPC

Now, you have probably noticed that we haven’t referred to the VPC/subnets we created for a while.

If you look carefully at your instances, you’ll notice that they were launched into our account’s default VPC and it is time we corrected this. Modify your specification to the following:

Notice how we specify the auto-scaling group subnets rather than the availability zone as before. Deploy this to CloudFormation and you should see your instances launched into your VPC:

However if you now click on the IP address of your instance, you will see the following error:

This is not due to our security groups not being configured properly but rather due to our subnets not having access to the internet. We will fix this in the next section but, for now, our architecture looks something like this: