Divendres, gener 16, 2026
CLOUD & DEVOPS

Crear un balancejador de càrrega a AWS i afegir instàncies manualment

Muntar un balancejador de càrrega a AWS sembla trivial la primera vegada: un parell de clics a la consola, tries les subxarxes, el port 80/443 i llestos. El que no s’explica a la documentació és tot allò que pot fallar, els errors que et deixen instàncies “running” però sense rebre trànsit, o les decisions de seguretat que per comoditat es prenen malament i mesos després es paguen cares.

1. Tipus de balancejadors i elecció pràctica

AWS manté tres línies principals de load balancers:

  • Classic Load Balancer (CLB): encara es veu en comptes antics, però és una tecnologia obsoleta. No té les regles de capa 7 dels ALB, no suporta HTTP/2 i té limitacions a TLS. Només té sentit en infraestructures heretades.
  • Application Load Balancer (ALB): l’opció natural per a la majoria d’aplicacions web. Opera en capa 7, entén HTTP/S, permet regles per path, capçaleres, hostnames, suporta WebSockets, gRPC i redireccions. És més flexible per a projectes que canvien amb freqüència.
  • Network Load Balancer (NLB): opera en capa 4, gestiona tràfic TCP/UDP amb molt baixa latència i pot oferir IPs estàtiques. Útil quan el que es vol balancejar no són peticions HTTP sinó connexions persistents o protocols com SMTP, RDP o bases de dades.

A la pràctica, per a aplicacions web l ‘ALB és l’opció adequada. El NLB té sentit quan hi ha requisits d’ IP fixa o protocols diferents d’ HTTP. El CLB millor deixar-lo en el passat.

Decisió pràctica

L’error típic és triar un NLB perquè sembla “més ràpid” i després descobrir que no suporta redireccions HTTP → HTTPS o regles per path. Al revés també passa: fer servir un ALB per a trànsit de base de dades, cosa que porta a comportaments estranys i pèrdua de rendiment.

2. Disseny de xarxa i dependències prèvies

Un ALB no és un recurs aïllat. Necessita estar en una VPC amb subxarxes en almenys dues zones de disponibilitat. Aquest requisit pot sorprendre els qui munten entorns petits.

2.1 Subxarxes

  • Regla fixa d’AWS: no es pot crear un ALB amb menys de dues subxarxes en diferents AZ.
  • Truc comú: si només tens instàncies en una AZ, igualment necessites definir una altra subxarxa en una altra AZ (tot i que buida) només per complir el requisit.
  • Etiqueta les teves subxarxes. En una VPC gran, quan veus “subnet-123abc” és fàcil registrar l’equivocada. Noms com public-a, public-b, private-a ajuden més que qualsevol comentari en un diagrama.

2.2 Grups de seguretat

L’ ALB necessita el seu propi SG.

  • Entrada: normalment 80 i 443 des de qualsevol origen (0.0.0.0/0 e ::/0).
  • Sortida: pot quedar oberta, ja que el normal és que el trànsit es limiti d’ entrada.

El perillós és deixar que les instàncies acceptin trànsit des de qualsevol origen. El correcte és:

  • SG de l’ ALB obert a Internet.
  • SG d’ instàncies acceptant trànsit només des del SG de l’ ALB.

Això evita accessos directes saltant-se el balancejador. Es configura amb regles com:

# Exemple amb AWS CLI: permetre trànsit des del SG de l'ALB al SG de la instància
aws ec2 authorize-security-group-ingress \
  --group-id sg-instancies \
  --protocol tcp \
  --port 8080 \
  --source-group sg-alb

3. Configuració de listeners i certificats

3.1 Listeners bàsics

Un ALB necessita almenys un listener. El més habitual és:

  • Listener 80 (HTTP): respon amb redirect 301 a 443.
  • Listener 443 (HTTPS): acaba TLS i reenvia al target group.

Això garanteix que ningú es quedi a HTTP sense xifrar.

3.2 Certificats en ACM

  • Han d’estar a la mateixa regió que l’ALB. No es poden reutilitzar certificats importats en us-east-1 per a un ALB en eu-west-1.
  • Si fas servir diversos dominis, pots:
    • Crear un sol certificat amb SAN que cobreixi tots.
    • O associar diversos certificats al listener de 443.

Errors freqüents:

  • Importar un certificat a la regió equivocada.
  • Registrar una wildcard que no cobreix subdominis inesperats.

3.3 Exemple CLI

Crear listener HTTP → HTTPS:

aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:alb/my-alb/... \
  --protocol HTTP \
  --port 80 \
  --default-actions Type=redirect,RedirectConfig='{"Protocol":"HTTPS","Port":"443","StatusCode":"HTTP_301"}'

Listener HTTPS con certificado:

aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:alb/my-alb/... \
  --protocol HTTPS \
  --port 443 \
  --certificates CertificateArn=arn:aws:acm:region:account:certificate/xxxx \
  --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:...:targetgroup/my-targets/xxxx

4. Target Groups: el veritable cor

L’ALB només enruta trànsit. Les instàncies es gestionen des dels Target Groups. Aquí és on apareixen la majoria de problemes.

4.1 Health checks

Els health checks decideixen quines instàncies estan llestes per rebre trànsit. Errors comuns:

  • Deixar el path /. Això fa que l’ALB avaluï el home de l’aplicació, que sol ser pesada, dependent de base de dades o caché. Millor un endpoint lleuger com /health que en retorni 200 sense lògica complexa.
  • No adaptar intervals. Configuracions massa agressives (interval=10, unhealthy_threshold=2) provoquen que un pic de latència marqui instàncies com “unhealthy” encara que estiguin bé.
  • Fer servir HTTP en apps que només responen en HTTPS.

Configuració típica de health check:

aws elbv2 modify-target-group \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/my-targets/... \
  --health-check-protocol HTTP \
  --health-check-path /health \
  --health-check-interval-seconds 30 \
  --health-check-timeout-seconds 5 \
  --healthy-threshold-count 3 \
  --unhealthy-threshold-count 2

4.2 Sessions enganxoses

L’ALB permet stickiness amb cookies.

  • S’ ha d’ activar només si no hi ha un mecanisme de sessió compartit.
  • En entorns moderns se solen externalitzar sessions (Redis, DynamoDB). En aquest cas, activar stickiness degrada el balanceig real.

4.3 Registre manual d’ instàncies

Registrar instàncies en el target group:

aws elbv2 register-targets \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/my-targets/... \
  --targets Id=i-0123456789abcdef0,Port=8080 Id=i-0abcdef1234567890,Port=8080

Comprovar estat:

aws elbv2 describe-target-health \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/my-targets/...

Aquí és on molts se sorprenen: una instància “running” a EC2 pot figurar com “unhealthy” al Target Group i mai rebrà trànsit.

5. Afegir i retirar instàncies manualment

Quan no fas servir Auto Scaling, els target groups es gestionen a mà. Això implica registrar instàncies noves, comprovar que passin health checks i retirar les que s’han d’apagar o reiniciar.

5.1 Afegir instàncies

El flux és:

  • Llançar la nova instància a EC2.
  • Verificar que l’ aplicació arrenca i respon localment al port esperat.
  • Registrar la instància al target group.
  • Esperar que canviï a estat healthy (segons health checks).

Mai registris una instància sense provar-la abans. És fàcil assumir que l’AMI ja està ben configurada i després descobrir que faltava un secret, un volum muntat o una variable d’entorn. L’ALB marcarà la instància com a “unhealthy”, però mentrestant pots tenir clients rebent errors 502 o 504.

5.2 Retirar instàncies (draining)

El paràmetre delay controla quant temps manté l’ALB una instància en estat “draining” abans de deixar d’enviar-li trànsit. Per defecte són 300 segons.

  • Si la teva aplicació atén peticions ràpides (APIs típiques), pots baixar-lo a 30–60 segons.
  • Si serveix descàrregues grans o connexions llargues, 300 segons o més és raonable.

Exemple CLI:

aws elbv2 modify-target-group-attributes \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/my-targets/... \
  --attributes Key=deregistration_delay.timeout_seconds,Value=60

Quan vols apagar una instància:

  • Primer la desregistres del target group.
  • Esperes que acabi el draining.
  • Després l’atures o l’acabes.

Saltar-se aquest ordre implica tallar connexions a clients que encara no havien acabat la seva petició.

6. Configuracions crítiques

6.1 Temps d’espera d’inactivitat

L’ALB té un idle_timeout de 60 segons per defecte. Si la teva aplicació maneja peticions llargues (per exemple, streaming de vídeo o consultes SQL molt pesades servides a través d’HTTP), els clients poden veure desconnexions inesperades.

Pots canviar-ho:

aws elbv2 modify-load-balancer-attributes \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:alb/my-alb/... \
  --attributes Key=idle_timeout.timeout_seconds,Value=300

6.2 Proxy Protocol i capçaleres

Si necessites la IP real del client, l’ALB afegeix la capçalera X-Forwarded-For. És un problema clàssic: l’aplicació veu només la IP interna del balancejador i sembla que tot el trànsit ve del mateix lloc.

  • Solució: configurar la teva aplicació o revers proxy per llegir X-Forwarded-For.
  • No reinventis la roda intentant extreure la IP d’una altra banda.

6.3 Seguretat d’ instàncies

És habitual que les instàncies estiguin en subxarxes privades i no tinguin IP pública. En aquest cas:

  • SG de l’ ALB obert a Internet en 443.
  • SG d’ instàncies acceptant només del SG de l’ ALB.
  • Accés SSH només a través d’ un bastion host o Session Manager.

El que convé evitar: instàncies en subxarxa pública amb port 22 obert al món. Encara que no hi hagi usuaris reals, aquest patró sol convertir-se en un vector d’atac.

7. Logs i mètriques

Un balancejador que no es monitoritza és una caixa negra. AWS ofereix dos mecanismes principals: Access Logs i CloudWatch Metrics.

7.1 Access Logs

  • S’ emmagatzemen en S3.
  • Inclouen detalls de cada petició: IP, latència de l’ ALB, latència de l’ aplicació, codis de resposta, mida de payload.
  • Útils per depurar problemes intermitents: els 502 venen de l’ALB o de les instàncies?

Configuració CLI:

aws elbv2 modify-load-balancer-attributes \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:alb/my-alb/... \
  --attributes Key=access_logs.s3.enabled,Value=true \
               Key=access_logs.s3.bucket,Value=my-logs-bucket \
               Key=access_logs.s3.prefix,Value=alb-logs

Compte amb els costos: el volum de logs pot ser gran. Millor aplicar regles d’expiració en S3 perquè no creixin sense límit.

7.2 Mètriques de CloudWatch

L’ ALB exporta mètriques bàsiques:

  • RequestCount
  • HTTPCode_Target_2XX_Count, HTTPCode_Target_4XX_Count, HTTPCode_Target_5XX_Count
  • TargetResponseTime

El recomanable és configurar alarmes a CloudWatch o integrar-lo amb Prometheus via CloudWatch exporter. Una mètrica que dona molt valor és la distribució de latències (p95, p99), ja que reflecteix si hi ha saturació en les instàncies abans que explotin els errors.

8. Errors típics en producció

8.1 Health check mal configurat

Una de les fallades més comunes: health check contra / en lloc d’un endpoint lleuger. Resultat: durant un pic de càrrega, les instàncies triguen a respondre i l’ALB les marca com a “unhealthy”, provocant una cascada d’errors.

8.2 SG mal enllaçats

Instàncies exposades directament a Internet perquè el SG acceptava trànsit des de 0.0.0.0/0. Amb això qualsevol pot saltar-se el balancejador, veure banners de l’aplicació o explotar vulnerabilitats que creies ocultes.

8.3 Idle timeout massa baix

Els clients de mòbil són els que més ho pateixen: connexions TLS tallades just quan estan en xarxes inestables. Això es tradueix en queixes d’usuaris sense que el backend hagi fallat en realitat.

8.4 No ajustar deregistration delay

Apagar instàncies a les braves sense passar per draining. En el millor dels casos produeix errors intermitents difícils de rastrejar. En el pitjor, deixa clients corporatius amb descàrregues truncades.

8.5 Confondre NLB amb ALB

Quan es necessita HTTP/S amb redireccions o regles, el NLB no serveix.  Algú tria NLB perquè “necessitem IP fixa” i després perd setmanes implementant manualment el que un ALB feia de sèrie.

9. Configuració amb Terraform

Terraform és el més pràctic quan vols que el teu balancejador no sigui un “clic en consola” oblidat. Reprodueix entorns, documenta les decisions i redueix errors de configuració manual.

Un exemple complet i comentat:

provider "aws" {
  region = "us-east-1"
}
 
# Security Group per al ALB
resource "aws_security_group" "alb_sg" {
  name        = "alb-sg"
  description = "Permet HTTP i HTTPS des d' Internet"
  vpc_id      = aws_vpc.main.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"]

  }
}
 
# Security Group per a instàncies
resource "aws_security_group" "instances_sg" {
  name        = "instances-sg"
  description = "Permet tràfic només des de l'ALB"
  vpc_id      = aws_vpc.main.id
 
  ingress {
    from_port       = 8080
    to_port         = 8080
    protocol        = "tcp"
    security_groups = [aws_security_group.alb_sg.id]
  }
 
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
 
# Load Balancer
resource "aws_lb" "main" {
  name               = "my-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets            = aws_subnet.public[*].id
}
 
# Target Group
resource "aws_lb_target_group" "app" {
  name     = "app-tg"
  port     = 8080
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id

  health_check {
    path                = "/health"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 3
    unhealthy_threshold = 3
    matcher             = "200-299"
  }
}
 
# Listener HTTP -> redirect a HTTPS
resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.main.arn
  port              = "80"
  protocol          = "HTTP"
 
  default_action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}
 
# Listener HTTPS
resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.main.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-2016-08"
  certificate_arn   = aws_acm_certificate.main.arn
 
  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}
 
# Registre d' instàncies manuals
resource "aws_lb_target_group_attachment" "app_instances" {
  count            = length(var.instance_ids)
  target_group_arn = aws_lb_target_group.app.arn
  target_id        = var.instance_ids[count.index]
  port             = 8080
}

Punts importants:

  • aws_lb_target_group_attachment és el que et permet registrar instàncies manualment sense Auto Scaling. N’hi ha prou de passar-li els IDs en var.instance_ids.
  • Configura sempre un health check dedicat, no /.
  • TLS amb ACM es gestiona directament amb aws_acm_certificate.

Terraform et permet versionar canvis en el deregistration delay, idle timeout i polítiques de logs. Una cosa que a mà en consola s’oblida fàcilment.

10. Configuració amb AWS CLI

Quan l’entorn és petit o vols scripts ad-hoc, la CLI és suficient. Exemple:

Crear el ALB

aws elbv2 create-load-balancer \
  --name my-alb \
  --subnets subnet-123 subnet-456 \
  --security-groups sg-123456 \
  --scheme internet-facing \
  --type application

Crear target group

aws elbv2 create-target-group \
  --name app-tg \
  --protocol HTTP \
  --port 8080 \
  --vpc-id vpc-123456 \
  --health-check-path "/health"

Crear listener HTTPS

aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:alb/my-alb/... \
  --protocol HTTPS \
  --port 443 \
  --certificates CertificateArn=arn:aws:acm:...:certificate/... \
  --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:...:targetgroup/app-tg/...

Registrar instàncies

aws elbv2 register-targets \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/app-tg/... \
  --targets Id=i-123456 Id=i-789012

Deregistrar instància

aws elbv2 deregister-targets \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/app-tg/... \
  --targets Id=i-123456

Amb això pots crear scripts senzills per ciclar instàncies (drenar, actualitzar AMI, tornar a registrar). En entorns amb poques màquines pot ser suficient sense muntar Auto Scaling.

11. Costos i decisions que es paguen a la factura

Un ALB no és barat comparat amb un NLB o un clàssic ELB. Els costos típics:

  • Càrrec per hora del balancejador.
  • Càrrec per LCU (Load Balancer Capacity Unit): connexions actives, noves connexions, bytes processats i regles avaluades.

Detalls pràctics:

  • Cada regla addicional en listeners consumeix LCUs. Si abuses de regles complexes de host/path matching, la factura creix.
  • Mantenir un ALB per a proves pot ser malbaratar recursos: costa el mateix que en producció. De vegades té sentit un NLB intern o directament apuntar a instàncies si és temporal.
  • Els logs en S3 es disparen en entorns de molt trànsit. Configura Lifecycle Rules per purgar després de 30 dies o moure a Glacier.

12. Llista de verificació final

Abans de donar per tancat un desplegament d’ ALB amb instàncies manuals, revisa:

  • Health check contra un endpoint lleuger i confiable.
  • Deregistration delay ajustat a la naturalesa del tràfic.
  • Idle timeout (60s no sempre serveix).
  • TLS gestionat amb ACM i renovacions automàtiques.
  • Access logs activats amb caducitat en S3.
  • CloudWatch Alarms sobre TargetResponseTime i HTTPCode_Target_5XX_Count.
  • SG de l’ALB obert només en 80/443, SG d’instàncies només acceptant de l’ALB.
  • Terraform/CLI com a font de veritat, no només consola.
  • Script per registrar/deregistrar instàncies de forma ordenada.
  • Revisió de costos i eliminació de balancejadors “orfes” de proves.

Conclusió

Amb això es completa una entrada que cobreix tant el desplegament des de zero com l’operació diària, els problemes que solen repetir-se i exemples pràctics amb Terraform i CLI.

La combinació d’ALB + instàncies manuals no és la més “cloud-native”, però continua sent comuna en migracions, entorns legacy o desplegaments controlats. Fer-ho bé significa entendre els detalls que AWS dona per supòsits i que es converteixen en incidents quan es passen per alt.

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *