はじめに

こんにちは、MSPチームの村上です。

先日、AWSから以下のようなイベント情報が通知されました。(一部抜粋)

現在、S3 ライフサイクルでは、レプリケーションが失敗した場合でも、対象であればオブジェクトが有効期限切れになるか、移行されます。
Amazon S3 は、レプリケーションステータスが FAILED の間、ライフサイクルがオブジェクトの有効期限切れや移行をブロックするように変更します。
レプリケーションが成功し、ステータスが COMPLETED に変わると、ライフサイクルはそれらのオブジェクトの処理を再開します。この更新により、
ライフサイクルがアクションを実行する前に、レプリケーション設定の問題 (誤った暗号化設定など) を特定して修正し、必要に応じてオブジェクトを再レプリケートする時間を確保できます。
この動作は、S3 ライフサイクルがレプリケーションステータスが PENDING のオブジェクトを処理する方法と一致しています。
推奨アクションは次のとおりです。

* 事前監視の設定: CloudWatch レプリケーションメトリクスを使用して障害の傾向を監視したり、
S3 イベント通知を有効にしてレプリケーションエラーが発生したときにアラートを受信したり、
S3 インベントリレポートを生成してレプリケーションステータスを確認します。

* ベストプラクティスの確認: レプリケーションのトラブルシューティングガイド [6] を参照して、レプリケーションルールが正しく構成されていることを確認します。

注: S3 Inventory や CloudWatch メトリクスなどのモニタリングツールを使用する場合、標準の AWS 使用料が適用される場合があります。

要約すると、S3のライフサイクルポリシーに仕様変更があります。
内容としては、レプリケーションの設定とライフサイクルポリシーを同時に適用しているS3バケットの場合、
レプリケーションに失敗したS3バケットはライフサイクルが機能せずに、問題が解決されるまで保留にする仕様となります。
つまり、レプリケーションに失敗したS3バケットは問題が解決しない限り残り続ける、ということになります。
ということは、ライフサイクルポリシーを設定していたS3バケットが残ってしまうということなので、その分AWS利用料がかかってしまいます。

もしも、そのS3バケットの容量が膨大でライフサイクルとレプリケーションを設定していた場合、知らず知らずのうちに不要なコストが掛かってしまう可能性が発生します。

対策としては、AWSからの通知内にもあるようにS3のイベント通知を設定し、アラートを発砲するようにすることが推奨されています。

そこで今回は、S3で発生したイベントをNew Relicで検知するように設定してみたのでその内容をまとめてみました。

設定概要

今回の設定の概要は以下のような形です。
・S3のレプリケーションエラーのイベント通知を設定
・イベント通知をNew Relicに送信するように設定(Amazon SNS、Amazon Data Firehoseストリームを使用)
・New RelicでログをNRQLでアラートを設定
流れとしては以下のような感じです。

いざ設定

まずは、New Relicの橋渡しの役割を持つAmazon SNS、Amazon Data Firehoseストリームを作成します。
SNSの設定は以下のブログで詳細に書かれていますのでご参照ください。

【初心者向け】S3レプリケーションの失敗をSNS通知で検知させてみた

Firehoseストリームは以下のような項目で設定します。

  • ソース・・・Direct Put
  • 送信先・・・New Relic
  • ストリーム名・・・任意
  • HTTP エンドポイント URL・・・New Relic ログ 米国(米国か欧州かはお使いのNew Relicに準じます)
  • APIキー・・・New Relicにて取得したInsert APIキー

次に、ライフサイクルポリシーとレプリケーションが両方とも有効になっている必要があるため、
どちらも有効にしたS3を作成します。

次にイベント通知の設定を有効化します。
今回は、オブジェクトのレプリケーションが失敗した時に通知を飛ばす設定にしました。
送信先は事前に作成しておいたSNSトピックを選択します。

AWS側の設定は以上です。

検証

次に実際にイベントが検知されているかNew Relic側で確認します。
検証方法としては、S3のレプリケーションに設定しているIAMロールをわざと権限が適切でないロールに変更してレプリケーションを失敗させます。

そして、S3バケットに適当なファイルをアップロードします。

S3のレプリケーションメトリクスに失敗したレプリケーションとして記録されていればOK

その後、New Relicのログに以下のようなログが記録されていれば検証成功です。

監視

New Relicで監視するには、以下のNRQLで検知できます。

SELECT count(*) FROM Log WHERE Message.Records LIKE '%"eventName":"Replication:OperationFailedReplication"%' 
AND Message.Records LIKE '%"eventSource":"aws:s3"%'

バケットとオブジェクト名も一緒に取りたい場合はこちら

SELECT count(<em>) FROM Log WHERE Message.Records LIKE '%"eventName":"Replication:OperationFailedReplication"%' 
AND Message.Records LIKE '%AWSアカウントID%' 
FACET capture(Message.Records, r'.</em>"bucket":{"name":"(?P[^"]+).<em>'), 
capture(Message.Records, r'.</em>"object":{"key":"(?P[^"]+).*')

最後に

今回はNew Relicを使ってS3のレプリケーションエラーの監視を検証しました。
監視する方法は他にも色々ありますのでご自身の環境、ツールに合った監視を実装していただければと思います。

New Relicを使っているどなたかの参考になれば幸いです。