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」を事前に取得しておく

いちいち管理コンソールから探す手間を省ける。

参考:

やり方は二つあって、まず古いやり方では 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 パッケージを取得&実行&結果を得る