3-Tier Application Infrastructure Deployment with Terraform, ECS, and GitHub Actions
- Varun Rajput
- Feb 23, 2024
- 5 min read
Updated: Jun 11, 2024
Imagine 🌟
you're excited to launch your application, but the overwhelming responsibility of deploying a secure, cost-effective, and automated infrastructure is hindering you. Don't worry! With just a few CLI commands and our carefully designed Terraform setup, you can get your application up and running quickly.
Why Automation Matters ⚙️
In today's fast-paced world of cloud computing, automating infrastructure deployment is no longer a luxury but a necessity. Terraform is a widely used infrastructure as a code tool that simplifies this process. It allows you to define your infrastructure in code and provision it across various cloud providers.
What's in Store 📦
In this blog post, we'll embark on an exciting journey to deploy a 3-tier application on AWS using Terraform and GitHub Actions. But before you start skimming, let me assure you – this won't be your typical theoretical deep dive. Instead, we'll dive into practical scenarios, offering you a hands-on guide to kickstart your Terraform journey for real-world projects. 💡
Target Audience 🎯
Looking to create a 3-tier infrastructure in AWS with existing frontend and backend docker images? Look no further!
Assuming you have beginner theoretical knowledge of Terraform basic concepts and AWS services
What is a 3-Tier Application? ℹ️
A 3-tier application architecture divides an application into three logical tiers: presentation i.e. Frontend, application ( Backend ), and data as Database. Each tier is responsible for a specific application's functionality, leading to better scalability, maintainability, and performance. 🏗️
We've handpicked AWS as our cloud platform, harnessing the robust capabilities of ECS containers for both Frontend and Backend services and RDS as a database. But wait, there's more – we've integrated GitHub Actions into the mix for a smooth CI/CD pipeline that automates your workflow from code to deployment. 🛠️
Our Tech Stack 💻
For this deployment, we'll rely on a stack of services:
ECS (Elastic Container Service) for frontend and backend containers
RDS (Relational Database Service) for the database
ECR (Elastic Container Registry) for Docker image repository
ALB (Application Load Balancer) to top it all off for the frontend endpoint
Repository: https://github.com/var1914/automated-3-tier-infrastructure
Let's Get Hands-On!
Picture this: 🖼️ With just a few clicks and edits in a single file – tfvars, you can deploy an entire 3-tier application infrastructure effortlessly. 💻🔧
Let me walk you through how it's set up:
Our infrastructure deployment is automated through a seamless integration of GitHub Actions workflows and Terraform – think of it as your Infrastructure Deployment Pipeline. 🚀
Setting Up Prerequisites 🛠️
Before diving into the deployment, let's make sure we've set up a few things:
S3 Backend for Terraform State Files: To securely store Terraform state files ( Why we require state file, ref: Purpose of Terraform State ), you need to create a simple S3 bucket as the Terraform backend. After creation, you can configure the provider.tf file. Make sure to replace the placeholder values with your own S3 bucket name and key.
terraform {
backend "s3" {
bucket = "terraform-state-varun-blogs" # Replace with your bucket name
key = "terraform-state.tfstate" # its upto you
region = "eu-central-1" # Replace with your region name
}
}
AWS Access Keys and Secret Access Key ID as GitHub Actions Secret: For secure interaction with AWS services, we need to set up AWS access keys and secret access key ID as GitHub Actions secrets.
Generate an AWS access key and secret access key ID from the AWS Management Console, make sure it has almost Admin Rights, ref: https://docs.aws.amazon.com/cli/latest/userguide/cli-authentication-user.html
Navigate to your GitHub repository's settings and locate the "Secrets" section.
Add two secrets: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, and paste the corresponding values of your AWS access key and secret access key ID respectively.
Configure AWS_REGION as well, based on your requirements, and where you want to deploy infrastructure.
Now, let's come to actual implementation:
But, First learn a few things about Terraform 🧐:
Terraform Initialization: 🏗️ Setting up the working directory and downloading any necessary plugins or modules.
Terraform Plan: 📝 Generating an execution plan that shows what resources Terraform will be going to deploy when applying changes to infrastructure.
Terraform Apply: 🚀 Applying the changes described in the execution plan to the real infrastructure.
tfvars: 🛠️ Configuration file used to define variables for Terraform configurations, allowing for customization without modifying the main configuration files.
Now, the Infrastructure Deployment pipeline is configured to be triggered by changes in two branches: main for production deployment, and develop for staging. While these branches are examples, you can tailor them to suit your specific needs. 🛠️
And, Here's the magic: Make your changes in the develop branch i.e. in stage.tfvars file, git push it, and watch the infrastructure being deployed for your staging environment. Similarly, modifications in the main branch prod.tfvars will deploy to your production environment.

Well, it's not necessary to be tfvars changes, any changes to the develop/main branch will trigger infrastructure deployment to stage/prod respectively. 🌟
Just make sure you customize your stage.tfvars / prod.tfvars as per your need, like CPU, Memory, PORT ( where your application going to run ), REGION, AWS ACM Cert ARN, etc..
Sounds easy, right? 😄
Just remember to include your AWS Certs Manager ACM ARN in the tfvars file. This is crucial because our infrastructure is designed to deploy an Application Load Balancer (ALB) with HTTPS access, which you can then map your DNS. 🔐
Keep an eye on the progress by checking the logs in the GitHub Actions workflow titled Terraform Plan and Apply. 📋 ( Well, you will not find any build logs on my repo, because of security reasons )

So, With just a few steps:
Make your changes in either stage.tfvars / prod.tfvars.
Push those changes to GitHub.
Watch as the Infrastructure Deployment kicks off, based on the branch you pushed to.
Voilà! Your Infrastructure will be up and running smoothly. 🌟
Post-Deployment Verification ✅
Once the deployment is complete, Terraform will output the endpoint ALB URL and other necessary information as shown in below snap. 🛠️ Map these URLs to your DNS to access your application and verify that everything is up and running smoothly. 🌐
alb_dns_name = "blogging-demo-production-alb-XXXXXX.***.elb.amazonaws.com"
backend_ecr = "XXXXXXXXXXX.dkr.ecr.***.amazonaws.com/blogging-demo-production-backend"
frontend_ecr = "XXXXXXXXXXX.dkr.ecr.***.amazonaws.com/blogging-demo-production-frontend"

Note: ALB URL will give 503 error until you push frontend and backend docker images to ECR, to mitigate these, you can refer to my separate CI/CD blog, where we deploy sample docker images and can make the ALB URL work.
These Infrastructure Deployment pipeline steps can also be tried from your local machine as well, more information can be found on READ.me at https://github.com/var1914/automated-3-tier-infrastructure
How to Clean Up and Destroy 🧹🛠️
To clean up and destroy your infrastructure, follow these steps:
Set up your local machine with AWS credentials and Terraform 🔑💻.
Run the following commands:
terraform init
terraform destroy -var-file=stage.tfvars # for stage environment from develop branch
terraform destroy -var-file=prod.tfvars # for stage environment from main branch
Need to take care few things..
Take care of the number of characters for project_name in tfvars, it should not have more than 15 chars
What if you just want to look and play for Terraform Init and Plan, not Terraform Apply
Comment out Github Actions Workflow Terraform Apply step
What If you want your ALB to be private or want your app to be accessible within the private network?
Add below in main.tf
alb_public_access = var.alb_public_access
Add below in stage.tfvars / prod.tfvars
alb_public_access = false
Wrapping Up
With just minimal file changes in tfvars and a simple git push, you can deploy your 3-tier application on AWS effortlessly. Think of this as a standard template that you can use anywhere for quick and reliable deployments. 🚀
Stay tuned for more practical guides and hands-on tutorials. Until next time, happy Terraforming!
Please share and comment, to make Cloud and DevOps community better.
Comments