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

2024.06.05

はじめに

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

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サイトをご覧ください。