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

AspectConsideration
ScalingUse Auto Scaling Groups for horizontal scaling
UpdatesPlan for rolling deployments or blue-green
SSL/TLSUse ALB for SSL termination or certbot for direct SSL
MonitoringInstall CloudWatch agent for application metrics
SecurityHarden 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