NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

手動は卒業!AWS Lambdaによるレポート作成自動化

はじめに

こんにちは、クラウド事業推進部一年目の山本です。
クラウド事業推進部の中でもインフラ系のチームに配属されて、分からないことだらけですが、日々多くの学びを吸収しています。

いきなりですが「インフラ」と聞くと、縁の下の力持ちのようにアプリを裏側から支えていくようなイメージが想像できます。そうなると、業務としてはシステムを安定的に稼働させる運用業務が多くなります。この運用業務には、毎月決まってやらなければならない作業(以下、月次作業という)があり、案件の増加に比例して月次作業もどんどん増えていき、運用の負荷は高まる一方です。そこで、今回は手動で行っている月次作業を自動化し、運用負荷を減らすことに挑戦してみました。

本記事では、私が担当した月次作業の自動化についての学びや経験を共有したいと思います。

やってみた

今回やりたいこと

◎Amazon CloudWatchメトリクスのグラフ画像を取得し、その画像をExcelに貼り付けてレポートを作成する工程を自動化したい!!

使用する技術

今回は、AWS Lambdaを主軸に実装しました。
以下で、使用する技術について簡単に説明します。

AWS

  1. AWS Lambda
    AWSが提供するサーバーレスコンピューティングサービスです。開発者は、サーバの管理やプロビジョニングを気にせずにコードを実行することができます。
    今回は、ランタイムにPython3.10を選択をしました。

  2. Amazon S3
    AWSが提供するオブジェクトストレージサービスです。データの保存、管理、保護が簡単になり、さまざまなユースケースに利用することができます。

  3. Amazon EventBridge
    AWSが提供するサーバーレスイベントバスサービスです。さまざまなアプリケーションやサービス間でイベントを簡単に送受信できます。定期的なタスクやイベント駆動型のワークフローを自動化することもできます。

Python

  • Boto3
    AWSのサービスをPythonから操作するためのSDK(ソフトウェア開発キット)です。
    今回はS3やCloudWatchメトリクスの読み書きを行うために使用します。
    ちなみに名前の由来はアマゾン川に生息するアマゾンカワイルカからきているそうです。
    Boto3のREADMEに以下の記載がありました。🐬

Boto (pronounced boh-toh) was named after the fresh water dolphin native to the Amazon river.
引用元:boto3/README.rst at develop · boto/boto3 · GitHub

構成

今回の全体的な処理としては、まずAmazon EventBridgeにより、毎月の指定した日時にAWS Lambdaを実行します。次に、AWS LambdaがAmazon CloudWatchのグラフ画像からレポートを作成し、レポートファイルをAmazon S3バケットに出力します。
構成図は以下になります。

構成図の画像
構成図

実装の流れ
  1. 設定ファイルの準備
    まず初めに、AWS LambdaがAmazon CloudWatchからグラフ画像を取得するために、必要な情報をまとめた設定ファイルを作成します。 ここで言う必要な情報は、メトリクスイメージAPIのことです。 メトリクスイメージAPIとは、Amazon CloudWatchメトリクスのデータを視覚的に表示するための機能です。
    以下のように取得したいメトリクスのグラフ画面で、「発信元」タブの「表示」から「イメージAPI」を選択することで取得できます。

    イメージAPI取得方法の画像
    イメージAPI取得方法
    必要な各グラフのメトリクスイメージAPIをテキストファイルにまとめ、Amazon S3フォルダに格納します。

  2. IAMポリシー、IAMロールの作成
    AWS LambdaとAmazon EventBridge用にIAMポリシーを作成し、それぞれのIAMロールにアタッチします。
    IAMロールを次工程で作成するリソースにアタッチすることで、AWS LambdaがAmazon S3を触れるようにしたり、Amazon EventBridgeからAWS Lambdaを呼び出すことができるようになります。

  3. Amazon S3、AWS Lambdaの作成
    ■Amazon S3
    今回の用途は以下の通りです。
     ①AWS Lambdaで使用する設定ファイルの置き場
     ②Amazon CloudWatchメトリクス画像の一時保存場所
     ③作成したレポートの格納場所
    ■AWS Lambda
    今回作成するAWS Lambdaの大まかな処理の流れは以下の通りです。
     ① 設定ファイルからAmazon CloudWatchメトリクス画像を取得する。
      →コード部分には、Boto3のget_metrics_widget_imageメソッドを実装しました。
     ② 取得したAmazon CloudWatchメトリクス画像を一時的にAmazon S3フォルダに格納する。
      →コード部分には、Boto3のput_objectメソッドを実装しました。
     ③ ②でAmazon S3に保存した画像を読み込みAWS Lambdaの一時ディレクトリに保存する。
      →コード部分には、Boto3のlist_objects_v2メソッド、download_fileメソッドを実装しました。
     ④ 読み込んだ画像をExcelに張り付ける。Excelにタイトルや文字を挿入し、レポートを作成する。
      →コード部分には、Excelへの操作を行うためのモジュールである「openpyxl」をインポートして実装しました。
     ⑤ 作成したレポートをAmazon S3に格納する。
      →コード部分には、Boto3のupload_fileメソッドを実装しました。
     ⑥ AWS Lambdaの一時ディレクトリ、一時的に画像を保存しているAmazon S3フォルダを初期化する。
      →コード部分には、Boto3のdelete_objectメソッドを実装しました。

    AWS Lambdaの処理の流れ図の画像
    AWS Lambdaの処理の流れ図

  4. Amazon EventBridgeによる定期実行の設定
    今回は月次作業のため、cron式による定期実行を実装します。
    実装例として、毎月1日の12時0分に実行したい場合は、以下のように設定します。

    cron式の実装例の画像
    cron式の実装例

    上図のcron式を簡単に説明すると、以下の通りとなります。
    特殊文字「*」 : 「全て」を意味し、毎時や毎月などの連続した処理を実行したい場合に使用します。
    特殊文字「?」 : 「フィールドが持つスケジュール条件を無視する」ことを意味し、「毎月1日に実行する」場合の
            曜日の条件といった指定する必要がないフィールドに対して使用します。

出力イメージ

今回の実装によって出力されるレポートのイメージは以下の通りです。レポートのタイトルやその他の文字を挿入すること、グラフの縦軸の値や表示期間を調整することも可能です。

サンプルレポートの画像
サンプルレポート

つまずきポイント

  • イメージ APIのBoolean値
    Amazon CloudWatchからメトリクス画像を取得する際に、イメージAPIという取得したい画像の情報が入ったものを設定ファイルに記載していますが、このAmazon CloudWatch MetricsのイメージAPIのBoolean値は「true/false」で出力されるので、「True/False」に修正するとうまく読み込むことができます。

  • イメージ APIのtitleの値
    イメージAPIのtitleの値は、日本語非対応のため、日本語でタイトルを設定しようとすると画像を取得する際に文字化けしてしまうので注意が必要です。

  • 外部モジュールの読み込み
    画像のサイズをカスタムしたり、Excelに貼り付けたりするためにサードパーティ製の外部モジュールをLambda Layerからインポートする必要があります。
    今回は「Pillow」と「openpyxl」というモジュールをインポートしています。Lambda Layerの作成は、以下を参考にしてみてください。

docs.aws.amazon.com

  • ランタイムの有効期限
    前述した、Lambda Layerでの外部モジュールインポートの際に、モジュールによってはランタイムが前のバージョンのものしかサポートされていない場合があります。運用として長期的に使用する場合は注意が必要です。

  • AWS Lambdaのファイル操作
    AWS Lambdaは/tmp配下のファイルにしか読み書きができないため、エクセルファイルに画像を貼り付けたい場合は一度/tmpディレクトリ内に画像ファイルをダウンロードしてから読み書きを行います。また、処理が全て終わった後は、/tmpディレクトリ内のファイルを全て削除しておきましょう。(詳しくは割愛しますが、以下公式ドキュメントによると、AWS Lambdaの仕様上/tmpディレクトリの中身をそのままにするのは良くないそうです。)

リソース管理およびパフォーマンスを向上させるため、Lambda はある期間中に実行環境を保持します。この間、同じ関数に対して別のリクエストを送信した場合、Lambda は環境を再利用できます。
引用元: Lambda 実行環境のライフサイクルの概要 - AWS Lambda

おわりに

今回はこのように、月次作業の自動化にチャレンジしてみました。自分が配属されたチームのように、色々な案件を抱えながら業務を行っていく上では、どうすれば楽にできるだろうかという考えを常日頃から持つことが大切だと感じました。そのためにもまずは案件をよく理解しておき、どのような作業を行っているのかを自分の中で整理することが第一歩ですね!
また、今後の改善点として、定期実行のAWS Lambdaが実行に失敗してしまったときに時に通知するようCloudWatchアラームを設定しても良いかなと思いました。

以上長くなりましたが、最後まで読んでいただきありがとうございました。

執筆者:山本将望 クラウドエンジニア