Web Servers
Architecture
Deploy EC2 instances as production web servers with high availability:
- Application Load Balancer distributes traffic across instances
- Auto Scaling Group maintains desired capacity
- EBS volumes store application code and logs
- Security Groups control inbound HTTP/HTTPS traffic
- CloudWatch monitors instance and application health
┌─────────────────────────────────────────────────────────────┐
│ Internet │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────┐
│ Application Load │
│ Balancer │
└─────────────────────────┘
│ │
┌─────────┘ └─────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Web Server 1 │ │ Web Server 2 │
│ (EC2 Instance) │ │ (EC2 Instance) │
│ ┌──────────┐ │ │ ┌──────────┐ │
│ │ nginx │ │ │ │ nginx │ │
│ └──────────┘ │ │ └──────────┘ │
└──────────────────┘ └──────────────────┘
When to Use
EC2 web servers are ideal when you need:
- Custom web server configurations that go beyond managed services
- Specific software versions or custom-compiled binaries
- Persistent local storage for caching or session files
- Long-running connections like WebSockets
- Complex application stacks requiring multiple processes
- Legacy applications that cannot be containerized
Example Configuration
module "web_server" {
source = "registry.patterneddesigns.ca/patterneddesigns/ec2-instance/aws"
version = "1.5.0"
instance_name = "web-server"
instance_type = "t3.medium"
ami_id = data.aws_ami.amazon_linux.id
subnet_id = module.vpc.public_subnets[0]
security_group_ids = [aws_security_group.web.id]
key_name = aws_key_pair.admin.key_name
assign_public_ip = true
monitoring = true
user_data = <<-EOF
#!/bin/bash
yum update -y
amazon-linux-extras install nginx1 -y
systemctl start nginx
systemctl enable nginx
EOF
tags = {
Environment = "production"
Role = "web-server"
}
}
resource "aws_security_group" "web" {
name = "web-server-sg"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
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"]
}
}
Considerations
| Aspect | Consideration |
|---|---|
| Scaling | Use Auto Scaling Groups for horizontal scaling |
| Updates | Plan for rolling deployments or blue-green |
| SSL/TLS | Use ALB for SSL termination or certbot for direct SSL |
| Monitoring | Install CloudWatch agent for application metrics |
| Security | Harden OS, use IMDSv2, keep software updated |
Alternatives
Consider these alternatives for simpler deployments:
- ECS/Fargate - Containerized web applications
- Lambda + API Gateway - Serverless web APIs
- Elastic Beanstalk - Managed web application platform
- Lightsail - Simplified virtual servers