🚀 Deploying a Sample Web Application on AWS Using CloudFormation and EC2 💻🌐
Published: 2024-03-08 09:41:13

## Introduction
If you're an AWS Cloud Engineer, and you're looking to automate infrastructure deployment on AWS using IAC principles, you've come to the right place. In this guide, I'll walk you through the steps to deploy a sample application stack using AWS CloudFormation and AWS CLI. The goal is to automate the deployment of a multi-tier application stack and configure it to run smoothly on AWS. By following the steps in this guide, you'll be able to demonstrate your knowledge of AWS services and tools and how you can leverage them to streamline the deployment of complex applications on AWS. Let's get started!

## AWS CLI
Developers and system administrators can connect with AWS services and manage resources via the command line using the robust and flexible AWS CLI (Command Line Interface). The AWS CLI can be modified to match certain use cases and workflows because it is made to be highly flexible. It is also simple to combine with other tools and services thanks to the variety of output formats it offers, including JSON, YAML, and text.

The AWS CLI can be installed following the guide in this [AWS documentation](https://aws.amazon.com/cli/). Once installed, you can set up access keys to use as credentials. In this scenario, I am going to use AWS CloudShell to run the AWS CLI commands from the browser.

## CLoudFormation Template
The CloudFormation template to set up the VPC, subnets, security groups and EC2 instances is shown below. The code can be saved as IACTest.yaml and uploaded to AWS CloudShell. For the key name, The `3tier` specified is an already existing key pair.

```
---
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: "10.0.0.0/16"
      EnableDnsHostnames: true
      Tags:
        - Key: "Name"
          Value: "LabVPC"
  PublicSubnet:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: "us-east-1a"
      CidrBlock: "10.0.0.0/24"
      MapPublicIpOnLaunch: true
      VpcId: !Ref VPC
      Tags:
        - Key: "Name"
          Value: "MyPublicSubnet"
  PrivateSubnet:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: "us-east-1b"
      CidrBlock: "10.0.1.0/24"
      MapPublicIpOnLaunch: false
      VpcId: !Ref VPC
      Tags:
        - Key: "Name"
          Value: "MyPrivateSubnet"
  SecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "Allow inbound traffic to the EC2 instances"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
  Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: t2.micro
      ImageId: ami-0c94855ba95c71c99
      KeyName: "3tier"
      NetworkInterfaces:
        - DeviceIndex: "0"
          SubnetId: !Ref PublicSubnet
          GroupSet:
            - !Ref SecurityGroup

```
You can then run the command `aws cloudformation create-stack --stack-name my-stack --template-body file://IACTest.yaml --region us-east-1` to deploy the CloudFormation stack. 

![Deploying CloudFormation stack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x7n8le86vphmrr3o1yrg.png)

We can configure the EC2 instances to run a sample web application by adding user data section to the template and then updating the template. This modifies the Instance section of the template to look like this:

```
  Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: t2.micro
      ImageId: ami-0c94855ba95c71c99
      KeyName: "3tier"
      NetworkInterfaces:
        - DeviceIndex: "0"
          SubnetId: !Ref PublicSubnet
          GroupSet:
            - !Ref SecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<html><head><title>EC2 Instance Metadata</title></head><body><h1>EC2 Instance ID:</h1>" >> /var/www/html/index.html
          curl http://169.254.169.254/latest/meta-data/instance-id >> /var/www/html/index.html
          echo "</body></html>" >> /var/www/html/index.html
```

We can the update the CloudFormation stack by running the following command: `aws cloudformation update-stack --stack-name my-stack --template-body file://IACTest.yaml --region us-east-1`.

![Updating CloudFormation Stack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gre64lbodejl669iv72r.png)