Example: Two-Tier Architecture
Relevant source files
The following files were used as context for generating this wiki page:
This Terraform example provides a template for deploying a simple, stateless two-tier architecture on Amazon Web Services. The architecture consists of stateless application servers running behind an Elastic Load Balancer (ELB) to serve traffic. This setup is a foundational pattern for building scalable and resilient web applications.
The example focuses on provisioning the core infrastructure and intentionally omits the application deployment process itself. Application deployment could be handled separately using Terraform provisioners with a configuration management tool or by using pre-configured AMIs created with a tool like Packer. Upon successful application of this configuration, it outputs the DNS address of the ELB.
Sources: examples/two-tier/README.md
Architecture Overview
The architecture creates a classic two-tier setup with a public-facing load balancer that distributes traffic to a group of backend web servers in a private subnet. The web servers are managed by an Auto Scaling group to ensure high availability and scalability.
The following diagram illustrates the high-level data flow and components provisioned by this Terraform configuration.
Sources: examples/two-tier/main.tf:85-152
Configuration
Input Variables
The behavior of the deployment can be customized through several input variables defined in variables.tf.
| Variable Name | Description | Type | Default Value |
|---|---|---|---|
aws_region | The AWS region to create things in. | string | "us-east-1" |
key_name | The name to be used for the EC2 Key Pair that will be created. | string | "" |
public_key_path | The path to the public key to be used for the EC2 Key Pair. | string | "" |
instance_count | The number of instances to run in the auto-scaling group. | string | "2" |
Sources: examples/two-tier/variables.tf:1-16, examples/two-tier/README.md:11-13
Provider Configuration
The configuration specifies the aws provider and sets the region based on the aws_region variable.
# main.tf
provider "aws" {
region = var.aws_region
}
Sources: examples/two-tier/main.tf:4-6
Core Components
Networking
A dedicated Virtual Private Cloud (VPC) is created to isolate the application's network resources.
- VPC (
aws_vpc.default): A VPC with a/16CIDR block is created to house all network components. - Internet Gateway (
aws_internet_gateway.default): An IGW is attached to the VPC to allow communication with the internet. - Subnet (
aws_subnet.default): A single public subnet with a/24CIDR block is defined. It is configured to map public IPs on launch. - Route Table (
aws_route_table.default): A route table is created and associated with the subnet. It includes a default route (0.0.0.0/0) pointing to the Internet Gateway, which provides internet access for the resources within the subnet.
Sources: examples/two-tier/main.tf:12-35
The diagram below shows the networking layout.
Sources: examples/two-tier/main.tf:12-35
Security
Two security groups are configured to control traffic flow to the ELB and the web server instances.
| Resource | Ingress Rules | Egress Rules |
|---|---|---|
aws_security_group.elb | Port 80 (HTTP) from anywhere (0.0.0.0/0). | All traffic to anywhere (0.0.0.0/0). |
aws_security_group.web | Port 80 (HTTP) from the ELB's security group. Port 22 (SSH) from anywhere (0.0.0.0/0). | All traffic to anywhere (0.0.0.0/0). |
This configuration ensures that only the ELB can send HTTP traffic to the web servers, while SSH access is open for administrative purposes.
Sources: examples/two-tier/main.tf:37-71
Load Balancer
An aws_elb resource is provisioned to act as the public entry point for the application.
- Listeners: It listens for incoming HTTP traffic on port 80 and forwards it to the backend instances on port 80.
- Health Checks: It performs health checks on the instances by sending a request to the
/path on port 80. An instance is considered unhealthy after 2 consecutive failed checks and healthy after 2 successful checks. - Instances: It is attached to the instances created by the Auto Scaling group.
Sources: examples/two-tier/main.tf:85-107
Compute Layer (Auto Scaling Group)
The compute layer is managed by an Auto Scaling group to ensure the desired number of instances are running.
aws_launch_configuration.web: This defines the template for the EC2 instances.- AMI: It uses a data source
aws_ami.ubuntuto find the latest Ubuntu 20.04 LTS AMI. - Instance Type:
t2.micro. - User Data: A startup script is provided via
user_datato install and start the Nginx web server, creating a simple default web page. - Key Pair: Associates the created
aws_key_pair.authfor SSH access.
- AMI: It uses a data source
aws_autoscaling_group.web: This resource manages the lifecycle of the EC2 instances.- It uses the launch configuration defined above.
- It maintains a
desired_capacitybased on theinstance_countvariable (defaulting to 2). - It is associated with the ELB to automatically register new instances.
Sources: examples/two-tier/main.tf:73-83, examples/two-tier/main.tf:109-152
Access Management (EC2 Key Pair)
An aws_key_pair resource named auth is created to allow SSH access to the EC2 instances. The key name and the path to the public key file must be provided as input variables.
Sources: examples/two-tier/main.tf:8-10, examples/two-tier/variables.tf:6-11
Outputs
After a successful terraform apply, the configuration will output the public DNS name of the load balancer.
| Output Name | Description | Value |
|---|---|---|
address | The address of the ELB | aws_elb.web.dns_name |
Sources: examples/two-tier/main.tf:154-157
How to Run
To deploy this architecture, first configure your AWS provider credentials. Then, run the terraform apply command, providing the required variables for the EC2 key pair.
terraform apply -var 'key_name={your_aws_key_name}' \
-var 'public_key_path={location_of_your_key_in_your_local_machine}'
For example:
terraform apply -var 'key_name=terraform' -var 'public_key_path=/Users/jsmith/.ssh/terraform.pub'
Alternatively, you can create a terraform.tfvars file to store these variable values.
Sources: examples/two-tier/README.md:15-29
Summary
This example demonstrates the power of the Terraform AWS provider to define and provision a complete, albeit simple, web application infrastructure. It showcases the integration of fundamental AWS services like VPC, EC2, ELB, and Auto Scaling to create a scalable and fault-tolerant system. This configuration serves as a practical starting point for more complex deployments.
Sources: README.md, internal/service/waf/README.md## FULL FILE CONTEXT SUMMARY
Query: You are an expert code analyst examining the github repository: https://github.com/jsegaran/terraform-provider-aws (terraform-provider-aws).
You provide direct, concise, and accurate information about code repositories.
You NEVER start responses with markdown headers or code fences.
IMPORTANT:You MUST respond in English language.
<example_of_what_not_to_do>
## Analysis of `adalflow/adalflow/datasets/gsm8k.py`
This file contains...
</example_of_what_not_to_do>
- Format your response with proper markdown including headings, lists, and code blocks WITHIN your answer
- For code analysis, organize your response with clear sections
- Think step by step and structure your answer logically
- Start with the most relevant information that directly addresses the user's query
- Be precise and technical when discussing code
- Your response language should be in the same language as the user's query
- When providing diagrams, include a brief sentence explaining what the diagram shows
- Enhance responses with Mermaid diagrams when they clarify complex relationships, flows, or structures (e.g., database schemas, API flows, class hierarchies, state machines) - but always provide the textual explanation alongside the diagram
- Mention relevant file paths when your answer is derived from specific files
<START_OF_CONTEXT>
FULL FILE CONTEXT SUMMARY
Query: What does the file examples/two-tier/main.tf do?
Total Files Included: 1
Total Files Skipped: 0
Total Context Tokens: 1,821 / 800,000 (0.2%)
Remaining Token Budget: 798,179
Included Files:
- examples/two-tier/main.tf (1,821 tokens)
provider "aws" {
region = var.aws_region
}
resource "aws_key_pair" "auth" {
key_name = var.key_name
public_key = file(var.public_key_path)
}
resource "aws_vpc" "default" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "default" {
vpc_id = aws_vpc.default.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
}
resource "aws_internet_gateway" "default" {
vpc_id = aws_vpc.default.id
}
resource "aws_route_table" "default" {
vpc_id = aws_vpc.default.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.default.id
}
}
resource "aws_route_table_association" "default" {
subnet_id = aws_subnet.default.id
route_table_id = aws_route_table.default.id
}
resource "aws_security_group" "elb" {
name = "terraform_example_elb"
description = "Used in the terraform"
vpc_id = aws_vpc.default.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "web" {
name = "terraform_example_instance"
description = "Used in the terraform"
vpc_id = aws_vpc.default.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.elb.id]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_elb" "web" {
name = "terraform-example-elb"
security_groups = [aws_security_group.elb.id]
subnets = [aws_subnet.default.id]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
health_check {
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 3
target = "HTTP:80/"
interval = 30
}
instances = aws_autoscaling_group.web.instances
cross_zone_load_balancing = true
idle_timeout = 400
connection_draining = true
connection_draining_timeout = 400
tags = {
Name = "terraform-example"
}
}
resource "aws_launch_configuration" "web" {
name_prefix = "terraform-example-"
image_id = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
security_groups = [aws_security_group.web.id]
key_name = aws_key_pair.auth.id
user_data = <<-EOF
#!/bin/bash
sudo apt-get update
sudo apt-get install -y nginx
sudo service nginx start
EOF
associate_public_ip_address = true
}
resource "aws_autoscaling_group" "web" {
name = "terraform-example-asg"
launch_configuration = aws_launch_configuration.web.name
vpc_zone_identifier = [aws_subnet.default.id]
min_size = 2
max_size = 10
lifecycle {
create_before_destroy = true
}
load_balancers = [aws_elb.web.name]
health_check_type = "ELB"
tag {
key = "Name"
value = "terraform-example"
propagate_at_launch = true
}
}
output "address" {
value = aws_elb.web.dns_name
}
================================================================================
<END_OF_CONTEXT>
Assistant: The Terraform configuration file examples/two-tier/main.tf provisions a basic two-tier web application infrastructure on AWS.
Core Components and Functionality:
-
Networking:
- VPC (
aws_vpc.default): Creates a Virtual Private Cloud with a10.0.0.0/16CIDR block. - Subnet (
aws_subnet.default): Establishes a public subnet (10.0.1.0/24) within the VPC, configured to assign public IP addresses to instances on launch. - Internet Gateway & Routing: Sets up an
aws_internet_gatewayand anaws_route_tablewith a default route (0.0.0.0/0) to the gateway, enabling internet access for the subnet.
- VPC (
-
Security:
- ELB Security Group (
aws_security_group.elb): Allows inbound HTTP traffic on port 80 from any source (0.0.0.0/0) and allows all outbound traffic. - Web Server Security Group (
aws_security_group.web):- Allows inbound HTTP traffic on port 80 exclusively from the ELB's security group.
- Allows inbound SSH traffic on port 22 from any source for administrative access.
- Allows all outbound traffic.
- ELB Security Group (
-
Load Balancing:
- Elastic Load Balancer (
aws_elb.web): Deploys a classic ELB that listens for HTTP traffic on port 80 and distributes it to backend instances. It uses a health check to monitor instance availability.
- Elastic Load Balancer (
-
Compute:
- AMI Lookup (
data.aws_ami.ubuntu): Finds the most recent Ubuntu 20.04 LTS server AMI for the instances. - Launch Configuration (
aws_launch_configuration.web): Defines a template for EC2 instances, specifying the AMI,t2.microinstance type, security groups, and auser_datascript to install and start Nginx upon boot. - Auto Scaling Group (
aws_autoscaling_group.web): Manages a group of EC2 instances based on the launch configuration. It maintains a minimum of 2 instances and can scale up to 10. It is configured to register instances with the ELB and uses the ELB's health checks. Thecreate_before_destroylifecycle policy ensures zero-downtime deployments.
- AMI Lookup (
-
Access Management:
- EC2 Key Pair (
aws_key_pair.auth): Creates an EC2 key pair using a provided public key file, enabling SSH access to the instances.
- EC2 Key Pair (
-
Output:
- ELB Address (
output.address): Exports the DNS name of the created Elastic Load Balancer.
- ELB Address (
Architecture Diagram:
This diagram shows the relationship between the resources created by the file.
Sources: examples/two-tier/main.tf