AWSのログ管理についてはいくつか考えるポイントがあると思います。
- どのログを保存するか。
- CloudWatch Logs(以下CW Logsと記載)とS3のどちらに保存するか、もしくは両方に保存するか
などなど。
システムの特性によるところも多いかと思いますが、自分の中でのログ管理のベースラインが定まりつつあるので、頭の整理がてらまとめます。
自分の中での大まかな方針としては以下です。
- S3に保存できるものは基本S3に保存する。
- 以下の場合は、CW Logsに保存する。必要に応じてS3に転送する。
- アラームを出したい場合
- さっとCW Logs Insightでログを確認したい場合
- CW Logs に出さざるを得ない場合
全体像としては以下になります。
なおあくまで個人的な経験に基づくものなので、実際にはシステムの特性を踏まえて方針の決定が必要かと思います。 またこれは必要、これは不要などご意見あればいただけると非常に嬉しいです。
前提
ログの格納先について
今回はAWS内で完結させること(他のSaaS等は使用しない)を前提にしています。
また格納先としてはCW Logs 、またはS3で考えます。観測範囲にはなりますが、この2つのいずれかに保存し参照をすることが多いためです。
なおCW Logs やS3ほど多くはないない印象ですが、要件によってはOpenSearchにログを保存して、ニアリアルタイムで確認するというのもよくやるパターンです。今回大きくは取り上げません。
料金について
以下ログを保存、格納するための料金です(2023/3/17時点の東京リージョン)。
CW Logs | S3 | |
---|---|---|
格納 | 0.76USD/GB | 0.0047USD/1000リクエスト |
保存 | 0.033USD/GB | 0.025USD/GB |
よく言われることですが CW Logs の格納(Put)が特に高いです。「格納」でお金がかかるため、コストを抑えるためにはCW Logsになるべくログを取り込まないようにする必要があります。
一方で「保存」に関してはややCW Logs の方が高いものの、大きな差はありません。そのため「保存」のコスト削減だけを目的にCW Logs からS3へ転送する仕組みを用意するというのはあまり得策ではないように思われます。
格納先の判断基準
CloudWatch Logsへの格納
料金を踏まえるとなるべくCW Logs には格納せず、S3に寄せる方が良いです。しかしそうであってもCW Logsに格納したいケースはあるかと思います。
観測範囲でよく見るユースケースを以下に示します。
- ①CW Logsでログをさっと確認したい場合。S3に格納するとAthenaを使用する等多少のオーバーヘッドがあります。CW Logsだとマネコン上でロググループを更新して最新のログをすぐ見たり、CW Logs Insightsに文字列だけでgrepしたり等がしやすく、クイックに確認することができます。ただし商用環境だとログが大量に出て、CW Logsだと逆に調査しづらいということも起こり得るので考慮が必要です。
- ②ログを元にアラートを行いたい場合。アプリの実行ログでエラーが吐かれた場合にサブスクリプションフィルターを活用して、通知するというのがよくあるパターンです。
- ③CW Logsに出さざるを得ない場合。サービスによってはCW Logsにしか格納できない場合もあります。
なお CW Logsの保持期間が「期限なし」になっており、不要なものが残り続けているのはあるあるです。適切な保持期間を設定するようにした方が良いです。
S3への格納
CW Logsに保存する必要がないもの、もしくはCW Logsに保存するがS3にも保存しておきたいものはS3に保存することになります。
保存のパターンとしては以下になります。
- ①直接格納を行うパターン。サービス側でS3への格納がサポートされている場合該当します。
- ②Firehoseで配信するパターン。S3への格納はサポートされていないが、Firehoseによる配信がサポートされている場合はFirehose経由でS3に格納します。
- ③CW Logsから転送するパターン。サブスクリプションフィルタを元にCW LogsからFirehoseでS3にも転送します。
- ④CW Logsから転送するパターン。CW LogsからS3にエクスポートするためのAPIを実行します。
S3にのみ格納するパターン(①、②)
パターン①、②がCW Logsに保存せず、S3に保存するパターンです。基本はこれらを使います。
CW Logs → S3に転送するパターン(③、④)
CW Logsにしかログ出力ができないがS3にも保存したい場合です。
CW Logsにも格納していることから、CW Logsの「格納」の料金はかかってしまいコスト削減という点では効果が薄いです。その点を踏まえてもS3に転送したいケースとしては以下が考えられます。
- ログの量が非常に多く「保存」におけるCW LogsとS3の料金の違いが無視できないレベルの場合。
- ログを「安全に」保管したい場合。S3の場合、バージョニングによるログ誤削除への対策、オブジェクトロックにより削除不可にする、S3へのアクセスログを取る等、安全に保管するための設定がいくつかあります。特に監査ログを保存する場合は重要になるかと思います。
では③と④どちらが良いかという話になりますが、個人的には基本は③とし、Firehoseのコストが気になる or たまにしかエクスポートしないであれば④で考えることが多いです。理由として④のCreateExportTaskには以下のような制約があるためです(参考リンク)。
- 1リージョンで同時に1つしか実行できない。大量にエクスポートする場合は実行タイミング等を考慮する必要があります。
- 気をつけないと欠損する可能性がある。ログをエクスポートできるためには時間がかかる(ドキュメントだと最大12hと記載)ため、エクスポートするタイミングや時間の範囲を気にする必要があります。例えば毎月1日に前月のログをエクスポートするということを行うと前月最終日のログが欠損する可能性があります。
上記のため、④のCreateExportTaskを使用するのは、単発でエクスポートしたい場合や、念のためS3にエクスポートしておきたい程度の場合が多いです。
なお④で定期的にエクスポートするときはLambdaを実装することが多かったですが、2022/11にGAとなったEventBridge Schedulerで直接CreateExportTaskを実行できるため、今後はこちらを使用するのが基本になるかと思います。
Glacierへのアーカイブについて
S3への長期保存時にGlacierへのアーカイブを検討することがあるかと思います。
しかしGlacierにアーカイブする場合PUTの料金がかかり、小容量多ファイルの場合は逆効果となる可能性があります。アーカイブを検討する際はログファイルのサイズや保存期間を踏まえて検討が必要かと思います。
アクセスログやセキュリティサービスのログはサイズが小さいので、Glacierにアーカイブするメリットはないという印象です。
<参考リンク> dev.classmethod.jp
具体的なログ取得例
以下よく使うサービスごとに取得することが多いログや考慮点を記載していきます。
1. セキュリティログ
セキュリティ関連のサービスが出力するログです。
CloudTrail
CloudTrailではAPI Callのログを出力します。このログの保存はセキュリティ観点を踏まえると必須と言って良いかと思います。
CW Logsへの出力は不正なAPI Call発生時にアラートを出すために行うことが多いです。基本的にS3にも保存しているため、CW Logsにおける保存期間は最小限にすることが多いです。詳細は以下の記事にも記載しています。
S3への保存は当然行うとして、CloudTrailのログは監査の観点を踏まえても非常に重要なものであるため、他のログ以上に厳重に管理する必要があるかと思います。この辺りのベストプラクティスについては公式ドキュメントに記載されています。
個人的には以下のBlackbeltの資料がよくまとまっており参考になりました。特にオブジェクトロックはログの不正削除ができなくなるため、可能な限り有効化しておきたいところです。
https://d1.awsstatic.com/webinars/jp/pdf/services/20210119_AWSBlackbelt_CloudTrail.pdf
Config
Configでは設定変更とスナップショットを出力します(参考リンク)。
設定変更はセキュリティ観点的にも記録しておきたいところです。ただし開発時から全て記録すると、かなり料金がかかってしまいます。
そのため以下のような手段を取ることが多いです。
- 開発用の環境では記録しない or 一部の重要なリソースを記録する(頻繁にリソースの変更を行うため、不要な変更記録は避ける)。
- 本番環境では初期構築後に有効化し、極力記録するようにする(初期構築後の変更を記録する)。
<参考リンク> dev.classmethod.jp
スナップショットの取得周期は 1h/3h/6h/12h/24h のいずれかから設定可能です(CloudFormationのリンク)。
ただしIaCで構築している場合はコードで設定内容が確認できるため取得しないことも多いです。
GuardDuty
検出結果のログを格納可能です。マネコン上でも90日間は保持されます。そのため保存したいケースとしては以下のような場合が考えられます。
- 90日間以上検出結果を保存しておきたい場合
- 検出結果を別途分析したい場合
Q: GuardDuty では セキュリティの検出結果をどのくらいの間利用できますか?
セキュリティの検出結果を、GuardDuty コンソールおよび API を通じて 90 日間保持および利用できます。90 日経過した後、検出結果は破棄されます。検出結果を 90 日以上保持するには、EventBridge を有効にして、検出結果をアカウントや他のデータストア内の S3 バケットに自動的にプッシュします。
よくある質問 - Amazon GuardDuty | AWS
2. アクセスログ
リクエストによって発生する通信のログになります。基本的にS3に格納する形になります。
CloudFront
大きな違いとしては配信タイミングがあり、標準ログは1時間以内に配信するが最大24時間遅れる可能性あり、リアルタイムログは数秒以内の配信となっています。
アクセス異常時の調査などに使用する可能性がある場合は基本的にリアルタイムログを取得するのが望ましいかと思います。
API Gateway
CW LogsとFirehoseの2つがありますが、FirehoseからのS3配信で事足りることが多い印象です(メトリクスでアラートが発生したら、Athenaでログを調査するイメージ)。
ALB, WAF, Roure53, VPC
この辺りはS3バケットに出すのみのことがほとんどです。
基本的にはメトリクス監視で何か問題を検知した時に、必要に応じてログを調査するという形になるため。
3. バックエンドログ
主にバックエンドにおけるアプリ実行時のログを指します。
EKS, ECS, EC2, Fargate
CW Logsの「格納」の料金が最も問題になるポイントの1つがここなんじゃないかと思っています。
アプリの実行ログをCW Logsに大量に出力し、コスト増加というのはよくある気がします。パターンとしては以下のようにすることが多いです。
- 極力fluentd, fluentbit (Firelens) を使用してエラーログとログ全般の格納先を分岐させコストを削減する。エラーログはCW Logsにのみ(最小限)転送し、アラートに使用する。ログ全般はS3に格納しコストを削減する。
- ログの出力が少ないアプリであれば、一律CW Logsに出力し、必要に応じてFirehose経由でS3にも転送するということをやることはあり。
前者をECSでCDKでやる方法は以下の記事で紹介しています。
また図で記載していますが、踏み台サーバーのログはSession Managerで設定可能です。基本はS3に溜めておきますが、誰かが作業を始めた時に通知させたい場合はCW Logsにも格納してアラートを出すということはあります。
Lambda
Lambdaの実行ログを格納します。
基本的にCW Logsへの出力のみなので、CW Logsに出力し必要に応じてFirehoseでS3に転送しています。
なおLambda Extensionsを使用すればS3にログを出力することが可能のようです(私は使ったことなし)。
4. データベースログ
データベースに関するログになります。
RDS, Aurora
DBエンジンによって出力するログが微妙に異なります。ここでは個人的によく使うRDS/Auror MySQLで記載します。以下4種類のログがあります。
- 一般ログ:取るかどうかは場合によります。全てのSQLが出力されるため、ログが多くなる懸念があります。Performance Insightsやアプリ側のログで事足りることもあるのでその場合は出力しないこともあります。
- スロークエリログ:これは基本的に取得するようにしています。スロークエリ発生時に確認するため。
- エラーログ:デフォルトで有効化されている。
- 監査ログ:こちらは要件次第かと思います。必要な場合は取得します。
また記載時点ではログは基本的にCW Logsに直接出すしかないためそのようにします(S3に直接出せるようにならないかなあ...)
監査ログに関しては長期かつ厳重に保存が必要になることが多いためS3バケットにも転送します。他のログを転送するかは場合によります。
なおエラーログ以外は明示的に出力設定が必要な点に注意が必要です。
ElastiCache
ElastiCacheではスローログとエンジンログの2つを出力します。それぞれ CW Logs or Firehoseのどちらに出力するか選択可能です(参考リンク)。
スローログは量が多くなく、さっと見たいためCW Logsとすることが多いです。
エンジンログはFirehose経由でS3に保存しておき、何かあった際に見ることはあります。
5. その他サービスログ
ここは上記以外のサービスです(CodeBuildはあくまで一例)。
サービスにもよりますが、ログの重要度が低い場合はCW Logsにのみ保存し必要期間が経過したら削除、念のためS3に保存しておきたいものはCreateExportTaskを用いてどこかのタイミングでエクスポートとすることが多いです(例えばCodeBuildのビルドログを長期で保存しておいて後で必要になることは多くない印象...)。
削減すればいいというものではないですが、不要なものを長期保存すると料金や運用負荷が高くなるので、システムの特性を踏まえて判断していく必要があるかと思います。
その他
S3に格納したログ(特にセキュリティログ、アクセスログ)はPartition Projectionを活用してAthenaで調査しやすくすることをよくやります。CDKでの実装例は以下で紹介しています。
また、セキュリティインシデント調査のための基盤として、SIEM on Amazon OpenSearch Service が公開されています。セキュリティインシデント調査のための基盤やダッシュボードを作りたい場合は活用できそうです。
ワークショップもあるので興味があれば触ってみるのが良いかと思います。
catalog.us-east-1.prod.workshops.aws
おわりに
CW Logsは便利ですがやはり少し高い、、、
あとはCW Logs→S3へのエクスポートもマネージドな仕組みができないかなあと思っています(悩みが一つ減るので)。