Deploy scalable, highly-available and infra-as-code managed web app on AWS
Tags: aws, ecs, cloudformation, developer
Published: 2020-09-03 05:16:46

### Learn how to deploy a scalable, highly available and infra-as-code managed [3-tier web application](https://www.techopedia.com/definition/24306/three-tier-application) on AWS.

In this post, I'll be using Crystalnix’s **Omaha Server** as an example web application but it should equally apply to any other web app you wish to deploy onto AWS.

**What is Omaha Server?**
> An open-source implementation of Google’s [Omaha update protocol](https://github.com/omaha-consulting/omaha-server/blob/master/github.com/google/omaha), which for example powers Chrome’s automatic update mechanism. Omaha server is used by organizations large and small for products that require sophisticated update logic and advanced usage statistics.
[omaha-consulting/omaha-server](https://github.com/omaha-consulting/omaha-server)

### Technologies

* AWS CloudFormation

* Amazon VPC

* AWS ALB

* Amazon ElastiCache (redis)

* Amazon RDS (postgres)

* AWS S3

* Amazon ECS with EC2 launch type

* and Docker.

### Architecture

Here's the high-level architecture diagram of what we'll be working on.

![Fig: High-level Architecture Diagram](https://cdn-images-1.medium.com/max/3840/1*LU2_Vl1DVgBGQj6czNRSkg.png)

##### Let’s get started and have fun learning!

### 1. Clone the repository from Github

    $ git clone https://github.com/tuladhar/omaha-server-on-aws

{% github tuladhar/omaha-server-on-aws no-readme %}

### 2. Setup AWS credentials and environment variables

    $ export AWS_PROFILE=REPLACE_ME
    $ export AWS_REGION=us-east-1

    $ export ENV_LABEL=omaha
    $ export ENV_TYPE=nonprod

### 3. Deploy stack: Virtual Private Cloud (VPC)

![Fig: VPC with private & public subnet on AZ1 & AZ2 with Internet and NAT gateway](https://cdn-images-1.medium.com/max/2092/1*v7IxhObVJX4fMkxawNpyRw.png)*Fig: VPC with private & public subnet on AZ1 & AZ2 with Internet and NAT gateway*

    $ export SECOND_OCTET=254

    $ make -C 01_NETWORK/01_VPC create-stack

![Fig: CloudFormation stack](https://cdn-images-1.medium.com/max/2132/1*hIWR2N6lAUJkbncW8WqjZQ.png)*Fig: CloudFormation stack*

### 4. Deploy stack: Multi-AZ Public Load-balancer

![Fig: Publicly reachable load-balancer deployed on public subnet AZ1 & AZ2](https://cdn-images-1.medium.com/max/2000/1*ZY15-FvnfACPY8i8s4BjXA.png)*Fig: Publicly reachable load-balancer deployed on public subnet AZ1 & AZ2*

    $ make -C 01_NETWORK/02_ALB create-stack

![Fig: CloudFormation stack](https://cdn-images-1.medium.com/max/2128/1*o0F0sEqTUc8UKtbPA0_DoA.png)*Fig: CloudFormation stack*

### 5. Deploy stack: Multi-AZ ElastiCache Redis Cluster

![Fig: Multi-AZ ElastiCache Redis Cluster](https://cdn-images-1.medium.com/max/2364/1*3GI825keZxuQPmA7PhdUuw.png)*Fig: Multi-AZ ElastiCache Redis Cluster*

    $ make -C 02_DATABASE/01_REDIS create-stack

![Fig: Redis CloudFormation stack](https://cdn-images-1.medium.com/max/2118/1*kmViuo1smJsNm3T_an1foQ.png)*Fig: Redis CloudFormation stack*

### 6. Deploy stack: Multi-AZ RDS (postgres) with read-replica

![Fig: Multi-AZ RDS (postgres) with read-replica](https://cdn-images-1.medium.com/max/2820/1*lIP8GKg2B7f7VpKBiYPoiQ.png)*Fig: Multi-AZ RDS (postgres) with read-replica*

    $ make -C 02_DATABASE/02_RDS create-stack

### 7. Deploy stack: S3 bucket

    $ make -C 03_S3 create-stack

![Fig: S3 Bucket CloudFormation Stack](https://cdn-images-1.medium.com/max/2104/1*zQSV5qzOgJ62YpR-d8ZvnA.png)*Fig: S3 Bucket CloudFormation Stack*

### 8. Deploy stack: ECS Cluster

![Fig: Deploy ECS cluster with EC2 launch type](https://cdn-images-1.medium.com/max/2304/1*1vIdLuNy_gt6Dp_UfHdshA.png)*Fig: Deploy ECS cluster with EC2 launch type*

<iframe src="https://medium.com/media/e9132aaeff02b6c23ec8c97dd874ddc7" frameborder=0></iframe>

    $ make -C 04_COMPUTE/01_ECS/01_CLUSTER create-stack

![Fig: Cloudformation stack](https://cdn-images-1.medium.com/max/2096/1*_755WC081XK9nlrVmObieA.png)*Fig: Cloudformation stack*

### 9. Deploy stack: ECS service that runs Omaha Server (Django App) container

![Fig: Deploy the app](https://cdn-images-1.medium.com/max/2360/1*xzeiyXUeGr2bd5U-k5TaGw.png)*Fig: Deploy the app*

    $ make -C 04_COMPUTE/01_ECS/02_SERVICE create-stack

![Fig: CloudFormation stack](https://cdn-images-1.medium.com/max/2100/1*BoknLnyNy_V7Parr1sNO7Q.png)*Fig: CloudFormation stack*

### Demo: Omaha Server Dashboard

![Fig: Omaha Server Dashboard](https://cdn-images-1.medium.com/max/2552/1*Hkvjg-nZ4lqqmdiIYE02aQ.gif)*Fig: Omaha Server Dashboard*

### Conclusion

**And that’s it.** I hope you've enjoyed reading and learned something new.

**What’s next?**

* Use SSM to store RDS credentials and avoid hard-coding in CloudFormation template.

* Separate out the VPC subnets for stateless and stateful resources. [Read about it in this blog post](https://dev.to/ptuladhar3/design-secure-scalable-vpc-for-micro-service-architecture-4iah).

#### *Don’t forget to hit 👏 and follow for more awesome blog posts.*