Multi-Tier Web App on AWS with Terraform preview
  • Multi-Tier Web App on AWS with Terraform

    AWS, Terraform, EC2, RDS (MySQL), S3, VPC, IAM, CloudWatch, SNS, Linux, Bash

  • Type

    Cloud infrastructure, automation and troubleshooting project, 2026

  • Source Code

    github.com/Farabe1911/Multi-tier-AWS-Terraform

  • Work With Me

    Contact me about a cloud support or operations role.

Info

A complete two-tier web application on AWS, provisioned entirely with Terraform, with monitoring, alerting and a real-world troubleshooting runbook. The application itself is intentionally minimal: the focus is the infrastructure, the automation, and the operational documentation. About 19 resources deploy and tear down with a single command, and the stack runs within free-tier and credit limits, with a billing budget and a CloudWatch billing alarm set up before anything was deployed.

Architecture

Users reach the EC2 web server in a public subnet through an internet gateway. The web server connects to a MySQL RDS database in a private subnet that only accepts traffic from the web tier's security group, and reaches S3 and CloudWatch through a least-privilege IAM role.

Architecture diagram: users reach an EC2 web server in a public subnet through an internet gateway; the web server connects to an RDS database in a private subnet, and uses an IAM role to reach S3 and CloudWatch

The Challenge

Stand up realistic infrastructure the way a cloud team would: secure by default, reproducible, monitored, and cheap to run. Then go a step further than a typical demo by deliberately breaking it — removing an IAM permission, creating state drift, and more — and diagnosing each failure from symptom to root cause, the way a support engineer works a ticket.

The Solution

Everything is defined as code in Terraform: a VPC (10.0.0.0/16) with a public subnet for the EC2 web tier and private subnets in two Availability Zones for a MySQL RDS database, an S3 bucket with public access fully blocked, a least-privilege IAM instance role, and a CloudWatch CPU alarm that emails through SNS. Twelve real failure scenarios are documented in a support-style runbook.

Key Design Choices

  • Public/private subnet split: the database has no route to the internet; only the web tier can reach it.
  • No NAT gateway: a deliberate cost choice, since the managed database needs no outbound internet access.
  • Least-privilege IAM: the instance role grants only S3 and CloudWatch, with no long-lived keys on the server — verified by confirming that ungranted actions are denied.
  • Security groups as tier-to-tier firewalls: the database trusts the web tier's security group, not an IP range; SSH is locked to a single IP.
  • No secrets in code: the database password is a runtime variable, and state files, keys and variable files never reach version control.

Troubleshooting Runbook

Each scenario records the symptom, diagnostic steps, root cause and fix. Examples:

  • SSH refused with "invalid format" on a valid key — PowerShell had saved it as UTF-16 instead of ASCII.
  • "Access Denied" calling S3 from the instance — a missing policy on the least-privilege role.
  • DBInstanceAlreadyExists on apply — Terraform state drift, reconciled with terraform import instead of rebuilding.
  • RDS creation failing on a password that broke the service's input rules.
  • A CloudWatch alarm firing — worked through the full detect, alert, remediate and recover cycle.

What It Demonstrates

Secure multi-tier AWS design, infrastructure as code with Terraform (including state management), least-privilege IAM, monitoring and incident response with CloudWatch and SNS, cost control with budgets and routine teardown, and structured troubleshooting documented the way a support engineer documents a resolved ticket.