Kinesis Firehoseを使ってCloudWatch Logをs3へ出力してみた

はじめに

はじめまして、PSインフラチームのsasakiです 。
主にクラウド環境を利用した環境構築を行っております。

今回は CloudWatch Logs上のログデータを長期保管した場合のコスト増を考え、一定期間を経過したログを自動でAmazon S3 へ出力することを検討しました。

出力方法として手動でCloudWatch Logsのエクスポート機能を動かす事も可能ですが、今回の要件である「自動出力」の方法について纏めました。自動出力方法の選択肢としては、AWS Lambdaを使用してCloudWatch Logsのエクスポート機能を実行する事も可能です。

今回は将来的に様々な利用用途に合わせて複数の出力先への出分けをコードを書かずに簡易に行えるようにする為に「Amazon CloudWatch Logsサブスクリプション」と「Amazon Kinesis Data Firehose」を利用して、「Amazon S3」 へ出力する、までをゴールとしています。

Amazon Kinesis Data Firehose とは

Amazon Kinesis Data Firehose は、リアルタイムのストリーミングデータを Amazon Simple Storage Service (Amazon S3)、Amazon Redshift、Amazon Elasticsearch Service (Amazon ES)、Splunk などの送信先に配信するための完全マネージド型サービスです。Kinesis Data Firehose は、Kinesis ストリーミングデータプラットフォームの一部です。他にも、Kinesis Data StreamsKinesis ビデオストリームAmazon Kinesis Data Analytics があります。Kinesis Data Firehose を使用すると、アプリケーションを記述したり、リソースを管理したりする必要はありません。Kinesis Data Firehose にデータを送信するようデータプロデューサーを設定すると、指定した送信先にデータが自動的に配信されます。データを配信前に変換するように、Kinesis Data Firehose を設定することもできます。

引用:Amazon Kinesis Data Firehose とは?

Amazon Kinesis Data Firehoseは、リアルタイムで配信するサービスです。Amazon CloudWatch Logs サブスクリプションを通して配信されるデータがs3へエクスポート対象です。
また、今回の検証ではデータの変換は行いません。

Amazon CloudWatch Logs サブスクリプションとは

サブスクリプションを使用して CloudWatch Logs からのログイベントのリアルタイムフィードにアクセスし、カスタム処理、分析、他のシステムへのロードを行うために、Amazon Kinesis ストリーム、Amazon Kinesis Data Firehose ストリーム、AWS Lambda などの他のサービスに配信することができます。ログイベントのサブスクリプションを開始するには、Kinesis ストリームなど、イベントを配信する宛先ソースを作成します。サブスクリプションフィルタは、AWS リソースに配信されるログイベントのフィルタリングに使用するフィルタパターンと、一致するログイベントの送信先に関する情報を定義します。

引用:サブスクリプションを使用したログデータのリアルタイム処理

サブスクリプションは、リアルタイムにAWSの他のサービスに配信するサービスです。リアルタイムに配信するサービスのため、既存の書き込まれたデータはエクスポートをすることは出来ません。

検証に利用したサービス

  • Amazon Kinesis Data Firehose(以下、Firehose)
  • Amazon CloudWatch Logs(以下、CWL)
  • Amazon Simple Storage Service (以下、s3)
  • AWS Identity and Access Management(以下、IAM)

▼事前準備

  • s3 エクスポート先のバケット作成

▼Firehose 作成

  • Firehose作成
    マネージメントコンソールよりFirehoseのデータストリームを作成します。
    簡単に設定内容を説明します。

  • Delivery stream name
    配信ストリーム名前を設定
  • Sources (送信元)
    今回は「Direct PUT or other sources」を選択する。
    • Direct PUT or other sources :
      CWLやKinesis Agentなどがデータソースは場合はこちらを選択する。今回はこちらを選択する。
    • Kinesis Data Stream
      データソースを「Kinesis Data Stream」を利用してFirehoseへ書き込みを行う際に利用します。

  • Transform source records with AWS Lambda
    レコード変換をAWS Lambdaを利用して変換を行う。 今回は利用しないのでDisabledを選択する。
    • Disabled(無効)
      変換を行わないず、送信先にへ格納される。
    • Enabled(有効)
      Lambda関数を指定する、既存のLambda関数やLambdaの設計図を利用することが出来る。
  • Convert record format
    レコードの形式をAWS Glue を利用して変更を行います。今回は利用しないのでDisabledを選択する。
    • Disabled(無効)
      変換を行わないず、送信先にへ格納される。
    • Enabled(有効)
      AWS Glueのテーブルを指定する。

  • Destination
    送信先を指定する。
    「Amazon s3」 、「Amazon Redshift」、「Amazon Elasticsearch Service」、「Splunk」が選択することが出来ます。 今回は 「Amazon s3」 を選択する。
    • S3 bucket
      データを送信先のs3をバケットを指定します。
    • prefix
      保存するときのフォルダを指定出来ます。
      送信先のフォルダは構成はYYYY/MM/DD/HH" UTC 時間形式のプレフィックスを自動的作成されます。
    • error prefix
      変換がエラーとなったデータを配信するフォルダです。

  • s3 バッファ条件
    s3へ配信する前にFirehose内に受信データをバッファします。バッファサイズとバッファ間隔を指定することが出来ます。条件を満たすとs3へ受信データを送信されます。
    • Buffer size
      バッファサイズを指定しいます、1 - 126 MBから設定
    • Buffer interval
      バッファ間隔を指定します。60 - 900 秒から設定
  • S3 compression
    配信されるファイルの圧縮の形式を選択する。今回は「Disabled(圧縮なし)」を選択する。
    S3 encryption
    配信されるファイルの 暗号化の有無を選択する。 今回は「Disabled(暗号化なし)」を選択する。
  • Error logging
    データ配信やデータ変換でエラーが発生した際にCWLへ出力の設定が行えます。
    今回は「Disabled」を選択する。
  • IAM role
    画面に従って新たにIAMロールを作成致します。
    また、自動で作成されるIAMポリシーは各設定に必要な内容がアクションが含まれております。

IAMポリシーを最低限権限にするのであればs3のアクションがあれば良いかと思います。

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::【バケット名】",
                "arn:aws:s3:::【バケット名】/*"
            ]
        }
    ]
}

Firehoseの設定については特に困ることもなく設定することが出来ました。

IAMロールの権限についてはデフォルトだと全ての機能が利用できるようになっているので、参考にすれば最小限の権限付与も割と簡単に出来ると思います。

▼CWL サブスクリプションの作成

  • IAMロール作成
    CWLよりFirehoseのデータストリームへ書き込みを行うIAMロールを作成する。
    作成する際には、「信頼するエンティティ」にCWLが選択出来ないため、一旦EC2を選択し、ポリシーはアタッチせずにIAMロールを変更します。
  • IAMロール の信頼関係の変更
    作成したIAMロールを選択し、「信頼関係」タブを選択する。
    信頼関係の編集より以下の内容に変更する。
    ※リージョンについては適切なリージョンを指定してください。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "logs.ap-northeast-1.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
  • IAMポリシーを作成
    FirehoseのARNを控えて、以下の内容のIAMポリシーを作成します。
    作成したポリシーはIAMロールへアタッチする。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "firehose:PutRecord",
                "firehose:PutRecordBatch"
            ],
            "Resource": [
               "arn:aws:firehose:ap-northeast-1:XXXXXXXXXXXX:deliverystream/test-ssk-Firehoe"
            ]
        }
    ]
}
  • CWL サブスクリプションの作成
    CWLのサブスクリプションはマネージメントコンソールでは設定できません。そのためAWS CLIやAPIで設定が必要です。
    今回はAWS CLIで設定を行います。コマンドは以下のコマンドを実行する。
> aws logs put-subscription-filter --log-group-name "test-ssk-log" --filter-name "subscription" --filter-pattern "" --destination-arn "arn:aws:firehose:ap-northeast-1:XXXXXXXXXXXX:deliverystream/test-ssk-Firehoe" --role-arn "arn:aws:iam::XXXXXXXXXXXX:role/CWLtoKinesisFirehoseRole"

Firehose 料金

Firehoseの料金は取りこまれたデータ量で決まります。
東京リージョンの場合は、1GB あたり$0.036です。
※最新情報は公式サイトの料金ページをご確認下さい。
レコードのデータサイズの直近の 5 KB の倍数に切り上げた値になる。なのでレコードサイズが3 KBの場合は5 KB、16KBの場合は20KBとなります。

s3やCWLの料金も発生します。

まとめ

Firehoseを使うことで比較的簡単にCWLのデータをs3へ出力することが出来ました。
これでCWLへ書き込まれたデータをAmazon Athena等を利用して検索や分析することも出来るようになりました。

注意点として本検証では「CWL」のログを「Firehose」を使用して「s3」へ出力する事をゴールとた為、詳細には触れていませんがAmazon Athenaを利用する場合、ストレージ容量とクエリのスキャン量を減らす事がコストやパフォーマンスに大きく影響します。本検証で行ったFirehoseの設定で出力されたデータの場合、データの容量次第では処理遅延だけでなく、思わぬ大金を支払うことになりかねませんので、最適なデータ圧縮やパーティション、ファイルフォーマットを利用して下さい。

参考

・Amazon Kinesis Data Firehose のサブスクリプションフィルタ
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#FirehoseExample
・Amazon Athena のパフォーマンスチューニング Tips トップ 10
https://aws.amazon.com/jp/blogs/news/top-10-performance-tuning-tips-for-amazon-athena/
・Firehose料金
https://aws.amazon.com/jp/kinesis/data-firehose/pricing/