This repository provisions a small AWS application stack with:
- A custom VPC across 2 Availability Zones
- Public and private subnets
- Internet + NAT egress design
- An internet-facing ALB
- Backend EC2 instances managed by an Auto Scaling Group
- A standalone frontend EC2 instance
- A private MySQL RDS instance
The goal of this README is to help you understand what each Terraform file does and how they connect.
mindmap
root((main.tf))
"terraform.tf"
"Terraform version constraint"
"AWS provider source + version"
"vpc_setup.tf"
"aws_vpc.app_vpc"
"AZ data sources - 1a and 1b"
"Public subnets - A and B"
"Private subnets - A and B"
"IGW + EIPs + NAT GWs"
"Public and private route tables + associations"
"backend_setup.tf"
"Amazon Linux AMI data source"
"Key pair"
"ALB + listener + target group"
"ASG + launch template + scaling policy"
"Backend SG"
"frontend.tf"
"Frontend EC2 in public subnet"
"Frontend SG - ports 22 and 80 ingress"
"User-data points to ALB DNS"
"db_setup.tf"
"DB subnet group - private subnets"
"DB SG - port 3306 from backend SG"
"RDS MySQL instance"
"variables.tf"
"Instance sizing and name vars"
"SSH and public key vars"
"Sensitive DB vars"
"outputs.tf"
"ALB DNS output"
"Frontend public IP output"
"DB host output"
- Defines the AWS provider block and target region (
us-east-1). - Serves as the entry point context for the configuration set.
- Mostly comments and Terraform learning notes; no resources are declared here.
- Configures Terraform itself:
required_providers.awsfromhashicorp/awswith version~> 5.92required_version = ">=1.2"
- No infrastructure resources; this file controls tooling compatibility.
Defines all core networking.
Resources and data sources:
aws_vpc.app_vpcdata.aws_availability_zone.az-adata.aws_availability_zone.az-baws_subnet.public_subnet_aaws_subnet.private_subnet_aaws_subnet.public_subnet_baws_subnet.private_subnet_baws_internet_gateway.app_vpc_igaws_eip.eip_aaws_eip.eip_baws_nat_gateway.nat_aaws_nat_gateway.nat_baws_route_table.public_subnet_rtaws_route_table.private_subnet_a_rtaws_route_table.private_subnet_b_rtaws_route_table_association.public_subnet_a_rt_associationaws_route_table_association.public_subnet_b_rt_associationaws_route_table_association.private_subnet_a_rt_associationaws_route_table_association.private_subnet_b_rt_association
What it builds:
- A VPC
10.0.0.0/16 - 4 subnets split across
us-east-1aandus-east-1b - Public egress through IGW for public subnets
- Private subnet outbound internet access through per-AZ NAT gateways
Defines backend compute and traffic entry.
Resources and data sources:
data.aws_ami.amazon_linuxaws_key_pair.app_key_pairaws_lb_target_group.lb_target_groupaws_security_group.lbaws_lb.app_lbaws_lb_listener.app_lb_listeneraws_launch_template.launch_templaws_autoscaling_group.auto_sc_groupaws_autoscaling_policy.cpu_usageaws_autoscaling_attachment.asg_lb_linkaws_security_group.backend_sg
What it builds:
- Internet-facing Application Load Balancer in both public subnets
- HTTP listener on port 80 forwarding to target group
- Launch template for backend instances (user-data from
backend-script-setup.tftpl) - Auto Scaling Group in private subnets (min 2, desired 2, max 4)
- Target tracking scaling policy on average CPU
- Security model where backend accepts HTTP only from the ALB security group
Defines a separate frontend instance and its security group.
Resources:
aws_instance.frontend_serveraws_security_group.frontend_sg
What it builds:
- One public EC2 frontend host in
public_subnet_a - Public IP attached
- User-data generated from
frontend-script-setup.tftpl, with backend ALB DNS injected - Inbound rules for SSH (22) and HTTP (80) from
0.0.0.0/0
Defines the database layer.
Resources:
aws_db_subnet_group.dbaws_security_group.dbaws_db_instance.db
What it builds:
- RDS subnet group spanning private subnets
- DB security group that allows MySQL (3306) only from backend security group
- Private MySQL RDS instance (
publicly_accessible = false)
Defines configurable inputs for the stack.
Notable variables:
- EC2 settings:
instance_name,instance_type - SSH/key path settings:
ssh_key,public_key - Bootstrap helper values:
ec2_init_log_file,ec2_custom_user - Sensitive DB inputs:
db_username,db_passwd,db_name
Defines useful post-apply values:
load_balancer_dnsfrontend_ssh(frontend public IP)db_host(RDS endpoint)
- Networking comes first (
vpc_setup.tf) to provide VPC, subnets, routing, and NAT. - Backend components (
backend_setup.tf) use that networking:- ALB in public subnets
- ASG instances in private subnets
- Frontend instance (
frontend.tf) is public and calls the backend through ALB DNS. - Database (
db_setup.tf) stays private and is reachable from backend instances only. - Outputs expose key runtime endpoints.
terraform init
terraform validate
terraform plan
terraform applyIf variables are not provided via *.tfvars or environment variables, you will need to set at least:
db_usernamedb_passwddb_name
- Terraform loads all
.tffiles in this directory as one configuration. - Template files (
*.tftpl) are used for EC2 bootstrap scripts. - State files (
terraform.tfstate*) contain real infrastructure metadata and should be handled carefully.