Saltar al contenido principal

Arquitectura Web en AWS

Introducción​

Desplegar un servicio web en AWS requiere combinar varios servicios: VPC, EC2, Load Balancer y una buena estrategia de seguridad. Esta sección cubre los patrones de arquitectura más comunes.

Patrón 1: Arquitectura Simple​

Una Instancia EC2 Pública​

┌─────────────────────────────────────────────────────────────┐
│ ARQUITECTURA SIMPLE (dev/test) │
├─────────────────────────────────────────────────────────────┤
│ │
│ INTERNET │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ IGW │ │
│ └────┬─────┘ │
│ │ │
│ ┌─────────────────────┼─────────────────────┐ │
│ │ VPC │ │ │
│ │ │ │ │
│ │ ┌─────────────────▼───────────────────┐ │ │
│ │ │ SUBNET PUBLIC │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ EC2 │ │ │ │
│ │ │ │ Web Server │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ IP: 52.1.2.3 │ │ │ │
│ │ │ │ SG: web-server │ │ │ │
│ │ │ └─────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ Ventajas: │
│ ✅ Fácil de desplegar │
│ ✅ Costo mínimo │
│ ✅ Ideal para dev/test │
│ │
│ Desventajas: │
│ ❌ Sin alta disponibilidad │
│ ❌ Un solo punto de falla │
│ ❌ No escalable │
│ │
└─────────────────────────────────────────────────────────────┘

Configuración​

# 1. Crear un Security Group para la web
aws ec2 create-security-group \
--group-name sg-web-simple \
--description "Web server SG" \
--vpc-id vpc-xxx

# 2. Permitir HTTP y HTTPS
aws ec2 authorize-security-group-ingress \
--group-id sg-xxx \
--protocol tcp --port 80 --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress \
--group-id sg-xxx \
--protocol tcp --port 443 --cidr 0.0.0.0/0

# 3. Lanzar la instancia
aws ec2 run-instances \
--image-id ami-xxx \
--instance-type t3.micro \
--subnet-id subnet-public \
--security-group-ids sg-xxx \
--associate-public-ip-address \
--user-data '#!/bin/bash
yum install -y httpd
systemctl start httpd
echo "Hello World" > /var/www/html/index.html'

Patrón 2: Arquitectura con Load Balancer​

ALB + Instancias Privadas​

┌─────────────────────────────────────────────────────────────────────────┐
│ ARQUITECTURA CON ALB (producción) │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ INTERNET │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ IGW │ │
│ └────┬─────┘ │
│ │ │
│ ┌────────────────────────────┼────────────────────────────────┐ │
│ │ VPC │ (10.0.0.0/16) │ │
│ │ │ │ │
│ │ ┌────────────────────────┴────────────────────────────┐ │ │
│ │ │ SUBNETS PÚBLICOS │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ Public 1a │ │ Public 1b │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ ┌───────┐ │ │ ┌───────┐ │ │ │ │
│ │ │ │ │ ALB │◄─┼──────────────┼──│ ALB │ │ │ │ │
│ │ │ │ │ node │ │ │ │ node │ │ │ │ │
│ │ │ │ └───┬───┘ │ │ └───┬───┘ │ │ │ │
│ │ │ └──────┼──────┘ └──────┼──────┘ │ │ │
│ │ │ │ │ │ │ │
│ │ └─────────┼────────────────────────────┼───────────────┘ │ │
│ │ │ │ │ │
│ │ ┌─────────┼────────────────────────────┼───────────────┐ │ │
│ │ │ │ SUBNETS PRIVADOS │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ ┌──────▼──────┐ ┌──────▼──────┐ │ │ │
│ │ │ │ Private 1a │ │ Private 1b │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │
│ │ │ │ │ EC2 │ │ │ │ EC2 │ │ │ │ │
│ │ │ │ │ Web 1 │ │ │ │ Web 2 │ │ │ │ │
│ │ │ │ └─────────┘ │ │ └─────────┘ │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ Ventajas: │
│ ✅ Alta disponibilidad (Multi-AZ) │
│ ✅ Escalable (agregar instancias) │
│ ✅ Terminación SSL a nivel de ALB │
│ ✅ Servidores web protegidos (subnet privado) │
│ │
└─────────────────────────────────────────────────────────────────────────┘

Tipos de Load Balancers AWS​

TipoUsoCapa OSIProtocolos
ALBAplicaciones HTTP/HTTPSCapa 7HTTP, HTTPS, gRPC
NLBUltra rendimientoCapa 4TCP, UDP, TLS
CLBLegacyCapa 4/7TCP, SSL, HTTP, HTTPS
GWLBAppliances de redCapa 3IP

Configuración ALB​

# 1. Crear el Target Group
aws elbv2 create-target-group \
--name tg-web-servers \
--protocol HTTP \
--port 80 \
--vpc-id vpc-xxx \
--health-check-path /health \
--health-check-interval-seconds 30

# 2. Crear el Application Load Balancer
aws elbv2 create-load-balancer \
--name alb-web \
--subnets subnet-public-1a subnet-public-1b \
--security-groups sg-alb \
--scheme internet-facing \
--type application

# 3. Crear el Listener
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:...:alb-web \
--protocol HTTP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:...:tg-web-servers

# 4. Registrar las instancias
aws elbv2 register-targets \
--target-group-arn arn:aws:...:tg-web-servers \
--targets Id=i-web1 Id=i-web2

Patrón 3: Arquitectura 3-Tiers​

Web + App + Base de Datos​

┌─────────────────────────────────────────────────────────────────────────┐
│ ARQUITECTURA 3-TIERS │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ INTERNET │
│ │ │
│ ┌──────▼──────┐ │
│ │ IGW │ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────────────────────────────┼──────────────────────────────┐ │
│ │ VPC │ │ │
│ │ │ │ │
│ │ ╔══════════════════════════╧════════════════════════════╗ │ │
│ │ ║ TIER 1 : PRESENTACIÓN ║ │ │
│ │ ║ (Subnet Público) ║ │ │
│ │ ║ ║ │ │
│ │ ║ ┌─────────────────────────┐ ║ │ │
│ │ ║ │ Application Load │ ║ │ │
│ │ ║ │ Balancer (ALB) │ ║ │ │
│ │ ║ └───────────┬─────────────┘ ║ │ │
│ │ ╚═══════════════════════╪═══════════════════════════════╝ │ │
│ │ │ │ │
│ │ ╔═══════════════════════╪═══════════════════════════════╗ │ │
│ │ ║ TIER 2 : APLICACIÓN ║ │ │
│ │ ║ (Subnet Privado App) ║ │ │
│ │ ║ │ ║ │ │
│ │ ║ ┌────────────────────┼────────────────────┐ ║ │ │
│ │ ║ │ │ │ ║ │ │
│ │ ║ ┌───▼───┐ ┌─────▼─────┐ ┌─────▼───┐ ║ │ │
│ │ ║ │ EC2 │ │ EC2 │ │ EC2 │ ║ │ │
│ │ ║ │ App 1 │ │ App 2 │ │ App 3 │ ║ │ │
│ │ ║ └───┬───┘ └─────┬─────┘ └────┬────┘ ║ │ │
│ │ ║ │ │ │ ║ │ │
│ │ ╚══════╪════════════════════╪═══════════════════╪═══════╝ │ │
│ │ │ │ │ │ │
│ │ ╔══════╪════════════════════╪═══════════════════╪═══════╗ │ │
│ │ ║ │ TIER 3 : DATOS │ │ ║ │ │
│ │ ║ │ (Subnet Privado DB) │ ║ │ │
│ │ ║ │ │ │ ║ │ │
│ │ ║ └────────────────────┼───────────────────┘ ║ │ │
│ │ ║ │ ║ │ │
│ │ ║ ┌──────▼──────┐ ║ │ │
│ │ ║ │ RDS │ ║ │ │
│ │ ║ │ MySQL │ ║ │ │
│ │ ║ │ Multi-AZ │ ║ │ │
│ │ ║ └─────────────┘ ║ │ │
│ │ ║ ║ │ │
│ │ ╚════════════════════════════════════════════════════════╝ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

Security Groups para 3-Tiers​

┌─────────────────────────────────────────────────────────────┐
│ SECURITY GROUPS 3-TIERS │
├─────────────────────────────────────────────────────────────┤
│ │
│ sg-alb (Load Balancer) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Inbound: HTTP/443 from 0.0.0.0/0 │ │
│ │ Outbound: HTTP/80 to sg-app │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ sg-app (Application Servers) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Inbound: HTTP/80 from sg-alb │ │
│ │ Inbound: SSH/22 from sg-bastion │ │
│ │ Outbound: MySQL/3306 to sg-db │ │
│ │ Outbound: HTTPS/443 to 0.0.0.0/0 (APIs externas) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ sg-db (Database) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Inbound: MySQL/3306 from sg-app │ │
│ │ Outbound: Ninguno (o mínimo) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Principio: Cada tier acepta SOLO el tráfico del tier │
│ anterior │
│ │
└─────────────────────────────────────────────────────────────┘

Health Checks​

Configuración Health Check ALB​

┌─────────────────────────────────────────────────────────────┐
│ HEALTH CHECKS ALB │
├─────────────────────────────────────────────────────────────┤
│ │
│ Parámetros importantes: │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Protocol : HTTP │ │
│ │ Path : /health o /api/health │ │
│ │ Port : traffic-port (80) │ │
│ │ Healthy threshold : 2 (éxitos consecutivos) │ │
│ │ Unhealthy threshold : 3 (fallos consecutivos) │ │
│ │ Timeout : 5 seconds │ │
│ │ Interval : 30 seconds │ │
│ │ Success codes : 200-299 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Endpoint /health típico: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ HTTP 200 OK │ │
│ │ { │ │
│ │ "status": "healthy", │ │
│ │ "database": "connected", │ │
│ │ "cache": "connected" │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

DNS con Route 53​

┌─────────────────────────────────────────────────────────────┐
│ ROUTE 53 + ALB │
├─────────────────────────────────────────────────────────────┤
│ │
│ Usuario escribe: www.monsite.com │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Route 53 │ │
│ │ DNS │ │
│ └──────┬───────┘ │
│ │ │
│ │ Alias Record │
│ │ www.monsite.com │
│ │ → alb-web-xxx.elb.amazonaws.com│
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ ALB │ │
│ └──────────────┘ │
│ │
│ Tipos de registros: │
│ • A (Alias): Apunta a recurso AWS (ALB, CF, S3) │
│ • CNAME : Apunta a otro nombre de dominio │
│ │
│ Ventaja Alias: │
│ ✅ Gratis para consultas a recursos AWS │
│ ✅ Responde con las IPs directamente │
│ │
└─────────────────────────────────────────────────────────────┘

Resumen de los Patrones​

PatrónComplejidadCostoHACaso de uso
EC2 Simple⭐$❌Dev/Test
ALB + EC2⭐⭐$$✅Producción simple
3-Tiers⭐⭐⭐$$$✅✅Producción
Microservicios⭐⭐⭐⭐$$$$✅✅✅Gran escala

Próxima sección: Lab: Publicación Web