
AWS DataFirehose をCloudFormationで構築
はじめに
AWS環境を運用するうえで、システムの状況確認や障害発生時の調査を行うためには、ログを取得・保管することが重要です。
AWSでは、CloudWatch Logsを利用することで、EC2や各種AWSサービス、アプリケーションなどから出力されるログを収集できます。特に、障害調査や原因分析を行う際には、より細かいログ情報が必要になる場合があります。そのため、CloudWatch Logsを利用して詳細なログを収集し、必要なときに確認できるようにしておくことが有効です。
しかし、ログを詳細に取得し続ける場合、CloudWatch Logs上に大量のログが蓄積されていきます。そのため、ログを長期間CloudWatch Logsに保持すると、ログの保存量に応じてコストが発生します。
そこで本記事では、CloudWatch Logsでログを収集しつつ、長期間保存したいログについてはS3へ保存する構成を構築します。
CloudWatch Logsに出力されたログをS3へ直接保存するのではなく、今回はData Firehoseを使用します。
Data Firehoseを利用することで、CloudWatch Logsに収集されたログを自動的にS3へ配送できます。
今回構築するログの流れは以下のとおりです。

今回の記事では、CloudFormationを使用して上記の環境を構築し、実際にCloudWatch Logsへテストログを出力した後、そのログがData Firehoseを経由してS3に保存されることを確認します。
対象の読者
本記事は、以下のような方を対象としています。
・ CloudWatch Logsに収集したログをS3へ保存したい方
・ Data Firehoseを実際に構築して動作を確認してみたい方
・ CloudFormationを使用してAWSリソースを構築してみたい方
本記事では、CloudWatch Logs、Data Firehose、S3を組み合わせた構成を実際に構築し、CloudWatch Logsに登録したテストログがS3へ保存されるまでの流れを確認します。
使用するAWSサービス
構築する各リソースの役割は以下のとおりです。
・CloudWatch Logs:ログの収集
・Data Firehose :ログの配送
・S3 :ログの保存
・IAM :AWSサービス間のアクセス権限を設定
構築するAWSリソース
CloudFormationを使用して、以下のリソースを構築します。
今回の検証では、できるだけ構成をシンプルにするため、EC2やKinesis Data Streams、Lambdaなどの追加リソースは使用しません。
また、Data Firehoseへのデータ投入方式にはDirectPutを使用します。
・S3バケット
・CloudWatch Logs Log Group
・Data Firehose
・Data Firehose用IAM Role
・CloudWatch Logs用IAM Role
・CloudWatch Logs Subscription Filter
各サービスの設定
①S3の設定
ログの保存先となるS3バケットには、以下の設定を行います。
今回はData Firehoseの動作確認を目的としているため、暗号化にはSSE-S3を使用します。
・パブリックアクセスをブロック
・SSE-S3による暗号化
・logs/ 配下にログを保存
・FirehoseからS3へログを書き込むためのIAM Roleを設定
②CloudWatch Logsの設定
ログの送信元となるCloudWatch Logsには、以下の設定を行います。
作成したLog Streamへテストログを登録し、そのログがData Firehoseを経由してS3へ保存されることを確認します。
・CloudWatch LogsにはLog Groupを1つ作成
・検証環境のためログの保持期間は1日
・Subscription Filterを設定し、CloudWatch Logsに登録されたログをData Firehoseへ送信
③IAM Roleの設定
今回の構成では、AWSサービス間の連携にIAM Roleを使用します。
主に以下の2つのIAM Roleを作成します。
・CloudWatch Logs → Data Firehose
CloudWatch LogsがData Firehoseへログを送信するためのIAM Roleです。
・Data Firehose → S3
Data FirehoseがS3へログを書き込むためのIAM Roleです。
④Amazon Data Firehoseの設定
CloudWatch Logsから送信されたログを受け取り、S3へ配送するData Firehoseには、以下の設定を行います。
・データ投入方式にはDirectPutを使用
・データを受け取ってから1分経過、またはバッファサイズが1MBに達した場合にS3へ配送
・S3へ配送する際にGZIP形式で圧縮
・通常のログはS3バケットのlogs/配下へ保存
・配信処理でエラーになったデータはS3バケットのerrors/配下へ保存
CloudFormationテンプレート作成
まず、今回構築するAWSリソースをCloudFormationで作成します。
CloudFormationのテンプレートをyamlファイルで作成し、以下のコードを記述します。





CloudFormationでスタック作成
AWSマネジメントコンソールからCloudFormationを開きます。
「スタックの作成」から「新しいリソースを使用」を選択し、作成したCloudFormationテンプレートをアップロードします。

スタック名には以下を指定します。
・firehose-minimal

スタックデプロイオプションは、検証用のため「すべてのリソースをロールバック」と「新しく作成されたリソースを削除する」を選択し、スタックの作成に失敗した場合に、作成したリソースを削除してロールバックするように設定します。

テンプレートの内容を確認し、「送信」を押下しスタックを作成します。
CloudFormationで作成されたリソースを確認する
スタックの作成が完了したら、「リソース」タブを開きます。
今回のテンプレートでは、以下のリソースが作成されます。
・LogBucket
・LogGroup
・FirehoseRole
・CloudWatchLogsRole
・FirehoseDeliveryStream
・SubscriptionFilter
すべてのリソースが正常に作成されていることを確認します。

また、「出力」タブでは、以下の情報を確認できます。
・LogGroupName
・FirehoseName
・S3BucketName
後の動作確認で使用するため、これらの値を確認しておきます。

Data Firehoseの状態を確認
AWSマネジメントコンソールから、
Amazon Data Firehose → Firehose ストリーム
を開きます。
CloudFormationで作成したDelivery Streamを選択します。
Delivery Streamの状態がアクティブとなっていることを確認します。
今回の構成では、CloudWatch Logsから送られてきたデータをData Firehoseが
受け取り、S3へ配送します。
CloudWatch LogsのLog Groupを確認
CloudWatchコンソールから、CloudWatch → ログ → ロググループを開きます。
CloudFormationで作成したLog Groupを選択します。

Log Groupの中にLog Streamを作成します。
今回は以下の名前とします。
・test-stream

PRLog Streamにテストログを追加する
作成したLog Streamに、CloudWatch Logsのコンソールからテストログを追加します。
CloudWatch Logsの対象Log Groupを開き、作成した「test-stream」を選択します。
Log Streamの画面で「アクション」を選択し、「ログイベントの作成」を選択します。
表示された入力欄に、テストメッセージを入力します。
今回は以下の文言とします。
test log message
画面を再読み込みし、入力したログがLog Streamに表示されることを確認します。

S3へのログ出力を確認
テストログを作成したら、今回のFirehoseではバッファリング設定を行っているためData FirehoseがS3へログを配送するまで少し待ちます。
バケット内に、logs/というプレフィックスが作成されていることを確認します。

その配下に、GZIP形式でログファイルが保存されます。
これで、ログ配送が正常に動作していることを確認できます。


検証終了後のリソース削除
今回の環境は検証用のため、動作確認が終了したら不要なAWSリソースを削除します。
CloudFormationのスタックを削除することで、スタックによって作成したリソースをまとめて削除できます。
今回のS3バケットには、以下を設定しています。
DeletionPolicy: Delete
UpdateReplacePolicy: Delete
ただし、S3バケットは空でなければ削除できません。CloudFormationで「DeletionPolicy: Delete」を指定していても、バケット内にオブジェクトが残っている場合は削除に失敗します。
そのため、CloudFormationのスタックを削除する前に、S3バケット内のテストログを削除しておきます。


一方、今回作成したCloudWatch LogsのLog Streamについては、Log Stream内のログを事前に削除する必要はありません。
CloudFormationが管理している「AWS::Logs::LogGroup」を削除すると、Log Groupに保存されているログイベントもまとめて削除されます。
Log Streamにテストログが残っていること自体は、S3バケットのような削除失敗の原因にはなりません。
したがって、今回の検証環境を削除するときは、以下の流れで問題ありません。
② S3バケット内のオブジェクトを削除
②CloudFormation スタックを削除(Log Group・Log Streamも含めて削除される)
①を実施後、CloudFormation スタックを削除するにあたり、AWSマネジメントコンソールからCloudFormationを開きます。「スタック」から今回作成したスタックを選択し、「スタックの削除」を押下します。
画面を更新し、対象のスタックが存在しないことを確認できれば完了です。
まとめ
今回は、CloudWatch Logsに収集したログをData Firehose経由でS3へ保存する環境を、AWS CloudFormationを使用して構築しました。
CloudWatch Logsをログの収集・確認に利用し、長期間保存するログはS3へ配送することで、それぞれの用途に応じてログの保存先を分ける構成を実現できます。
また、CloudFormationを利用することで、AWSリソースの構成をコードとして管理できるため、同じ環境を必要に応じて再構築することができます。
なお、今回は動作確認を目的とした最小構成としましたが、実際の運用環境では、要件に応じて設定を追加で検討する必要があります。
CloudWatch LogsとS3を用途に応じて使い分けることで、ログの確認性と長期保存を両立した構成を実現できます。
CNSについて
CNSではAWSを取り扱う案件を数多く支援してきた実績があります。
AWSに限らずクラウド環境構築でお困りの方は、お気軽にご相談下さい。
こちらの発言は全て個人的意見です。内容につきましては、十分注意し投稿しておりますが、誤りがあれば直接ご指導頂けますとありがたいです。
CNS Tech Blog Beyond|CNS シイエヌエス - BEYOND THE RIGHT ANSWER.: 株式会社シイエヌエス
▶ お問い合わせフォームはこちら:
https://reg34.smp.ne.jp/regist/is?SMPFORM=ofte-lerand-a156f4b7d094ddf7db06c166e8de81dd


