Kinesis Data Firehose を使って CloudWatch Logs を S3 へ 転送する 方法

0 件のコメント

今回は「Kinesis Data Firehose を使ってCloudWatch Logs にあるログを S3 へ転送する方法」についてまとめます。

概要

CloudWatch Logs の Log Group へ溜め込まれたログをS3へ流し込むための実装手順を見ていきます。 とりあえずログはすべてS3へまとめておくことができれば QuickSite や Athena への取り込みもできそうなので、その下準備になります。

今回は EC2 → CloudWatch Logs → Kinesis Data Firehose → S3 の流れを実装していきます。 作成するリソース類の全体は次のようなものになります。 実際に利用する際は適宜読み替え差し替えを行ってください。

上図の中で、今回は以下のリソースについてはすでに作成済みの前提で進めていきます。

  • CloudWatch Logs ロググループ(=転送元)
  • S3バケット(=転送先)

権限まわりの準備

CloudWatch Logs からは Kinesis Data Firehose への書き込みができる必要があるので、Firehose に対する書き込み権限を作っていきます。

sample-dev-firehose-write-iam-policy

まずは以下のようなIAMポリシーを作成します。

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "firehose:*"
      ],
      "Resource": [
        "arn:aws:firehose:<YOUR-REGION>:<YOUR-ACCOUNT-ID>:*"
      ]
    }
  ]
}

sample-dev-log-trans-firehose-iam-role

続いてIAMロールを…と行きたいのですが、マネジメントコンソール上から作成しようとすると「AWSサービス」に「CloudWatch Logs」が存在せず作成できません。 なので、いったん「EC2」などでIAMロールを作成し、作成したIAMロールの「信頼関係」タブから「信頼関係の編集」を選択して、以下の内容に書き換えます。

{
  "Statement": {
    "Effect": "Allow",
    "Principal": {
      "Service": "logs.<YOUR-REGION>.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
  }
}

「信頼関係」が書き換われば、あとは「アクセス権限」から作成済みの「sample-dev-firehose-write-iam-policy」をアタッチします。

Kinesis Data Firehose はS3へ対する書き込みが必要なので、S3に対する書き込み権限を作っていきます。

sample-dev-s3-write-iam-policy

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:AbortMultipartUpload",
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::<YOUR-BUCKET-NAME>",
        "arn:aws:s3:::<YOUR-BUCKET-NAME>/*"
      ]
    }
  ]
}

sample-dev-log-trans-s3-iam-role

Kinesis Data Firehose のIAMロールはマネジメントコンソール上から作成可能なのでそんなに迷うこともありません。 作成する際は作成済み「sample-dev-s3-write-iam-policy」をアタッチします。

Kinesis Data Firehose にロール付与しただけだとS3バケットポリシーにはじかれるので、バケットポリシーも見直します。 Principalにはサービス指定できなさそうだったのでロールで指定します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<YOUR-ACCOUNT-ID>:role/<YOUR-FIREHOSE-ROLE>"
      },
      "Action": [
        "s3:AbortMultipartUpload",
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::<YOUR-BUCKET-NAME>",
        "arn:aws:s3:::<YOUR-BUCKET-NAME>/*"
      ]
    }
  ]
}

Kinesis Data Firehose の作成

  1. New delivery stream

    インプット内容について設定していきます。

    Delivery stream name
    リソース名を指定します。今回は sample-dev-ec2-access-firehose
    Source
    インプット方法を指定します。 CloudWatch Logs の場合、 Direct PUT or other sources になります。
    Server-side encryption
    暗号化するかどうかの設定。今回は暗号化しないのでチェック無し。
  2. Process records

    データ整形をするかどうかの設定を行っていきます。 今回は行わないのですべて Disabled になります。 もしデータ変換を行いたいのであればここで設定することができます。

  3. Choose a destination

    アウトプット先について設定していきます。 今回はS3へアウトプットしていくのでS3に関する設定です。

    Destination
    Amazon S3」を選択します。
    S3 bucket
    保存先バケット名を指定します。 ログは1つのバケットに集約したいのでログ用バケット「sample-dev-log-bucket」を指定します。
    S3 prefix
    正常に取り込む場合の保管先フォルダ名を指定します。 …正しくは保管先キー名のプリフィックス指定です。 他のログと区別がつくように保管先パスを指定します。
    S3 error prefix
    エラー発生時のエラーログ保管先プリフィックス名を指定します。
  4. Configure settings

    その他オプションを設定していきます。

    S3 buffer conditions
    FirehoseはStreamと違ってバッファをとるのでその容量と期間を指定します。
    S3 compression and encryption
    圧縮と暗号化の設定です。 CloudWatch Logs はもともと圧縮された状態で転送されてくるので、改めて圧縮する必要はありません。 暗号化は必要に応じて設定します。 今回はどちらも利用しないので Disabled を指定します。
    Error logging
    エラーログを保存するかどうかの設定です。 保存先の設定と離れているので少しわかりづらいですが。。
    Permissions
    IAMロールを指定します。 あらかじめ作成済みなので作成したIAMロール「sample-dev-log-trans-s3-iam-role」を指定します。
  5. Review

    最終確認。設定内容を確認して問題なければ「Create delivery stream」で作成します。

CloudWatch Logs のサブスクリプションへ登録

残念ながらマネジメントコンソール上から CloudWatch Logs のロググループに Kinesis Data Firehose をサブスクリプションとして追加することができません。 AWS CLI を使ってコマンドから接続します。

以下のコマンドを実行して CloudWatch Logs の ロググループ に Kinesis Data Firehose のサブスクリプションを追加します。

aws logs put-subscription-filter \
    --log-group-name "<LOG_GROUP_NAME>" \
    --filter-name "<SUBSCRIPTION_FILTER_NAME>" \
    --filter-pattern "<SUBSCRIPTION_FILTER_PATTERN>" \
    --destination-arn "arn:aws:firehose:<YOUR_REGION>:<YOUR_ACCOUNT_ID>:deliverystream/<FIREHOSE_NAME>" \
    --role-arn "arn:aws:iam::<YOUR_ACCOUNT_ID>:role/<CWL_IAM_ROLE_NAME>

PowerShell の複数行指定で利用する行末文字は "`"(バックティック) で、 コマンドプロンプトで利用する行末文字は "^"(ハット) です。

ちなみに…なぜか PowerShell だと filter-pattern に空文字( "" )指定が正しく認識されず。。 コマンドプロンプトだと正しく認識されました。

まとめ

CloudWatch Logs のロググループに入ったログを Kinesis Data Firehose を使って S3 へ転送する方法を見ていきました。 残念ながらすべてをマネジメントコンソール上からすることはかなわず。。 ところどころ手動で対応する必要がある点が注意点です。

テスト実行したいときはEC2に対してロググループへ出力される操作をしてみることになります。 …今回は具体的な内容に触れていませんが。。

Kinesis Data Firehose より後ろであれば、 Kinesis Data Firehose にサンプルデータ出力のテストコマンド実行ができるのでそちらを試してみるのもアリかと思います。

今回は「Kinesis Data Firehose を使ってCloudWatch Logs にあるログを S3 へ転送する方法」についてまとめました。 参考になったでしょうか? 本記事がお役に立っていると嬉しいです!!

参考記事

最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!