AWS CloudFormation テンプレート中で使う AMI ID のメンテナンス方法
AMI ID をハードコードしていると、そのうち AMI が見つからなくなり以下のような CREATE FAILED になる。
API: ec2:RunInstances Not authorized for images: [ami-XXXXXXXXXXXXXXXXX]
これに対処するにはどうすればいいのだろう?
まとめ
- FAILED が起きた時に素早く対処できるようにする
- AMI ID をパラメータ化する(ハードコード時よりもいじりやすい)
- 管理コンソールで AMI ID で検索して有効無効を調べる
- awscli で「有効な AMI ID」を事前にゲットしておく
- FAILED が起きないよう CloudFormation 側で自動で有効な AMI ID を指定させる
- 「有効な AMI ID をゲットする処理」をする Lambda + s3 にアップ + CloudFormation 側でそれ取ってきて実行
方法1: FAILED になった時に素早く対処できるようにする
これは FAILED を防ぐのではなく「FAILED が起きた時に簡単に別の AMI ID を指定できるようにする」というアプローチ。
詳しいやり方は色々ある(組み合わせる)。以下雑多に取り上げる。
AMI ID の指定をパラメータ化する
FAILED 時、ハードコードだと「Resources.InstanceServerA.Properties.ImageId を変えてくれ」となるが、これはコードに馴染みがない人にはハードルが高い。
一方、このパラメータ化なら「AMIServerA のパラメータに、有効な AMI ID を指定してくれ」と言えば済む。画面操作なので(AWS CloudFormation の管理画面を使っている程度のリテラシーでも)ハードルは低い。
Parameters: AMIServerA: Description: ServerA AMI ID. Default: ami-XXXXXXXXXXXXXXXXX Type: String Resources: InstanceServerA: Type: AWS::EC2::Instance Properties: ImageId: !Ref AMIServerA
AMI ID が有効かどうかを調べる
- 1: 管理コンソール > EC2 > インスタンスの作成
- 2: AMI 選択画面で、AMI ID で検索
有効な場合、コミュニティ AMI に 1 件だけヒットする。
これが 0 件の場合、当該 AMI ID は存在しない(のでスタック流した時に Not authorized for images で FAILED になる)。
AWS CLI で「有効な AMI ID」を事前に取得しておく
いちいち管理コンソールから探す手間を省ける。
参考:
- パラメーターストアから最新のWindows AMIのIDを取得する | DevelopersIO
- AWS Systems Manager Parameter Store を使用して最新の Amazon Linux AMI IDを取得する - Amazon Web Services ブログ
やり方は二つあって、まず古いやり方では aws ec2 describe-images
を使って、AMI 名のワイルドカードでフィルタする模様。ソートして一番上を取り出す、など面倒くさかった。
新たなやり方では aws ssm get-parameters (URI)
を使って、指定 AMI の最新バージョン(の AMI ID)を 常に同じ URI で 取れる模様。
方法2: そもそも FAILED が起きないようにする(自動で有効な AMI ID を使う)
方法 1 は手動であり、FAILED を起こさないようにすることができないが、これを可能にするのが方法2。
とりあえず一つだけ見つけた。Lambda と連携させれば良いみたい。
参考: Walkthrough: Looking Up Amazon Machine Image IDs - AWS CloudFormation
実装は何百行となっているが、要点はこんな感じっぽい。
- 1: 「有効な AMI ID を取得する Lambda パッケージ」を S3 にアップしておく
- この Lambda は「Windows_Server-2008-SP2-English-32Bit-Base-*」みたいにワイルドカードで AMI を探す
- 2: テンプレートでは
AWS::Lambda::Function
などを駆使して、1: の Lambda パッケージを取得&実行&結果を得る