何が起きたか
弊社ではインスタンスの定期起動やWindows Updateの実施などでCloud Automatorを大活用しています。
その日常の中で事態は突然起こりました。
Cloud AutomatorジョブでEC2インスタンスの起動に失敗したのです。

ジョブの設定を変えたか? →変えてない
起動されるEC2インスタンスで何を変えたか? →変えました。CMK(カスタマーマスターキー)を設定してこれでEBSボリュームを暗号化したのでした
ちなみに、AWSマネジメントコンソール上で当該EC2インスタンスの起動は難なくできました。 CMKの持ち主ユーザとEC2インスタンスを起動させたユーザは同一だったからです。
直す方針
Cloud AutomatorジョブでEC2インスタンスを起動させることは、EC2インスタンスがあるAWSアカウントにクロスアカウントアクセスして実行しています。
起動させるEC2インスタンスにアタッチされているEBSボリュームにCMKによる暗号化がされている場合、クロスアカウントアクセスするIAMロールに「CMKにもアクセスしてよい」許可を与える必要があります。
直す方法
これに倣ってポリシーを作成します。
AWSマネジメントコンソールにて、サービスメニューから「KMS」を選択し、「カスタマー管理型のキー」を選択し、該当キーを選択して、「キーポリシー」のところで「編集」を選択して、CMKのキーポリシーに下記の2つのポリシーを追加します。

キーポリシーに下記のポリシーを追加します。
このポリシー内容はこのCMKを利用して何かするという許可になります。キーユーザ(この場合はCloudAutomator-1a〜ロール)に以下のアクセス許可を与えています。
EC2インスタンスの起動・稼働にはEBSボリュームの読み書きが行われることになり、EBSボリュームに暗号化が有効になっている場合はEBSボリュームの読み書きの過程で暗号化・復号化されます。
参考: Amazon EBS 暗号化 - Amazon Elastic Compute Cloud
今回の場合、EBSボリュームの暗号化・復号化でこのCMKが指定されているため、このCMKを利用してEBSボリュームの暗号化・復号化を行ってよい許可をキーユーザに付与している設定になります。
- kms:Encrypt: キーユーザがこのCMKを使用してデータを暗号化できる
- kms:Decrypt: キーユーザがこのCMKを使用してデータを復号化できる
- kms:ReEncrypt*: キーユーザはこのCMKで最初に暗号化されたデータを再暗号化するか、このCMKを使用して以前に暗号化されたデータを再暗号できる
- kms:GenerateDataKey*: キーユーザはクライアント側の暗号化操作のために対称データキーまたは非対称データキーペアを要求できる
- kms:DescribeKey: キーユーザは識別子、作成日、キー状態など、このCMKに関する詳細情報を取得できる
上記のアクセス許可を「"kms:ViaService": "ec2.ap-northeast-1.amazonaws.com"」によって、東京リージョンのEC2サービスに限って許可を与えるようにしています。
{
"Sid": "Allow external account Cloud Automator use of the customer managed key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111122223333:role/CloudAutomator-1a2b3c4d5e6f7g8h9i0j-CloudAutomator-1a2b3c4d5e6f"
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "ec2.ap-northeast-1.amazonaws.com"
}
}
}
キーポリシーに下記のポリシーを追加します。
このポリシー内容は暗号化操作にこのCMKを使用することの許可になります。
このポリシー内容はこのCMKの利用の許可になります。キーユーザ(この場合はCloudAutomator-1a〜ロール)にアクセス許可を与えています。
「"kms:GrantIsForAWSResource": "true"」を追加することでEBSなどのKMSと統合されたAWSサービスが、指定されたプリンシパル(この場合はCloudAutomator-1a〜ロール)に代わって、このCMKを利用してよいという許可を与えています。
参考: CreateGrant - AWS Key Management Service
参考: Using policy conditions with AWS KMS - AWS Key Management Service
{
"Sid": "Allow attachment of persistent resources in external account Cloud Automator",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111122223333:role/CloudAutomator-1a2b3c4d5e6f7g8h9i0j-CloudAutomator-1a2b3c4d5e6f"
]
},
"Action": [
"kms:CreateGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
上記の「arn:aws:iam::111122223333:role/CloudAutomator-1a2b3c4d5e6f7g8h9i0j-CloudAutomator-1a2b3c4d5e6f」は実際にはCloud AutomatorがスイッチロールしてくるIAMロールになります。
Cloud AutomatorがどのIAMロールを使用しているか、AWSマネジメントコンソールのIAMロール一覧から判別できない場合は、Cloud Automatorにログインし、下記のメニューをたどって確認することができます。
グループ管理 → グループ一覧 → 一覧から該当グループを選択 → AWSアカウント → 操作対象のアカウント名の「編集」を選択
「IAMロールARN」の設定値をメモし、「role/」以降がロール名になります。

ここまで確認できたら、「IAMロールARN」の設定値にあるarnから始まるすべてをポリシーに書けます。
解決
起動させられなかったEC2インスタンスを起動させられるかCloud Automatorジョブを発火させてみます。

見事成功しました。