はじめに
こんにちは。サメ映画をこよなく愛する梅木です。
先日、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のサービス連携では、思わぬところで権限不足のエラーに遭遇することがあるので、要注意ですね。