概要
前回
にてCloudWatch Logsの過去ログをS3へエクスポートする方法を説明しました。
今回はリアルタイムにS3に転送する方法を紹介します。
手順
管理ポリシーではないIAMポリシーが何度も出てくるので、自動生成してくれるWebコンソールで作成します。
前提
- CloudWatch Logsのロググループ
- S3バケット
はすでにあるとして進めます。
フロー
Kinesis Firehoseの用意
Webコンソールでポチポチ作ってきます。
データソース
CloudWatch Logsの場合はこちらを選択します。

データ変換
今回データはいじらずそのまま保存するのでDisableに

転送先
転送先はS3にします。

※Prefixの最後に/を入れた方がS3のディレクトリ構造が綺麗になります。Prefixの後ろにyyyy/MM/dd...と付くのですが、最初のスラッシュがないので。この例では付いてませんが、cloudwatch-logs-test/と言う感じにしてください
CloudWatch Logs のすべてのログイベントは、既に gzip 形式で圧縮されており、二重に圧縮することを防ぐため、Firehose では圧縮しないようにします。

IAMポリシー
IAMポリシーの指定です。ボタンをクリックすると自動で生成してくれるのでそれに任せます。
自分で指定したい場合は使いたいポリシーを選択してください。

クリックすると以下の画面に飛ばされます。

自動生成されたIAM Policyは以下です。非常に長いので折りたたんでます。
指定すると以下のように選択された状態になります。

確認画面
最後に設定の確認画面が挟まります。問題なければ作成してください。

作成
作成ボタンを押すと以下のようにCreating...となります。

1分程度待つと完了します。

CloudWatch Logsの設定
Webコンソールにはアクションからサブスクリプションフィルタを設定できますが、コンソール上で可能なのは
- Lambda
- Elasticsearch
だけで
はaws-cliなど使ってAPI経由でしか現時点では登録できません。
なのでaws cliで作成していきます。
IAM Roleの作成
IAM ロールを作成して、CloudWatch Logs に Kinesis Data Firehose 送信ストリームにデータを置く権限を付与します。
~/TrustPolicyForCWL.jsonという信頼ポリシーを用意します。
{ "Statement": { "Effect": "Allow", "Principal": { "Service": "logs.region.amazonaws.com" }, "Action": "sts:AssumeRole" } }
先程の信頼ポリシーを指定してIAM Roleを作成します。
下の例ではCWLtoKinesisFirehoseRoleという名前のRoleを作ってます。
$ aws iam create-role \ --role-name CWLtoKinesisFirehoseRole \ --assume-role-policy-document file://~/TrustPolicyForCWL.json
次に権限ポリシーを作成します。
~/PermissionsForCWL.jsonとします。
{ "Statement":[ { "Effect":"Allow", "Action":["firehose:*"], "Resource":["arn:aws:firehose:region:123456789012:*"] }, { "Effect":"Allow", "Action":["iam:PassRole"], "Resource":["arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole"] } ] }
先程作ったCWLtoKinesisFirehoseRoleにポリシーをアタッチします。
$ aws iam put-role-policy --role-name CWLtoKinesisFirehoseRole \ --policy-name Permissions-Policy-For-CWL \ --policy-document file://~/PermissionsForCWL.json
サブスクリプションフィルタの作成
準備が整ったので以下のパラメータでサブスクリプションフィルタを作成します。
| パラメータ | 値 | 備考 |
|---|---|---|
| log-group-name | cloudwatch-test | CloudWatch Logsで転送したいロググループ |
| filter-name | "All" | 任意 |
| filter-pattern | "" | 全ログを流すため空文字 |
| destination-arn | arn:aws:firehose:region:${account_id}: deliverystream/firehose-test |
転送先のFirehoseのARN |
| role-arn | arn:aws:iam::${account_id}: role/CWLtoKinesisFirehoseRole |
サブスクリプションフィルタで使うIAM RoleのARN |
cloudwatch-testというCloudWatch Logsのロググループに作成するとして、以下のように実行します。
$ aws logs put-subscription-filter \ --log-group-name "cloudwatch-test" \ --filter-name "All" \ --filter-pattern "" \ --destination-arn "arn:aws:firehose:region:${account_id}:deliverystream/firehose-test" \ --role-arn "arn:aws:iam::${account_id}:role/CWLtoKinesisFirehoseRole"
作成が完了すると以下のようにFirehoseのサブスクリプションフィルタが付きます。

動作確認
Kinesis Firehoseのモニターでは以下のようにメトリクスが取れてます。

S3の方にもデータが逐次転送されていきます。

まとめ
Firehoseを使うことで簡単にCloudWatch LogsからS3へのバックアップができるようになりました。