CloudWatch LogsをS3に転送するためにEventBridge Schedulerを使用する
はじめに
昨年 Amazon EventBridge Schedulerという機能が公開されました。今回はこれを利用して、Amazon CloudWatch LogsをAmazon S3に転送してみます。
設定方法
EventBridge Schedulerは多数のAWSサービスのAPIをターゲットに指定できます。この中にはCloudWatch Logsの CreateExportTask
も含まれており、これはLog GroupからS3バケットにエクスポートするタスクを作成します。今回はこのAPIを利用して、CloudWatch LogsからS3バケットへのエクスポートを定期的に実行することを目指します。
EventBridge Scheduer用のIAMロール作成
EventBridge SchedulerからCloudWatch Logsに対する操作権限を付与します。今回は横着して CloudWatchLogsFullAccess
というマネージドポリシーを付与しました。
ログ保存用のS3バケットの作成
CloudWatch Logsのエクスポート先とするS3バケット (名称: cw-s3-20230820
) を作成します。ここでは以下のようなバケットポリシーを付与しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::cw-s3-20230820"
},
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::cw-s3-20230820/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
CloudWatch Logsの設定
今回は過去に取得していたCloudWatch Logsを利用しましたが、必要に応じて設定をします。
EventBridge Schedulerの設定
ここからEventBridge Schedulerの設定をします。
マネジメントコンソールから設定する場合は以下の項目を入力します
1. スケジュールの詳細の指定
スケジュール名、スケジュールグループに加え、スケジュールのパターンを入力します。
2. ターゲットの選択
ターゲットとなるAPIを選択します。ここでは すべてのAPI
からCloudWatch Logsを検索し、 CreateExportTask
を選択します。
続いて CreateExportTask
APIへのインプット情報をJson形式で渡します。今回は以下のようなデータを渡しました。
{
"Destination": "cw-s3-20230820",
"DestinationPrefix": "<aws.scheduler.scheduled-time>",
"From": 1692351040000,
"LogGroupName": "messages",
"To": 1694192262000
}
いくつか補足します。
-
From
To
: Unix timestampで、取得するログの期間を指定します。 -
DestinationPrefix
: 保存先のS3バケット名を指定します。 -
LogGroupName
: 取得する対象のCloudWatch LogGroupを指定します。 -
DestinationPrefix
: エクスポートされるオブジェクトのキーの先頭として使用されるPrefixを指定します。デフォルトはexportedlogs
となりますが、ここではEventBridge Schedulerで利用できるキーワードを利用します (後述)。
3. 設定
スケジュール完了後のアクションや再試行ポリシー、暗号化などの設定を行います。ここでは使用するIAMロールを指定します。
4. スケジュールの確認と作成
設定情報を確認して作成します。
補足: EventBridge Schedulerで利用できるキーワードについて
3. 設定
で指定した DestinationPrefix
は、デフォルトでは exportedlogs
が指定されます。この場合、指定したS3バケットに exportedlogs
というフォルダが作成され、そこに <タスクID> / <Logストリーム> / 000000.gz
という形式でログが保存されます。
ここで EventBridge Scheduler特有のキーワードである <aws.scheduler.scheduled-time>
を利用します。これはSchedulerが実行された時間を指定するキーワードであり、これを DestinationPrefix
に指定することで、 Schedulerの実行時間ごとにフォルダが分かれます。こうするとエクスポートされたログのファイルが一定周期ごとに分けて保存され、特に定期的にCloudWatch Logsからエクスポートする場合は見分けやすくなるのではないかと思います。
動作確認
今回設定したSchedulerは以下の通りです。ここでは10分ごとにタスクを実行するようにしています。
設定後、スケジュールした時間が経過したのちにS3バケットを見てみると、以下のようにスケジュール実行時間ごとにフォルダが分かれている様子が確認できます (何度か実行しているので上記スケジュール以外のものも保存されています)。
なお保存時の時刻はUTCに変換されるようです。
今回指定したLogGroupにはEC2インスタンスからのログを保存しており、インスタンスごとにLogストリームが分かれていますが、それらが保存されていることも確認できました。
CloudFormationによる作成
CloudFormationでの作成は、以下のようなファイルを使用します。なお、Schedulerの開始・終了時刻を指定する StartDate
EndDate
というパラメータがあるのですが、こちらで指定するフォーマットが作成時点ではよくわからなかったため、空欄にしています。
CloudFormationファイル
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
BucketName:
Type: String
ScheduleExpression:
Type: String
Default: "rate(10 minutes)"
ScheduleExpressionTimezone:
Type: String
Default: "Asia/Tokyo"
LogGroupName:
Type: String
FromTimestamp:
Type: Number
Default: 1693540800000 # 2023-09-01T13:00:00
ToTimestamp:
Type: Number
Default: 1694318400000 # 2023-09-10T13:00:00
#StartDate:
# Type: String
#EndDate:
# Type: String
Resources:
S3BucketForCWLogs:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3BucketForCWLogs
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: logs.ap-northeast-1.amazonaws.com
Action: s3:GetBucketAcl
Resource: !Sub arn:aws:s3:::${S3BucketForCWLogs}
- Effect: Allow
Principal:
Service: logs.ap-northeast-1.amazonaws.com
Action: s3:PutObject
Resource: !Sub arn:aws:s3:::${S3BucketForCWLogs}/*
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
IAMRoleForEventBridgeScheduler:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- scheduler.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
EventBridgeScheduler:
Type: AWS::Scheduler::Schedule
Properties:
FlexibleTimeWindow:
Mode: "FLEXIBLE"
MaximumWindowInMinutes: 15
Name: !Ref S3BucketForCWLogs
ScheduleExpression: !Ref ScheduleExpression
ScheduleExpressionTimezone: !Ref ScheduleExpressionTimezone
State: "ENABLED"
#StartDate: !Ref StartDate
#EndDate: !Ref EndDate
Target:
Arn: arn:aws:scheduler:::aws-sdk:cloudwatchlogs:createExportTask
Input: !Sub |-
{
"Destination": "${S3BucketForCWLogs}",
"DestinationPrefix": "<aws.scheduler.scheduled-time>",
"From": ${FromTimestamp},
"LogGroupName": "${LogGroupName}",
"To": ${ToTimestamp}
}
RoleArn: !GetAtt IAMRoleForEventBridgeScheduler.Arn
最後に
これまでCloudWatch LogsをS3に定期的に転送する方法は、主に2通りありました。
- EventBridgeでスケジュール実行を設定、Lambdaで
create_export_task
を実行 - CloudWatchLogsのサブスクリプションフィルターでKinesis Data Firehoseを指定、Kinesis Data FirehoseはターゲットにS3バケットを指定
これらの方法と比べ、EventBridge Schedulerは、より気軽にCloudWatch Logsをエクスポートする手段として使えそうです。柔軟性には欠けますが、選択肢の1つとして覚えておこうと思います。
Discussion