Можно ли принудительно воссоздать экземпляр EC2 или RDS, используя стеки облачной информации?
Мой стек застревает в точке, где простое уничтожение и создание ресурса исправит его, вместо этого мне пришлось удалить весь стек, чтобы продолжить работу.
редактировать:
Эта проблема поразила меня дважды. Сначала я создал AWS :: RDS :: Instance с некоторыми значениями по умолчанию, а затем попытался понизить его до "EngineVersion": "5.5". Предполагается, что это произойдет с некоторым прерыванием, но экземпляры mysql не могут быть понижены с 5.6 до 5.5, поэтому стек был оставлен в состоянии UPDATE_FAILED, и я не могу воссоздать RDS без неприятного трюка.
Другой случай заключался в том, что у меня есть несколько «AWS :: EC2 :: Instance», которые загружают и запускают скрипт из «UserData», очевидно, если Y изменит загруженный скрипт, я должен воссоздать экземпляр, и нет возможности сделать это. Я снова использую тот же неприятный трюк, чтобы воссоздать машину.
Гадкий трюк:
Вместо использования группы автомасштабирования одной машины я решил обе проблемы, изменив зону доступности в свойствах ... но оставил мне дурной вкус
Для экземпляров EC2, поддерживаемых хранилищем, один трюк состоит в том, чтобы добавить комментарий к сценарию пользовательских данных, содержащий номер версии, дату или аналогичный, а затем изменить его всякий раз, когда вы хотите воссоздать экземпляр:
{
"Resources" : {
"MyEC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
// ... other properties ...
"UserData": {
"Fn::Base64" : {
"Fn::Join" : [ ":", [
"#!/bin/bash\n",
"# Version: 1.0\n",
// ... rest of user data ...
]]}
}
}
}
}
Любое изменение UserData
вызовет замену экземпляра (т. е. регенерирование). Однако поведение сценария пользовательских данных должно быть таким же, поскольку единственное изменение - это комментарий. Обратите внимание, что это не работает для экземпляров с поддержкой EBS.
Для RDS вы можете взять Снимок БД текущего экземпляра RDS, затем измените свой шаблон, чтобы использовать этот снимок с DBSnapshotIdentifier
:
{
"Resources" : {
"MyDB" : {
"Type" : "AWS::RDS::DBInstance",
"Properties" : {
// ... other properties ...
"DBSnapshotIdentifier": "<db snapshot ID>"
}
}
}
Когда бы ни DBSnapshotIdentifier
изменяется, экземпляр базы данных будет заменен. Использование снимков также позволит вам сохранить данные с момента создания снимка. (Если ты хотеть чтобы стереть данные, вы можете создать пустой снимок и передать его в качестве ввода. Или удалите и заново создайте весь стек CloudFormation.)
Более общий подход - изменить логическое имя ресурса. Из Изменение шаблона стека в документации CloudFormation:
Для большинства ресурсов изменение логического имени ресурса эквивалентно удалению этого ресурса и замене его новым. Любые другие ресурсы, зависящие от переименованного ресурса, также необходимо обновить, что может привести к их замене. Другие ресурсы требуют, чтобы вы обновили свойство (а не только логическое имя), чтобы запустить обновление.
Если вы поместите его в AutoScalingGroup, вы можете отредактировать AutoScalingGroup min / max / default на 0, а затем, как только он начнет уничтожать старый экземпляр, вы можете затем установить min / max / default на 1/1/1 и presto: новый экземпляр.
Если ваш EC2 входит в AutoScalingGroup, вы можете установить AutoScalingGroupName
свойство с номером версии в нем.
Каждый раз, когда вы меняете номер версии, CFN будет: 1. создавать новую группу автоматического масштабирования и раскручивать нужные экземпляры 2. уничтожать экземпляры в старой группе автоматического масштабирования и удалять ее.
Вот фрагмент кода из моего стека, в котором я использую эту технику, чтобы заставить большое количество машин EC2 воссоздавать и автоматически извлекать новое программное обеспечение из S3.
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub "${StackName}-${ServiceName}-${ServiceVersion}"