CloudFormation AutoScalingGroup no espera señal en la actualización / escalado
Estoy trabajando con una plantilla de CloudFormation que muestra tantas instancias como solicito, y quiero esperar a que finalicen la inicialización (a través de los Datos del usuario) antes de que la creación / actualización de la pila se considere completa.
La expectativaLa creación o actualización de la pila debe esperar las señales de todas las instancias recién creadas, para garantizar que se complete su inicialización.
No quiero que la creación o actualización de la pila se considere exitosa si alguna de las instancias creadas no se inicializa.
La realidadCloudFormation solo parece esperar señales de instancias cuando se crea la pila por primera vez. Actualizar la pila y aumentar el número de instancias parece ignorar la señalización. La operación de actualización finaliza con éxito muy rápidamente, mientras que las instancias todavía se están inicializando.
Las instancias creadas como resultado de la actualización de la pila pueden fallar al inicializarse, pero la acción de actualización ya se habría considerado un éxito.
La preguntaUsando CloudFormation, ¿cómo puedo hacer que la realidad cumpla con las expectativas?
Quiero el mismo comportamiento que se aplica cuando se crea la pila, cuando se actualiza la pila.
Preguntas similaresSolo he encontrado la siguiente pregunta que coincide con mi problema:UpdatePolicy en el grupo de escalado automático no funciona correctamente para la actualización de AWS CloudFormation
Ha estado abierto durante un año y no ha recibido una respuesta.
Estoy creando otra pregunta ya que tengo más información para agregar, y no estoy seguro de si estos detalles coincidirán con los del autor en esa pregunta.
ReproducciónPara demostrar el problema, he creado una plantilla basada en el ejemplo debajo deEncabezado de Auto Scaling Group en esta página de documentación de AWS, que incluye señalización.
La plantilla creada se ha adaptado así:
Utiliza un Ubuntu AMI (en la regiónap-northeast-1
) loscfn-signal
El comando se ha inicializado y se ha llamado según sea necesario teniendo en cuenta este cambio.Un nuevo parámetro dicta cuántas instancias lanzar en el grupo de escalado automático.Se ha agregado un tiempo de reposo de 2 minutos antes de la señalización, para simular el tiempo empleado durante la inicialización.Aquí está la plantilla, guardada entemplate.yml
:
Parameters:
DesiredCapacity:
Type: Number
Description: How many instances would you like in the Auto Scaling Group?
Resources:
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AvailabilityZones: !GetAZs ''
LaunchConfigurationName: !Ref LaunchConfig
MinSize: !Ref DesiredCapacity
MaxSize: !Ref DesiredCapacity
CreationPolicy:
ResourceSignal:
Count: !Ref DesiredCapacity
Timeout: PT5M
UpdatePolicy:
AutoScalingScheduledAction:
IgnoreUnmodifiedGroupSizeProperties: true
AutoScalingRollingUpdate:
MinInstancesInService: 1
MaxBatchSize: 2
PauseTime: PT5M
WaitOnResourceSignals: true
LaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: ami-b7d829d6
InstanceType: t2.micro
UserData:
'Fn::Base64':
!Sub |
#!/bin/bash -xe
sleep 120
apt-get -y install python-setuptools
TMP=`mktemp -d`
curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | \
tar xz -C $TMP --strip-components 1
easy_install $TMP
/usr/local/bin/cfn-signal -e $? \
--stack ${AWS::StackName} \
--resource AutoScalingGroup \
--region ${AWS::Region}
Ahora creo la pila con una sola instancia, a través de:
$ aws cloudformation create-stack \
--region=ap-northeast-1 \
--stack-name=asg-test \
--template-body=file://template.yml \
--parameters ParameterKey=DesiredCapacity,ParameterValue=1
Después de esperar unos minutos a que se complete la creación, veamos algunos eventos de la pila de claves:
$ aws cloudformation describe-stack-events \
--region=ap-northeast-1 \
--stack-name=asg-test
...
{
"Timestamp": "2017-02-03T05:36:45.445Z",
...
"LogicalResourceId": "AutoScalingGroup",
...
"ResourceStatus": "CREATE_COMPLETE",
...
},
{
"Timestamp": "2017-02-03T05:36:42.487Z",
...
"LogicalResourceId": "AutoScalingGroup",
...
"ResourceStatusReason": "Received SUCCESS signal with UniqueId ...",
"ResourceStatus": "CREATE_IN_PROGRESS"
},
{
"Timestamp": "2017-02-03T05:33:33.274Z",
...
"LogicalResourceId": "AutoScalingGroup",
...
"ResourceStatusReason": "Resource creation Initiated",
"ResourceStatus": "CREATE_IN_PROGRESS",
...
}
...
Puede ver que el grupo de escalado automático comenzó a iniciarse a las 05:33:33. A las 05:36:42 (3 minutos después del inicio), recibió una señal de éxito. Esto permitió que el grupo de escalado automático alcanzara su propio estado de éxito solo unos momentos después, a las 05:36:45.
Eso es increíble, trabajar como un encanto.
Ahora intentemos aumentar el número de instancias en este grupo de escalado automático a 2 actualizando la pila:
$ aws cloudformation update-stack \
--region=ap-northeast-1 \
--stack-name=asg-test \
--template-body=file://template.yml \
--parameters ParameterKey=DesiredCapacity,ParameterValue=2
Después de esperar un tiempo mucho más corto para que se complete la actualización, veamos algunos de los nuevos eventos de pila:
$ aws cloudformation describe-stack-events \
--region=ap-northeast-1 \
--stack-name=asg-test
{
"ResourceStatus": "UPDATE_COMPLETE",
...
"ResourceType": "AWS::CloudFormation::Stack",
...
"Timestamp": "2017-02-03T05:45:47.063Z"
},
...
{
"ResourceStatus": "UPDATE_COMPLETE",
...
"LogicalResourceId": "AutoScalingGroup",
"Timestamp": "2017-02-03T05:45:43.047Z"
},
{
"ResourceStatus": "UPDATE_IN_PROGRESS",
...,
"LogicalResourceId": "AutoScalingGroup",
"Timestamp": "2017-02-03T05:44:20.845Z"
},
{
"ResourceStatus": "UPDATE_IN_PROGRESS",
...
"ResourceType": "AWS::CloudFormation::Stack",
...
"Timestamp": "2017-02-03T05:44:15.671Z",
"ResourceStatusReason": "User Initiated"
},
....
Ahora puede ver que si bien el grupo de autoescalado comenzó a actualizarse a las 05:44:20, se completó a las 05:45:43, eso es menos de un minuto y medio para completarse, lo que no debería ser posible considerando un tiempo de sueño de 120 segundos en los datos del usuario.
La actualización de la pila continúa hasta su finalización sin que el grupo de escalado automático haya recibido ninguna señal.
La nueva instancia sí existe.
En mi caso de uso real, he introducido SSH en una de estas nuevas instancias para descubrir que todavía estaba en proceso de inicialización incluso después de que se completara la actualización de la pila.
Lo que he probadoHe leído y releído la documentación que rodeaCreationPolicy
yUpdatePolicy
, pero no he podido identificar lo que me falta.
Echando un vistazo a la política de actualización en uso anterior, no entiendo lo que realmente está haciendo. Por que esWaitOnResourceSignals
cierto, pero no está esperando? ¿Tiene algún otro propósito?
¿O estas nuevas instancias no están incluidas en la política de "actualización continua"? Si no pertenecen allí, entonces esperaría que cayeran bajo la política de creación, pero eso tampoco parece aplicarse.
Como tal, no sé qué más probar.
Tengo la sensación de que está funcionando según lo diseñado / esperado, pero si es así, ¿cuál es el punto de eso?WaitOnResourceSignals
propiedad y cómo puedo cumplir con las expectativas establecidas anteriormente?