EFS のファイルシステム状態を監視する Lambda 関数 を作成してみた

2024.05.08

はじめに

テクニカルサポートの 片方 です。

EFS に表示されている ファイルシステムの状態を監視する Lambda 関数 を作成しました。当該状態を監視する Lambda 関数 を使って、CloudWatch カスタムメトリクスとして表示させます。
お好みで EventBridge による Lambda 関数の定期実行や CloudWatch アラームより SNS を使用した通知 などをご検討ください。

構成と説明

EFS のファイルシステムの状態を監視する Lambda 関数を作成します。それをカスタムメトリクスとして取得して CloudWatch に送信して表示させます。

以下はイメージです。(本ブログでは赤枠で囲んだ範囲についてご紹介します)

やってみた

ロール

ロール名: LambdaFunctionCheckEFSFileSystemStatusRole

Lambda 関数にアタッチするロールを作成します。信頼関係は以下です。

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

アタッチするポリシー例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudwatch:PutMetricData",
                "elasticfilesystem:DescribeFileSystems"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

Lambda 関数

Lambda 関数を作成します。ランタイムは Python 3.12 を使用しました。 以下を参考に作成してます。

関数名: LambdaFunctionCheckEFSFileSystemStatus

アタッチする実行ロールは、先ほど作成した "LambdaFunctionCheckEFSFileSystemStatusRole" を選択します。

サンプルコード
import boto3
from botocore.exceptions import ClientError

def send_cw_metric(metric_dimension_value, metric_value):
    client = boto3.client('cloudwatch')
    try:
        client.put_metric_data(
            Namespace='EFS File System Status',
            MetricData=[
                {
                    'MetricName': 'EFS Status',
                    'Dimensions': [
                        {
                            'Name': 'EFS Status Metrics',
                            'Value': metric_dimension_value
                        }
                    ],
                    'Value': metric_value,
                    'Unit': 'Count'
                },
            ]
        )
    except ClientError as e:
        print(e)

def lambda_handler(event, context):
    status_map = {
        'available': 0,
        'creating': 1,
        'updating': 2,
        'deleting': 3,
        'deleted': 4,
        'error': 5
    }

    client = boto3.client('efs')
    paginator = client.get_paginator('describe_file_systems')
    pages = paginator.paginate()

    for page in pages:
        for fs in page['FileSystems']:
            send_cw_metric(fs['FileSystemId'], status_map[fs['LifeCycleState']])

以上で実装は終了です。お疲れさまでした。

検証してみた

検証では作成した Lambda 関数を毎分呼び出すため EventBridge による定期実行の設定を行いました。 結果はご覧の通り available として 0 がカウントされていますので、成功です。

"error" としてカスタムメトリクス取得可能であるか検証したいものの、手段がないため叶いませんでした。
また、スループットモード変更などを試して同様に "updating" としてカスタムメトリクス取得可能であるかも検証しましたが、ステータスが変更になる前に完了するため叶いませんでした。

補足程度ですが、 "available" 5 に、"error"を 0 にして検証した場合でも成功してます。

まとめ

ご自身の環境に合わせ適宜修正の上ご利用ください。本ブログが誰かの参考となれば幸いです。

参考資料

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。