[アップデート] CloudWatch Logs エクスポート機能が出力先として SSE-KMS 暗号化 S3 バケットをサポートしました
コンバンハ、千葉(幸)です。
CloudWatch Logs のログエクスポートを行う際、AWS KMS によって暗号化された S3 バケットを宛先に指定できるようになりました。
「AWS KMS によって暗号化された S3 バケット」とは、デフォルト暗号化が有効で、使用するキーがSSE-KMS
であるバケットのことです。 *1
制約がひとつ取り払われたので、要件に応じてより幅広く選択できるようになりました。
先にまとめ
- デフォルト暗号化が
SSE-KMS
の S3 バケットも CloudWatch Logs ログエクスポートの宛先に指定できる- ただし
SSE-KMS
のキーを AWS 管理キーaws/s3
にしてはならない - 出力先 S3 バケット、KMS キーの双方で
logs
への許可が必要
- ただし
CloudWatch Logs ログエクスポート機能とは
標準で使用できる機能で、CloudWatch Logs ロググループ上のログを S3 バケットにエクスポートできるものです。エクスポート対象のログは開始時刻と終了時刻を指定できるほか、特定のログストリームのみを対象とする、ということもできます。
これまでエクスポート先の S3 バケットは以下のいずれかである必要がありました。
- デフォルト暗号化が無効
- デフォルト暗号化で使用するキーが
SSE-S3
今回のアップデートでデフォルト暗号化がSSE-KMS
であるバケットもサポートされています。
SSE-KMS
暗号化されたバケットを出力先に指定する場合、S3 バケットポリシーに加え、KMS キーのキーポリシーも意識する必要があります。
それぞれのポリシーで、プリンシパルをlogs.{region}.amazonaws.com
とする許可を与えてあげる必要があります。(リージョンを指定しないこともできますが、なるべく絞った方がよいでしょう。)
キーポリシーで許可が与えてあげる必要があるということは、AWS 管理キーaws/s3
は指定できなく、カスタマー管理の KMS キーを指定してあげる必要があるということですので注意してください。
SSE-KMS 暗号化バケットへのログエクスポートやってみた
今回は以下のイメージで実行していきます。
1. KMS キーの準備
以下設定で KMS キーを作成します。
- キーのタイプ:対称
- キーの使用:暗号化および復号化 *2
- エイリアス:
chibayuki-key
キーポリシーはドキュメントの記述を参考に以下を指定しました。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Allow CWL Service Principal usage", "Effect": "Allow", "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" }, "Action": "kms:GenerateDataKey", "Resource": "*" }, { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::012345678910:root" }, "Action": [ "kms:GetKeyPolicy*", "kms:PutKeyPolicy*", "kms:DescribeKey*", "kms:CreateAlias*", "kms:ScheduleKeyDeletion*", "kms:Decrypt" ], "Resource": "*" } ] }
2. S3 バケットの準備
以下設定で S3 バケットを作成しました。
- バケット名:
chibayuki-destination
- デフォルト暗号化:SSE-KMS
- 先ほど作成した KMS キーを指定
- オブジェクト所有者:ACL 無効
- ブロックバブリックアクセス:すべてブロック
- バージョニング:無効
作成後、S3 バケットポリシーを以下の通り編集します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::chibayuki-destination" }, { "Effect": "Allow", "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::chibayuki-destination/*", "Condition": { "StringEquals": { "aws:SourceAccount": "012345678910", "s3:x-amz-acl": "bucket-owner-full-control" } } } ] }
ちなみに
今回は「ACL 無効」にしたので、もしかしてバケットポリシーでs3:GetBucketAcl
の Allow は要らないのか?と思い削ってみたところ、エクスポート実行時に以下のエラーが発生しました。
エクスポートタスクを作成できませんでした。 GetBucketAcl call on the given bucket failed. Please check if CloudWatch Logs has been granted permission to perform this operation.
改めて考えると「ACL 無効」は無効というよりは「ACL の固定・強制」なので、s3:GetBucketAcl
が不要になるわけではありませんでした。 *3
ちなみに 2
SSE-KMS
で使用するキーに AWS 管理のaws/s3
を使用した際にはエクスポート実行時に以下のエラーが発生します。
エクスポートタスクを作成できませんでした。 PutObject call on the given bucket failed. Please check if CloudWatch Logs has been granted permission to perform this operation. This may be a result of a KMS key or bucket encryption misconfiguration.
aws/s3
は logs からのアクセスを許可していないしそれを変えることもできないので、カスタマーが作ったキーを指定する必要があるということですね。
3. エクスポートタスクの実行
準備が整ったのでエクスポートを実行していきます。今回はたまたま環境にあった、Lambda 関数の実行ログをエクスポートしてみます。
CloudWatch Logs ロググループの画面から「アクション」→「データを Amazon S3 にエクスポート」を押下します。
エクスポートの設定画面で各種指定を行い、「エクスポート」を実行します。指定できるパラメータは以下の通りです。
- エクスポートするデータの期間
- 開始
- 終了
- 特定のログストリームのみエクスポートする場合はそのプレフィックス
- 出力先 S3 バケット
- 出力先プレフィックス(省略した場合は
exportedlogs
になる)
実行すると、画面上部にエクスポートタスクが正常に作成された旨のメッセージと、その詳細画面へ遷移できるボタンが表示されます。
エクスポートタスクの詳細画面です。ここから出力先の S3 バケットに遷移できます。
(なお、CloudWatch コンソールの左ペインから上記の画面に遷移できる導線はありませんでした。東京リージョンであれば以下リンクから遷移できそうです。)
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:export-tasks
出力先の S3 バケットに遷移しました。
オブジェクトは.gz
で圧縮されています。S3 バケットの設定に従い、指定した KMS キーで暗号化されています。
ダウンロード・解凍し中身を確認するとこのような感じ。冒頭で述べた通り今回エクスポートしたログは Lambda 関数の実行ログなので、このような内容になっています。
2022-11-11T01:10:28.255Z START RequestId: a7679120-0a7d-4ca2-9b4c-3dd23567b670 Version: $LATEST 2022-11-11T01:10:30.491Z 200 2022-11-11T01:10:30.531Z END RequestId: a7679120-0a7d-4ca2-9b4c-3dd23567b670 2022-11-11T01:10:30.531Z REPORT RequestId: a7679120-0a7d-4ca2-9b4c-3dd23567b670 Duration: 2275.75 ms Billed Duration: 2276 ms Memory Size: 128 MB Max Memory Used: 69 MB Init Duration: 515.05 ms
SSE-KMS で暗号化された S3 バケットへの CloudWatch Logs ログのエクスポートが確認できました。
おまけ:エクスポートされたオブジェクトの命名規則
アップデートとは関係ありませんが、今回やってみたことで学んだので書いておきます。
今回エクスポートされたオブジェクトの S3 URI は以下の通りです。
s3://chibayuki-destination/exportedlogs/d8fdd9b6-9bb8-4e13-8df1-7f41e8610d8c/2022-11-11-[$LATEST]cb2c7d0c04344d1d820adffe7ae8a506/000000.gz
これは以下の規則になっています。
s3://バケット名/プレフィックス名/エクスポートタスクID/ログストリーム名/000000.gz
プレフィックス名
エクスポート時に S3 バケットのプレフィックスを指定すると上記の例のexportedlogs
の部分がそのプレフィックスに置き換わります。
エクスポートタスク ID
エクスポートタスク ID は実行直後以外はマネジメントコンソールからは確認できませんが、例えば AWS CLI を使用すれば後からでも確認できます。
% aws logs describe-export-tasks\ --query 'exportTasks[].{taskID:taskId,completionTime:executionInfo.completionTime}'\ --output table ------------------------------------------------------------ | DescribeExportTasks | +-----------------+----------------------------------------+ | completionTime | taskID | +-----------------+----------------------------------------+ | 1668238248915 | 75cfe91e-2f6c-4e42-91f7-dfb6d31dc1df | | 1668238157538 | 081b0127-b7fd-4447-a152-612d16d8e20d | | 1668237746082 | d8fdd9b6-9bb8-4e13-8df1-7f41e8610d8c | +-----------------+----------------------------------------+
ログストリーム名
エクスポート対象のログストリームが複数あった場合、s3://バケット名/プレフィックス名/エクスポートタスクID/
配下にそれぞれのストリーム名に応じたプレフィックスが作成されます。
まとめ(再掲)
- デフォルト暗号化が
SSE-KMS
の S3 バケットも CloudWatch Logs ログエクスポートの宛先に指定できる- ただし
SSE-KMS
のキーを AWS 管理キーaws/s3
にしてはならない - 出力先 S3 バケット、KMS キーの双方で
logs
への許可が必要
- ただし
終わりに
CloudWatch Logs ロググループのエクスポートで出力先のバケットにSSE-KMS
暗号化バケットが指定できるようになった、というアップデートでした。
SSE-KMS
を標準的に使っているが、これまでサポートされていなかったのでエクスポート先のバケットのみSSE-S3
にしていた、といったワークロードに刺さりそうです。
こういった暗号化方針はある程度大規模な環境では細かく定められていることも多いと思います。機能の仕様により例外的な対応をとる、というのがなるべく少なくなり、幅広い選択肢の中から選択できる、となっていくのは望ましいことだと思います。
以上、 チバユキ (@batchicchi) がお送りしました。