8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CloudWatch Logs を長期保管してはいけない理由と、Subscription → Firehose → S3(Deep Archive) で約85%コスト削減できた話

Last updated at Posted at 2025-12-24

CloudWatch Logs の長期保管コスト、想像以上に高くないですか?

結論
CloudWatch Logs に長期保管するのは割高。
Subscription → Firehose → S3(Deep Archive) の方が安定運用&コスト最適でした。

先日、監査要件で「ログ18か月保存」が必要になり、CloudWatch Logs の料金を計算したところ…

18か月で $1,069.20 になる計算
→ さすがに高い!

そこで AWS 公式が「推奨」としている
Subscription → Firehose → S3
の構成に Deep Archive へのライフサイクル移行を組み合わせ、実際にコストを試算してみたところ、

約85%コスト削減
しかも自動で安定運用できる

という結果になりました。

本記事では

  • なぜ CreateExportTask が非推奨なのか(AWS 公式)
  • 実際にどれくらいコストが下がるか(計算式あり)
  • Subscription → Firehose → S3(Deep Archive) の構成と作り方

をまとめます。

CloudWatch Logs を長期保管してはいけない理由

監査要件や法的要件で「ログの数年保管」が必要になることが多いです。
しかし CloudWatch Logs に大量のログを保管するとコストが膨らみます。

  • 料金が高い(保管コストが重い)
  • 容量が増えるほど影響大
  • 長期保存前提のストレージには向いていない

結果、「どう長期保管すべきか?」が問題になってきます。

AWS 公式: Export Task が"非推奨"な理由と実際の制約

コンソールからだと、以下から S3 にエクスポートできます。
create_export_task.png

しかし日々の運用の中で実施していくので、できれば自動化したいです。
上記を自動化する場合、CreateExportTask という API を使います。AWS 公式ドキュメントはこちら。

これを Lambda や EventBridge Scheduler から定期的に呼び出すことになるのですが、AWS 公式ドキュメントには"定期実行非推奨"の注意書きがあります。

Note
We recommend that you don't regularly export to Amazon S3 as a way to continuously archive your logs. For that use case, we instead recommend that you use subscriptions. For more information about subscriptions, see Real-time processing of log data with subscriptions.

日本語訳はこちら。

注記
ログを継続的にアーカイブするために Amazon S3 に定期的にエクスポートすることはお勧めしません。そのようなユースケースでは、サブスクリプションのご利用をお勧めします。サブスクリプションの詳細については、「サブスクリプションによるログデータのリアルタイム処理」をご覧ください。

また、同時実行1件の制限があり、複数ロググループ・多期間分をエクスポートしようとすると、タスクが詰まって失敗や遅延の原因になります。
こう考えると安定性に欠けるので、監査要件向けの長期保存には向かないことが分かります。
AWS 公式ドキュメントにある通り、サブスクリプションの利用がよさそうです。

AWS 推奨アーキテクチャ(Subscription → Firehose → S3)

AWS の推奨は CloudWatch Logs サブスクリプションフィルターを使うことです。公式ドキュメントはこちら。

Firehose を使うのでリアルタイム転送で手動オペレーション不要、安定して長期保管できそうです。
運用もほぼ放置でよさそうです。

しかし、この構成を見たときに「なんだかコストがかかりそうだな。転送しないほうが安かったりしないだろうか。」と思い、比較してみました。

コスト比較: CloudWatch Logs vs Subscription → Firehose → S3(Deep Archive)

結論
18か月運用すると Subscription → Firehose → S3(Deep Archive) の方が約85%安い。

注意
保管期間が 2か月以下 の場合、コストが逆転するケースがあります。
本記事の結論は、あくまで 長期保管を前提 としたものです。

前提条件

以下の条件で比較してみます。

  • 保管期間: 18か月
  • 毎月: 100GB
  • 東京リージョン料金: 2025年12月時点
    • CloudWatch保存: $0.033/GB・月
    • Firehose配信: $0.036/GB
    • S3標準: $0.025/GB・月
    • Glacier Deep Archive: $0.002/GB・月
  • ケース1: CloudWatch Logs に全期間(18か月)残す
  • ケース2: CloudWatch Logs は解析用に2週間だけ残し、同時に Firehose → S3標準 → 1日後 Glacier Deep Archive 移行

比較表

項目 ケース1 計算式 ケース2 計算式
CloudWatch Logs保存 $1,069.20 0.033 * (100 * 18) * 18 $27.72 0.033 * (100 * 14 / 30) * 18
Firehose配信 - - $64.80 0.036 * 100 * 18
S3標準ストレージ(1日分) - - $1.50 0.025 * (100 * 1 / 30) * 18
Glacier Deep Archive保存 - - $64.80 0.002 * (100 * 18) * 18
合計 $1,069.20 - $158.82 -
差額 - - 約 $910.38(約85%削減) -
  • 補足
    • 平均保管量
      • 2週間保存: 月ログ量 * (14 / 30) = 100 * 14 / 30

結論

解析用に2週間だけ CloudWatch Logs に残し、古い分を Deep Archive へ移すと、18か月保管で約85%コスト削減が可能。
ちゃんと安くなるので設定していきます。

Firehose で CloudWatch Logs を S3(Deep Archive) に転送する設定方法

1. 出力先の S3 バケットを作る

出力先の S3 バケットを作ります。
create_s3_bucket_1.png
create_s3_bucket_3.png

次にライフサイクルルールを作ります。
s3_lifecycle_policy_1.png

赤枠部分を入力していきます。
s3_lifecycle_policy_2.png

1日で Glacier Deep Archive に移行するよう設定し作成します。
s3_lifecycle_policy_3.png

作成できると以下のような表示になります。
s3_lifecycle_policy_4.png

2. Firehose ストリームを作る

Firehose ストリームを作ります。
ソースを「Direct PUT」、送信先を「Amazon S3」とします。
create_firehose_stream_2.png

作成した S3 バケットを設定します。
create_firehose_stream_3.png

作成します。裏で IAM ロールが作成されます。
create_firehose_stream_4.png

作成できると以下のような表示になります。少し時間がかかるかもしれませんが、ステータスも「アクティブ」になります。
create_firehose_stream_5.png

3. CloudWatch Logs のサブスクリプションフィルター用の IAM ロールを作る

CloudWatch Logs のサブスクリプションフィルター用の IAM ロールを作ります。
AWS 公式ドキュメントを参考に作ります。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#FirehoseExample

許可ポリシーは以下の通り。
region、account-id、delivery-stream-name は書き換える必要があります。

{
    "Statement": [
        {
            "Effect":"Allow",
            "Action": [
                "firehose:PutRecord"
            ],
            "Resource": [
                "arn:aws:firehose:region:account-id:deliverystream/delivery-stream-name"
            ]
        }
    ]
}

信頼ポリシーは以下の通り。
region、account-id は書き換える必要があります。

{
    "Statement": {
        "Effect": "Allow",
        "Principal": {
            "Service": "logs.amazonaws.com"
        },
        "Action": "sts:AssumeRole",
        "Condition": { 
            "StringLike": {
                "aws:SourceArn": "arn:aws:logs:region:account-id:*"
            } 
        }
    }
}
4. CloudWatch Logs のサブスクリプションフィルターを作る

CloudWatch Logs のサブスクリプションフィルターを作ります。
subscription_filter_main.png

作成した Firehose ストリーム、サブスクリプションフィルター用の IAM ロールを選択します。
create_firehose_subscription_filter_3.png

サブスクリプションフィルター名を入力します。
create_firehose_subscription_filter_4.png

ストリーミングを開始します。
create_firehose_subscription_filter_5.png

開始できると以下のような表示になります。
create_firehose_subscription_filter_6.png

5. 確認

出力先の S3 バケットを見てみます。
設定した後のログイベントから転送されるので、まだ空っぽです。
check_1.png

確認のために、ログイベントを作成します。
check_2_1.png
check_2_2.png

しばらくするとオブジェクトが出来上がっていました。年月日時のフォルダーも自動で作ってくれています。これで自動アーカイブの完成です。
check_3.png

まとめ

  • Export Task は非推奨(AWS公式)
  • Firehose が最も運用しやすく現実解
  • S3 ライフサイクルルールで長期アーカイブするとコスト最適化

短期間のログ保存であれば CloudWatch Logs のままでも十分ですが、半年〜数年単位での保管が前提になる場合は、Subscription → Firehose → S3(Deep Archive) が現実解だと感じました。
長期保管が必要になったタイミングで、構成を見直す価値があります。
同じようにログの保管コストで悩んでいる方の参考になれば幸いです。

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?