はじめに
こんにちは。サメ映画をこよなく愛する梅木です。
先日、Control Tower ランディングゾーンにて、KMSを利用した設定を行ったところ、ちょっとした落とし穴にはまりました。 小さなハマりどころでしたが、同様のエラーメッセージに直面されている方の一助となれば幸いです。
起こったこと
Control Tower のランディングゾーン設定で、事前に作成しておいたKMSキーを指定したところ、以下のようなエラーメッセージが表示されてしまいました。
- エラーメッセージ(IDなどは異なります)
- AWS Control Tower はランディングゾーンを完全に設定できませんでした。AWS Control Tower failed to deploy one or more stack set instances. StackSet Id: AWSCtrlTowerBP-BASELINE-CONFIG:abcdefg-hijklmn-opqr-stuvwxyz1234, Stack instance id: arn:aws:cloudformation:ap-northeast-1:123456789012:stack/StackSet-AWSControlTowerBP-BASELINE-CONFIG-abcdefgh-1010-abcdefghijklmnopqrstuv/12345678-abcd-1234-5678-901234567890, Status: OUTDATED, Status Reason: ResourceLogicalId:ConfigDeliveryChannel, ResourceType:AWS::Config::DeliveryChannel, ResourceStatusReason:Insufficient delivery policy to s3 bucket: aws-controltower-logs-210987654321-ap-northeast-1, unable to write to bucket, provided s3 key prefix is 'a-b1c2d3e4f5', provided kms key is 'arn:aws:kms:ap-northeast-1:567890123456:key/a1b2c3c4-5678-9a0b-a1b2-c1d2f3g4h5j6. (Service: AmazonConfig; Status Code: 400; Error Code: InsufficientDeliveryPolicyException; Request ID: abcdefgh-ijkl-mnop-qrst-vwxyz1233456; Proxy: null)
要約すると、以下の通りです。
- Control Tower が StackSet のデプロイに失敗(AWSCtrlTowerBP-BASELINE-CONFIG)
- S3 バケットへの書き込み失敗
- Configがログを格納(デリバリー)するためのポリシーが不十分
原因
KMS(カスタマーマネージドキー)に対するアクセス権限が不足しており、エラーメッセージに記載の ConfigDeliveryChannel リソース作成時にエラーとなったことが原因です。
背景
Control Tower のランディングゾーン設定では、CloudFormation スタックが自動的に起動し、AWS Config と AWS CloudTrail の設定を行います。 この際、ログデータの暗号化のために、ランディングゾーン設定時に指定したKMSキー(カスタマーマネージドキー)が利用されます。
- 該当の設定(KMS設定)

カスタマーマネージドキーを新規作成する際に、デフォルトのまま作成すると、キーポリシーにはAWSの各サービスがそのキーを使用するための権限が付与されません。
今回のケースでは、Config と CloudTrail が指定されたKMSキーを使用して暗号化・復号化を行うための権限が不足していました(逆に言えば、新規作成する際に、キーポリシーを適切に設定し、対象サービスへの許可設定をしておけば問題は起きませんでした)。
解決手順
以下の流れで解決していきます。
- キーポリシーの更新
- CloudFormation スタック削除
- Control Tower 再設定
1. キーポリシーの更新
AWS Control Tower の公式ドキュメント((オプションでAWS KMSキーを設定する)https://docs.aws.amazon.com/controltower/latest/userguide/configure-kms-keys.html#kms-key-policy-update)を参考に、KMSキーポリシーに以下のステートメントを追加し、Config と CloudTrail サービスからのアクセスを明示的に許可します。
注: YOUR-HOME-REGION、YOUR-MANAGEMENT-ACCOUNT-ID、YOUR-KMS-KEY-ID はご自身の環境に合わせて修正してください。
- Config用ステートメント
{ "Sid": "Allow Config to use KMS for encryption", "Effect": "Allow", "Principal": { "Service": "config.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey" ], "Resource": "arn:aws:kms:YOUR-HOME-REGION:YOUR-MANAGEMENT-ACCOUNT-ID:key/YOUR-KMS-KEY-ID" }
- CloudTrail用ステートメント
{
"Sid": "Allow CloudTrail to use KMS for encryption",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey*",
"kms:Decrypt"
],
"Resource": "arn:aws:kms:YOUR-HOME-REGION:YOUR-MANAGEMENT-ACCOUNT-ID:key/YOUR-KMS-KEY-ID",
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudtrail:YOUR-HOME-REGION:YOUR-MANAGEMENT-ACCOUNT-ID:trail/aws-controltower-BaselineCloudTrail"
},
"StringLike": {
"kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:YOUR-MANAGEMENT-ACCOUNT-ID:trail/*"
}
}
}
Principalで指定したサービスに、Actionで指定したGenerateDataKeyアクション、Decryptアクションの実行を許可しています。
2. CloudFormation スタック削除
失敗した CloudFormation スタックを削除してから、再度 Control Tower の設定を行う必要があります。
CloudFormation コンソールを表示し、失敗した AWSControlTowerBP-BASELINE-CLOUDTRAIL-MASTER スタックを選択、削除します。
3. Control Tower 再設定
再度、Control Tower ランディングゾーンを設定します。
これで無事にランディングゾーンの構築が完了し、ログも KMS で暗号化されるようになりました!
まとめ
Control Tower のランディングゾーン設定で KMS を利用する場合、事前に KMS キーのキーポリシーに Config と CloudTrail 用のアクセス許可を追加しておきましょう。 また、エラーメッセージにアクセス権限に関するメッセージが表示されており、KMS(CMK)を利用している際は、キーポリシーを忘れずにチェックしましょう。AWSのサービス連携では、思わぬところで権限不足のエラーに遭遇することがあるので、要注意ですね。