はじめに

本記事では、CloudWatch Alarm からトリガーされたメトリクスのデータを Systems Manager Automation ランブック(ドキュメント)の入力として渡し、特定の AWS API を実行する手順を示します。
Systems Manager Automation は、Lambda の代替案として優秀であり、汎用性が高いです。

今回は、SageMaker Canvas のコスト最適化を目的として、Canvas の自動シャットダウンを対象とします。ただし、Canvas に限らず、他の多くのソリューションにも適用可能な手法です。

構成

CloudWatch Alarm → EventBridge → SSM Automation → SageMaker Canvas

SSM Automation ランブック

  • コンソールにて、[AWS Systems Manager]→[ドキュメント]→[ドキュメントを作成]→[オートメーション]を選択
  • [AWS API]から SageMaker の[DeleteApp]を選択


🌾 最初からコードを書くよりも、[デザイン]モードで型を作ってから、[{}コード]モードに切り替えるとコーディングが楽になります。

  • [{}コード]を選択し、以下のように編集し、[ランブックを作成]を押下
    • ランブックの名前は「ShutdownCanvas」
{
  "schemaVersion": "0.3",
  "description": "Shutdown Canvas",
  "parameters": {
    "domainid": {
      "type": "String"
    },
    "userprofilename": {
      "type": "String"
    }
  },
  "mainSteps": [
    {
      "name": "DeleteApp_Canvas",
      "action": "aws:executeAwsApi",
      "maxAttempts": 2,
      "timeoutSeconds": 300,
      "isEnd": true,
      "inputs": {
        "Service": "sagemaker",
        "Api": "DeleteApp",
        "AppName": "default",
        "AppType": "Canvas",
        "DomainId": "{{domainid}}",
        "UserProfileName": "{{userprofilename}}"
      }
    }
  ]
}
  • ここで、以下の API 入力データの一部をパラメータとして設定しておきます。
    • DomainId
    • UserProfileName

🌾 ここで設定した parameters に EventBridge から値を渡す方法を後述します。

CloudWatch Alarm

  • CloudWatch を開き、SageMaker Canvas のアイドル時間に対して、アラームを設定
    • 名前空間:/aws/sagemaker/Canvas/AppActivity
    • メトリクス名:TimeSinceLastActive
    • DomainId:d-4tbpmqlp00h6
    • UserProfileName:default-20250317T145464
    • アクション:なし
    • 条件:TimeSinceLastActive > 1000

🌾 Canvas が1000秒以上アイドル状態のとき、アラートがトリガーします。

EventBridge 用の IAM ロール

  • IAM のコンソールから、EventBridge の実行ロールのために、SageMaker へのアクセスと SSM Automation へのアクセスを許可した IAM ロールを事前に作成します。
    • ロールの名前は「EventBridge-SageMaker-Canvas-Role」

🌾 場合によって、iam:PassRole を[許可を追加]からインラインポリシーで追加する必要があります。今回の場合は追加せずに成功したため、このままにします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "sagemaker.amazonaws.com",
                    "events.amazonaws.com",
                    "ssm.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

🌾 EventBridge のルールではなく、EventBridge Scheduler を使用する場合、「events.amazonaws.com」 ではなく、「scheduler.events.amazonaws.com」とする必要があります。

EventBridge ルールの作成

  • EventBridge のコンソールからルールを作成します。
  • イベントパターンを設定(カスタムパターン)
    • CloudWatch Alarm を検知するように設定
{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"],
  "detail": {
    "alarmName": ["canvas-idle-shutdown-SM"],
    "state": {
      "value": ["ALARM"]
    }
  }
}
  • ターゲットを設定
    • 「Systems Manager オートメーション」を選択
    • [ドキュメント]に「ShutdownCanvas」(事前作成済みのランブック)を選択
    • [自動化パラメータを設定]に「入力トランスフォーマー」を選択

参考:
入力トランスフォーマーを使用したオートメーションへのデータの受け渡し
Amazon EventBridge 入力変換
iret.media:EventBridge入力トランスフォーマーを使ってメールをカスタマイズ

  • 入力パスを以下に設定

[Input Path] (入力パス) は、変数を定義するために使用されます。JSON パスを使用してイベント内の項目を参照し、それらの値を変数に格納します。

{
  "dmid": "$.detail.configuration.metrics[0].metricStat.metric.dimensions.DomainId",
  "upname": "$.detail.configuration.metrics[0].metricStat.metric.dimensions.UserProfileName"
}

🌾 EventBridge が読み取っているイベント(JSON)のパスを指定して値を取得します。以下のドキュメントや EventBridge コンソールからサンプルイベントを確認できます。
参考:アラームイベントと EventBridge

  • 入力テンプレートを以下に設定
    • ここでは、入力パスで取得したデータを以下のように参照できます。

入力テンプレートは、ターゲットに渡す情報のテンプレートです。文字列または JSON をターゲットに渡すテンプレートを作成できます。

{
  "domainid":[<dmid>],
  "userprofilename":[<upname>]
}

🌾 半角スペースなど入れないように注意してください。 domainiduserprofilename は SSM のランブックで設定したパラメータ名と一致させなければなりません。

  • [実行ロール]に事前に作成した IAM ロール「EventBridge-SageMaker-Canvas-Role」を選択し、最後まで進み、[ルールの作成]を押下

🌾 以上の設定により、EventBridge はトリガーされたアラートのメトリクス情報を取得し、その値を SSM Automation に入力しつつ実行することができます。

検証

  • SageMaker AI で Canvas を起動して放置(アイドル状態にしておく)します。

  • しばらく待つと、CloudWatch Alarm がトリガーします。

  • Canvas のステータスが[Stopped]に変わります。

  • Systems Manager Automation を開いて実行を確認します。

  • Input parameters を開くと、EventBridge からメトリクスのデータを渡すことができています。

🌾 これにより、複数のドメイン名・ユーザプロファイルに対して、一つの EventBridge ルールと一つのランブックで自動シャットダウンができます。すなわち、ドメインやユーザが増減しても、CloudWatch Alarm だけを変更すれば良いです。ただし、イベントパターン(イベントのフィルタリング)に正規表現などを使って工夫が必要となります。

おわりに 〜SSM Automation のメリット〜

🌾 今回実施した SageMaker Canvas のシャットダウンは、CloudWatch Alarm アクション→ Lambda の方法でも同様に実現可能で、実際 AWS から推奨されています。
参考:自動シャットダウンソリューションを使ってAmazon SageMaker Canvas のコストを最適化する方法

ただし、以下のような理由から代替の選択肢として有用と考えています。

  • Lambda には、言語依存(EOLなど)がある
  • Lambda よりもランブックの方がコーディングが楽である
  • 連続した AWS の操作・複雑なワークフローを簡単にランブックにできる
  • Lambdaの実行時間の制限を回避できる