Mantener la capacidad con un grupo Auto Scaling

AWSBeginner
Practicar Ahora

Introducción

Un balanceador evita aplicaciones defectuosas, pero no crea servidores de sustitución. Crearás una plantilla y un grupo Auto Scaling que mantiene dos instancias. Provocarás un fallo y verificarás que una nueva instancia sirve solicitudes realmente.

Debes conocer EC2 User Data, grupos de destino ALB y comprobaciones de aplicaciones. Este entorno nuevo proporciona red, imagen, par de claves y un grupo de destino vacío con listener HTTP. No existe una flota previa. La CLI y los archivos de conexión se preparan independientemente de otros laboratorios.

Relación con certificaciones

Este laboratorio ofrece práctica introductoria para los siguientes temas.

Crear la plantilla de lanzamiento

Definirás la configuración que Auto Scaling utiliza al iniciar cada servidor.

Entra en el directorio y carga las variables de red preparadas:

cd /home/labex/project
source launch.env

Una plantilla de lanzamiento guarda AMI, tipo, grupos de seguridad y configuración inicial. Inspecciona el archivo proporcionado:

cat launch-template.json
cat application-user-data.sh

El JSON selecciona la AMI preparada, t3.micro, report-key y el grupo de seguridad de la aplicación. UserData contiene el script mostrado por separado, codificado en base64. Este establece el mensaje Application ready y healthy en true. Cada lanzamiento debe aplicar esa configuración para que el sustituto esté listo; cambiar un servidor antiguo no cambia la plantilla.

Crea la plantilla. file:// indica que la CLI debe leer el valor del parámetro desde el JSON:

LT_ID=$(aws ec2 \
  create-launch-template \
  --launch-template-name application-template \
  --launch-template-data file://launch-template.json \
  --query 'LaunchTemplate.LaunchTemplateId' \
  --output text)

Las plantillas tienen versiones numeradas. Inspecciona la versión 1, seleccionada explícitamente por el grupo:

aws ec2 \
  describe-launch-template-versions \
  --launch-template-id "$LT_ID" \
  --versions 1 \
  --query 'LaunchTemplateVersions[].{Version:VersionNumber,AMI:LaunchTemplateData.ImageId,Type:LaunchTemplateData.InstanceType,Key:LaunchTemplateData.KeyName,Groups:LaunchTemplateData.SecurityGroupIds}'

Crear una plantilla no inicia instancias. Abre AWS View: existen el ALB y el grupo de destino, pero todavía no hay destinos registrados.

Iniciar y conectar la flota

Crearás un grupo Auto Scaling y conectarás sus instancias reales al ALB proporcionado.

Un grupo Auto Scaling mantiene el número deseado dentro del mínimo y máximo. La capacidad deseada es un número de instancias, no una medida del rendimiento. Mínimo 2, deseado 2 y máximo 3 permiten comenzar con dos servidores y añadir otro.

Obtén el ARN del grupo de destino y el nombre DNS del balanceador:

TG_ARN=$(aws elbv2 \
  describe-target-groups \
  --names application-targets \
  --query 'TargetGroups[0].TargetGroupArn' \
  --output text)

LB_DNS=$(aws elbv2 \
  describe-load-balancers \
  --names application-alb \
  --query 'LoadBalancers[0].DNSName' \
  --output text)

Crea el grupo con la versión 1 y ambas subredes. --target-group-arns registra automáticamente las instancias en ALB. --health-check-type ELB incluye el estado del balanceador en las decisiones de sustitución; las comprobaciones EC2 no detectan todos los fallos de aplicación. El período de gracia permite iniciar la aplicación antes de que su estado provoque sustitución. Usamos 30 segundos; en producción debe corresponder al tiempo de inicio:

aws autoscaling \
  create-auto-scaling-group \
  --auto-scaling-group-name application-fleet \
  --launch-template "LaunchTemplateId=$LT_ID,Version=1" \
  --min-size 2 \
  --max-size 3 \
  --desired-capacity 2 \
  --vpc-zone-identifier "$SUBNET_ID,$SECOND_SUBNET_ID" \
  --target-group-arns "$TG_ARN" \
  --health-check-type ELB \
  --health-check-grace-period 30

Inspecciona el grupo y sus IDs:

aws autoscaling \
  describe-auto-scaling-groups \
  --auto-scaling-group-names application-fleet \
  --query 'AutoScalingGroups[].{Min:MinSize,Desired:DesiredCapacity,Max:MaxSize,HealthCheck:HealthCheckType,Grace:HealthCheckGracePeriod,Instances:Instances[].InstanceId}'

Espera a que las aplicaciones estén listas e inspecciona los destinos:

aws elbv2 \
  wait target-in-service \
  --target-group-arn "$TG_ARN"

aws elbv2 \
  describe-target-health \
  --target-group-arn "$TG_ARN" \
  --query 'TargetHealthDescriptions[].{Instance:Target.Id,Health:TargetHealth.State}' \
  --output table

Espera dos IDs saludables. Envía seis solicitudes y compara los IDs devueltos con las instancias del grupo:

for request in 1 2 3 4 5 6; do
  curl --config client.conf -sS "http://$LB_DNS/health"
  echo
done

Abre AWS View. Confirma capacidad 2, dos destinos saludables y respuestas reales 200 de ambos IDs con Send request. Las etiquetas de subred y zona muestran configuración; aquí no se mide resiliencia física entre zonas.

Observar la sustitución automática

Provocarás un fallo y dejarás que el grupo sustituya la instancia en lugar de repararla manualmente.

Selecciona una instancia actual y obtén su dirección pública para SSH:

OLD_ID=$(aws autoscaling \
  describe-auto-scaling-groups \
  --auto-scaling-group-names application-fleet \
  --query 'AutoScalingGroups[0].Instances[0].InstanceId' \
  --output text)

OLD_IP=$(aws ec2 \
  describe-instances \
  --instance-ids "$OLD_ID" \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text)

Cambia únicamente healthy para devolver 503. Como antes, el archivo JSON temporal evita sobrescribir el original mientras se lee:

ssh -F ssh_config "ubuntu@$OLD_IP" \
  'sudo jq ".healthy = false" /etc/report-app/config.json > /tmp/report-config.json && sudo install -m 644 /tmp/report-config.json /etc/report-app/config.json'

ssh -F ssh_config "ubuntu@$OLD_IP" \
  'curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8081/health'

Espera 503. La aplicación falla mientras la instancia sigue ejecutándose. ALB detecta el fallo; tras el período de gracia, el grupo sustituye la instancia para restaurar su capacidad. La misma plantilla inicia el sustituto con una configuración saludable.

Mantén AWS View abierto para observar IDs y estados. El estado no saludable puede ser breve porque la sustitución sigue a la detección. El nuevo destino puede aparecer como initial. No repares la aplicación ni ejecutes otro run-instances.

Espera la terminación de la instancia antigua y el estado saludable del grupo de destino:

aws ec2 \
  wait instance-terminated \
  --instance-ids "$OLD_ID"

aws elbv2 \
  wait target-in-service \
  --target-group-arn "$TG_ARN"

Inspecciona la instancia antigua y el grupo actual:

aws ec2 \
  describe-instances \
  --instance-ids "$OLD_ID" \
  --query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name}'

aws autoscaling \
  describe-auto-scaling-groups \
  --auto-scaling-group-names application-fleet \
  --query 'AutoScalingGroups[].{Desired:DesiredCapacity,Instances:Instances[].InstanceId}'

El ID antiguo debe estar terminated. La capacidad sigue en 2 y aparece un nuevo ID. La sustitución es un servidor recién inicializado; los cambios internos del antiguo no se conservan automáticamente.

Envía de nuevo seis solicitudes:

for request in 1 2 3 4 5 6; do
  curl --config client.conf -sS "http://$LB_DNS/health"
  echo
done

Busca ambos IDs actuales, incluido el nuevo, sin el antiguo. En AWS View, confirma dos destinos saludables y usa Send request para observar al sustituto responder. Contar recursos no demuestra que la aplicación funciona.

Instancia de sustitución respondiendo

Ejemplo: la capacidad permanece en dos y la nueva instancia devuelve HTTP 200. Tus IDs serán distintos.

Eliminar la flota y la plantilla

Eliminarás tu grupo, instancias y plantilla, conservando el ALB y la red proporcionados.

Elimina el grupo con --force-delete para terminar sus instancias incluso con mínimo 2. Eliminar solamente la plantilla no detiene instancias:

aws autoscaling \
  delete-auto-scaling-group \
  --auto-scaling-group-name application-fleet \
  --force-delete

aws ec2 \
  wait instance-terminated \
  --filters "Name=tag:aws:autoscaling:groupName,Values=application-fleet"

aws ec2 \
  delete-launch-template \
  --launch-template-id "$LT_ID"

El waiter selecciona las instancias mediante la etiqueta automática de Auto Scaling, incluida la instancia sustituida, y espera que todas terminen. Comprueba la ausencia del grupo, las plantillas y los destinos:

aws autoscaling \
  describe-auto-scaling-groups \
  --auto-scaling-group-names application-fleet \
  --query 'AutoScalingGroups[].AutoScalingGroupName'

aws ec2 \
  describe-launch-templates \
  --query 'LaunchTemplates[].LaunchTemplateName'

aws elbv2 \
  describe-target-health \
  --target-group-arn "$TG_ARN" \
  --query 'TargetHealthDescriptions[].Target.Id'

Las tres listas deben ser []. La baja de destinos puede tardar; espera y repite la última consulta si es necesario. AWS View conserva ALB y grupo de destino, sin flota ni destinos registrados. Conserva la red, AMI y claves proporcionadas.

Resumen

Creaste una plantilla con versiones y un grupo que mantiene dos servidores reales. Incluiste comprobaciones ALB, provocaste un fallo y verificaste solicitudes desde un nuevo ID. Después eliminaste grupo, instancias y plantilla, conservando balanceador y red.

El siguiente laboratorio modifica la capacidad con políticas simples y prueba los límites del grupo.