Назад | Перейти на главную страницу

Есть ли способ создать хуки жизненного цикла автомасштабирования AWS с помощью CloudFormation без состояния гонки?

Я пытаюсь использовать автоматическое масштабирование AWS крючки жизненного цикла в шаблоне, который инкапсулирует следующее:

  1. AWS::AutoScaling::AutoScalingGroup с соответствующими политиками увеличения / уменьшения масштаба, конфигурацией запуска, ролью IAM и т. д.
  2. 2 из AWS::AutoScaling::LifecycleHook для событий запуска / завершения EC2.
  3. AWS::SQS::Queue (в упрощенном примере), где публикуются уведомления жизненного цикла.
  4. AWS::IAM::Role роль для группы автомасштабирования для отправки уведомлений в очередь SQS.

Когда ASG запускается, в очереди появляются два тестовых уведомления о создании хуков жизненного цикла, но нет уведомлений о запуске экземпляра.

А вот и состояние гонки.

AWS::AutoScaling::LifecycleHook ссылки на объекты AWS::AutoScaling::AutoScalingGroup (а значит, зависит от этого). Это определяет порядок, в котором CloudFormation создает ресурсы (группа создается первой).

Проблема в том, что группа начинает запускать экземпляры до завершения создания ловушки (запуск экземпляра не является частью шаблона, поэтому он начинает выполняться параллельно). К моменту создания ловушки событий для публикации больше нет, поскольку экземпляры уже созданы.

Есть ли способ обойти это и поймать события запуска во время запуска стека?

Это не идеальное решение, но будет ли создание стека в два прохода допустимым обходным путем?

  1. Устанавливать DesiredCapacity собственность в AutoScalingGroup ресурс для 0 при первоначальном создании стека. Это позволяет LaunchConfiguration, AutoScalingGroup, и LifecycleHook ресурсы, которые будут созданы без фактического запуска каких-либо экземпляров.
  2. Устанавливать DesiredCapacity до желаемого количества (> 0) при последующем обновлении стека. Это должно запустить желаемые экземпляры после LifecycleHook был создан.

Другой обходной путь - сделать что-то похожее на то, что предлагает Уилл Джордан, но которое может быть частью того же обновления CloudFormation Stack:

  1. Установите для свойства DesiredCapacity в ресурсе AutoScalingGroup значение 0 при первоначальном создании стека. Это позволяет создавать ресурсы LaunchConfiguration, AutoScalingGroup и LifecycleHook без фактического запуска каких-либо экземпляров.
  2. Создайте AWS :: AutoScaling :: ScheduledAction в зависимости от LifecycleHook с желаемыми размерами и значением повторения: * * * * *

Эти ресурсы могут быть частью одного сценария Cloudformation, и нет необходимости выполнять несколько обновлений в стеке.

[Edit]: К сожалению, этот подход приводит к возникновению случаев, когда встречается повторение cron-выражения. Группе AutoScaling необходимо установить IgnoreUnmodifiedGroupSizeProperties в значение true в AutoScalingScheduledAction группы AutoScaling UpdatePolicy (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html#cfn-attributes-updatepolicy-scheduledactions).

Не уверен, что это сработает, но похоже, что вы сможете получить аналогичный результат, используя NotificationConfiguration в рамках ресурса ASG.

NotificationConfiguration может отправить уведомление в тему SNS, на которую подписана очередь SQS. Очевидно, что жизненный цикл будет проходить мимо pending с таким подходом и не ждать complete-lifecycle-action, но по крайней мере все запуски экземпляров будут доступны в очереди.

HTH

редактировать

Другой вариант может заключаться в использовании WaitCondition или CreationPolicy - не уверен, будут ли они применяться до обработки хуков жизненного цикла.