AWS Transfer Family のサーバー状態を監視する Lambda 関数を作成してみた

AWS Transfer Family のサーバー状態を監視する Lambda 関数を作成してみた

Clock Icon2024.06.05 00:00

はじめに

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

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

以下の状態監視が可能です。

  • "ONLINE" サーバーがジョブを受け入れてファイルを転送できることを示します。
  • "OFFLINE" サーバーはファイル転送操作を実行できません。
  • "STARTING""STOPPING" サーバーが完全に応答できないか、完全にオフラインではない中間状態にあることを示します。
  • "START_FAILED""STOP_FAILED" エラー状態を示している可能性があります。

構成と説明

AWS Transfer Family のサーバー状態を監視する Lambda 関数を作成します。それをカスタムメトリクスとして取得し CloudWatch に送信して表示させます。

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

やってみた

ロール

ロール名: LambdaFunctionCheckTransferFamilyServerStatusRole

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",
                "transfer:ListServers",
                "transfer:DescribeServer"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

Lambda 関数

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

関数名: LambdaFunctionCheckTransferFamilyServerStatus

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

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

def send_cw_metric(metric_dimension_value, metric_value):
    client = boto3.client('cloudwatch')
    try:
        response = client.put_metric_data(
            Namespace='Custom/TransferFamily',
            MetricData=[
                {
                    'MetricName': 'TransferFamilyServerStatus',
                    'Dimensions': [
                        {
                            'Name': 'ServerId',
                            'Value': metric_dimension_value
                        }
                    ],
                    'Value': metric_value,
                    'Unit': 'Count'
                },
            ]
        )
        print("Successfully sent metric data:", response)
    except ClientError as e:
        print("Failed to send metric data:", e)


def lambda_handler(event, context):
    state_map = {
        'ONLINE': 0,
        'OFFLINE': 1,
        'STARTING': 2,
        'STOPPING': 3,
        'START_FAILED': 4,
        'STOP_FAILED': 5
    }

    client = boto3.client('transfer')
    try:
        response = client.list_servers()
        servers = response['Servers']
        for server in servers:
            server_id = server['ServerId']
            server_state = server['State']
            send_cw_metric(server_id, state_map.get(server_state, -1))
    except ClientError as e:
        print("Failed to list servers:", e)

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

検証してみた

結果はご覧の通り問題なく ONLINE: 0 として取得できています。成功です。

※ 停止中 (STOPPING: 3)

※ オフライン (OFFLINE: 1)

※ 開始中 (STARTING: 2)

まとめ

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

参考資料

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

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

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.