Mary Similoluwa Medoye
9 min readJan 22, 2024

DEPLOYING A TWO-TIER APPLICATION ON AWS USING TERRAFORM

Project Description

This project aims to streamline the deployment of a 2-tier application on AWS by leveraging Terraform for automated infrastructure provisioning. This approach enhances scalability and maintainability, ensuring a more efficient and reliable deployment process. The project involves configuring AWS resources and services to support a 2-tier architecture, with Terraform scripts handling the setup and maintenance of these resources. This modern infrastructure-as-code method not only speeds up deployment but also improves consistency and reduces the potential for human error in the setup process.

Architectural Diagram

Architectural Diagram

Key Components and Features

Terraform, a prominent Infrastructure as Code (IaC) tool, is employed to provision the necessary AWS resources for deploying the two-tier application. Terraform offers a significant advantage over manual provisioning via the AWS console. Its declarative language, which can be tracked and version-controlled using Git, not only documents all changes but also encourages collaborative development and infrastructure management. This approach ensures the creation of repeatable and consistent environments, greatly reducing the likelihood of manual errors. Terraform’s powerful automation capabilities facilitate a more efficient and reliable infrastructure deployment process, significantly enhancing deployment speed and overall system reliability.

Prerequisites

To successfully implement this project, a foundational understanding of AWS services and concepts is essential. Participants will need to have:

  1. An active AWS Account: This is necessary for accessing and utilizing various AWS services required for the project.
  2. Terraform Installed on the Local Machine: Terraform is the key tool for infrastructure automation in this project. It should be correctly installed and configured on your local system.
  3. An Integrated Development Environment (IDE): For this project, Visual Studio Code is recommended. It offers a robust and user-friendly interface for writing and managing Terraform configurations and other code.

STEPS

Step 1: Setting up your development environment

Start by setting up your local environment with the necessary tools. Follow these steps:

  1. Install Terraform: Download and install Terraform on your local machine. This tool is crucial for automating infrastructure deployment.
  2. Install AWS CLI: Similarly, install the AWS Command Line Interface (CLI). This allows you to interact with AWS services directly from your command line.
  3. Configure AWS Credentials: Run the command aws configure in your terminal. During this process, you will be prompted to enter your AWS access key and secret key. This step is vital for authenticating and establishing a connection between your local environment and AWS services.
  4. Verify Installations: Ensure that both installations are successful. You can do this by checking the versions of both Terraform and AWS CLI. Use the command terraform version for Terraform and aws --version for the AWS CLI. Successful version display confirms the correct installation of these tools.

Step 2: Directory Overview

  1. Provider.tf
provider.tf

The ‘provider.tf’ file in Terraform plays a critical role as the configuration file where you specify the cloud provider you intend to use for infrastructure deployment, such as AWS, Azure, or Google Cloud. This file acts as a directive, akin to choosing the appropriate toolbox for a specific job. Within ‘provider.tf’, you detail the essential information required for Terraform to interface effectively with your chosen cloud provider. This includes providing credentials and various configuration settings. Essentially, by setting up this file, you are equipping Terraform with the necessary access keys and parameters to efficiently manage and orchestrate resources within your selected cloud environment, thereby enabling Terraform to act as an effective intermediary in handling your cloud infrastructure.

2. Network_resource.tf

  • VPC creation (aws_vpc)

Establishes a Virtual Private Cloud (VPC) with the specified CIDR block (10.0.0.0/16).

VPC creation
  • Public subnet creation (aws_subnet)

Generates two public subnets within the VPC. Enables public IP mapping, allowing instances to possess public IP addresses. Associates each subnet with an availability zone in the ap-southeast-1 region. Includes tags for identification.

Public subnet
  • Private subnet creation (aws_subnet)

Creates two private subnets within the VPC. Disables public IP mapping to prevent direct public internet access for instances. Associates subnets with availability zones and adds identification tags.

  • Internet Gateway Setup (aws_internet_gateway)

Establishes an internet gateway and links it to the VPC. Enables resources within the VPC to connect to the internet and vice versa.

  • Route Table Configuration (aws_route_table)

Creates a route table linked to the VPC. Defines a default route (0.0.0.0/0) via the internet gateway. Used by public subnets to route traffic to the internet.

  • Association of Route Tables with Public Subnets (aws_route_table_association)

Associates the route table from the previous step with public subnets. Ensures public subnet instances use the specified route table for internet-bound traffic.

Load Balancer Setup (aws_lb): Establishes an Application Load Balancer (ALB) with a name. Specifies it as non-internal, accessible from the internet. Attaches security groups to regulate inbound and outbound traffic. Designates subnets for distributing incoming traffic across two public subnets. Includes tags for identification.

  • Target Group Creation (aws_lb_target_group)

Generates a target group for routing requests to backend instances. Listens on port 80 using the HTTP protocol. Associates with the VPC.

Creates an ALB listener to handle incoming HTTP traffic on port 80. Forwards incoming requests to the previously defined target group.

  • Target Group for Database Subnet (aws_lb_target_group)

Establishes another target group for potential database instances. Configured for future use, even though not currently attached in this configuration.

  • EC2 Instance Attachment to Target Group (aws_lb_target_group_attachment)

Allows attachment of instances to the target group for the ALB. Assumes the existence of two instances (aws_instance.two-tier-web-server-1 and aws_instance.two-tier-web-server-2) representing web servers in the architecture.

  • Database Subnet Group Creation (aws_db_subnet_group): Creates a database subnet group, specifying available private subnets for RDS instances. Includes both private subnets established earlier.

3. Security_resource.tf

Security group for EC2 instance

  • Ingress Rules (Inbound Traffic)

Permits all incoming traffic on all ports (from_port = “0”, to_port = “0”, protocol = “-1”). Note that this is generally not recommended for production and should be configured more restrictively. Allows incoming traffic on port 80 (HTTP) from any source (cidr_blocks = [“0.0.0.0/0”]). Allows incoming traffic on port 22 (SSH) from any source. It’s essential to mention that this configuration is not recommended for production, and SSH access should ideally be confined to trusted IP addresses.

  • Egress Rules (Outbound Traffic)

Enables all outgoing traffic to any destination (from_port = “0”, to_port = “0”, protocol = “-1”). Security Group for Load Balancer (aws_security_group.two-tier-alb-sg): Defines a security group named “two-tier-alb-sg” associated with the same VPC as above (aws_vpc.two-tier-vpc.id). Dependencies are specified to ensure the VPC is created before this security group.

Security group for load balancer

  • Ingress Rules (Inbound Traffic)

Permits all incoming traffic on all ports from any source (from_port = “0”, to_port = “0”, protocol = “-1”, cidr_blocks = [“0.0.0.0/0”]). This configuration is generally not recommended for production as it exposes the load balancer to all traffic.

  • Egress Rules (Outbound Traffic)

Allows all outgoing traffic to any destination (from_port = “0”, to_port = “0”, protocol = “-1”).

Security group for the database

Security Group for Database Tier (aws_security_group.two-tier-db-sg)

Defines a security group named “two-tier-db-sg” associated with the same VPC as above (aws_vpc.two-tier-vpc.id).

  • Ingress Rules (Inbound Traffic)

Permits incoming traffic on port 3306 (MySQL) from any source (from_port = 3306, to_port = 3306, protocol = “tcp”, cidr_blocks = [“0.0.0.0/0”]). It’s important to note that allowing MySQL traffic from anywhere is generally not recommended for production, and restrictions to trusted sources should be implemented. Allows incoming traffic on port 22 (SSH) from a specific IP range within the VPC (from_port = 22, to_port = 22, protocol = “tcp”, security_groups = [aws_security_group.two-tier-ec2-sg.id], cidr_blocks = [“10.0.0.0/16”]). This enhances security by restricting SSH access to a specific IP range within the VPC.

  • Egress Rules (Outbound Traffic)

Enables all outgoing traffic to any destination (from_port = “0”, to_port = “0”, protocol = “-1”).

4. EC2_instance.tf

Public Subnet EC2 Instance 1 (aws_instance.two-tier-web-server-1)

  • Defines an EC2 instance named “two-tier-web-server-1” using the specified Amazon Machine Image (AMI) ID (ami-064eb0bee0c5402c5).
  • Sets the instance type to t2.micro for a cost-effective, general-purpose configuration.
  • Associate the instance with the previously defined security group (aws_security_group.two-tier-ec2-sg.id).
  • Places the instance in the public subnet two-tier-pub-sub-1 using the subnet_id.
  • Utilizes the “two-tier-key” key pair for SSH access.
  • Adds tags for easy identification. User Data Script:
  • Includes a Bash script in the user_data section that:
  • Updates system packages (sudo yum update -y).
  • Installs NGINX (sudo amazon-linux-extras install nginx1 -y).
  • Enables NGINX to start on boot (sudo systemctl enable nginx).
  • Starts NGINX (sudo systemctl start nginx).

Public Subnet EC2 Instance 2 (aws_instance.two-tier-web-server-2)

  • Similar to the first instance, defines a second EC2 instance named “two-tier-web-server-2” with identical configurations, but placed in the public subnet two-tier-pub-sub-2.

Elastic IPs (EIPs) for EC2 Instances

  • Allocates Elastic IPs (aws_eip) for each EC2 instance.
  • Associates EIP 1 (aws_eip.two-tier-web-server-1-eip) with two-tier-web-server-1.id.
  • Associates EIP 2 (aws_eip.two-tier-web-server-2-eip) with two-tier-web-server-2.id.
  • These EIPs provide static public IP addresses to the EC2 instances, ensuring accessibility from the internet.

Each step encompasses the creation and configuration of resources required for running EC2 instances in public subnets. The user data scripts initialize the instances, and the Elastic IPs secure static public IP addresses for consistent internet accessibility.

5. DB_resources.tf

A MySQL database instance using RDS (aws_db_instance) is specified with a range of configurations, as outlined in the Terraform documentation.

Step 3 -Deploy

  • terraform init

Initiates the Terraform configuration.

  • terraform plan

Generates an execution plan for the Terraform configuration

  • terraform apply

Executes the Terraform configuration, initiating the creation or modification of resources within the specified AWS environment.

Conclusion

In this comprehensive guide, we’ve explored the deployment of a Two-Tier architecture on AWS using Terraform. Our approach emphasizes modularity, incorporating advanced security measures. The infrastructure is thoughtfully organized into dedicated modules, ensuring scalability, maintainability, and robust security. Access our GitHub repository here for detailed resources and code implementation.

d