EventBridge Scheduler + Lambda を利用して SageMaker Canvas のアプリケーション削除忘れ防止として、 削除作業を自動化してみた

アノテーションのスライマンです。
今回は SageMaker Canvas において、高額料金が発生するのを防ぐための対策をやっていきたいと思います。
SageMaker Canvas を利用する際に、料金の発生を止めるには、アプリケーションをログアウトするか、アプリケーションを削除する必要がございます。
ブラウザのタブを閉じるだけでは、料金の発生は止まりません。
よくあるケースとしましては、ブラウザのタブを閉じることのみを行っており、アプリケーションのログアウトもしくは削除を行わずに、リソースを放置して、料金が発生し続け結果的に高額な料金が請求されているケースがございます。
本記事では、Canvas アプリケーションの削除忘れを防止するために、1日1回定期的に、Canvas が存在しているかを確認して、存在している場合は自動的に削除する仕組みを作成していきます。

構成図

構成は下記の通りとなります。

EventBridge Scheduler で任意の時間帯に定期的に Lambda が起動されるように cron 式のスケジュールを設定して、Lambda をターゲットとするスケジュールを作成します。
指定した時間帯に Lambda が起動して、Canvas アプリケーションの有無を確認して、もしあった場合には削除を実施します。

概要

必要なリソースは下記となります。

  • Lambda 関数
  • EventBridge Scheduler
  • SageMaker Canvas

必要なリソースを準備した後、実際に動作を確認していきたいと思います。

実際にやってみた

Lambda 関数の作成

まずは、Lambda の実行ロールから作成していきます。
IAM > ポリシー > ポリシーの作成 より下記の IAM ポリシーを記入していきます。
その後、次へ進み、任意の名前を指定して作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "sagemaker:ListApps",
                "sagemaker:DeleteApp"
            ],
            "Resource": "*"
        }
    ]
}

次に IAM ロールを作成します。
IAM > ロール > ロールの作成 より信頼されたエンティティタイプを AWS のサービス、サービスを Lambda と選択します。
許可するポリシーにて先程作成した IAM ポリシーを選択し、名前を記入して IAM ロールを作成します。

IAM ロールの作成が完了しましたら、Lambda の関数を作成します。
今回はランタイムとして、Python 3.10 を利用します。
アーキテクチャは x86_64 のまま、実行ロールを先程作成した IAM ロールに選択して、関数を作成します。

コードの設定をして、Deploy します。
下記の通りとなります。

import boto3
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    sagemaker = boto3.client('sagemaker')

    try:
        # List SageMaker Apps
        response = sagemaker.list_apps()

        #  Filtering App (AppType must be Canvas and not in Deleted status)
        canvas_apps = [app for app in response['Apps'] if app['AppType'] == 'Canvas' and app['Status'] != 'Deleted']

        # Do not delete App if Apptype is not Canvas and Status is Deleted
        if not canvas_apps:
            print("No Canvas apps found or already deleted.")
            return

        # If AppType is Canvas and not in deleted status, delete Canvas App
        for app in canvas_apps:
            domain_id = app['DomainId']
            user_profile_name = app['UserProfileName']
            app_type = app['AppType']
            app_name = app['AppName']

            # Delete Canvas App
            print(f"Deleting Canvas app: {app_name}")
            sagemaker.delete_app(
                DomainId=domain_id,
                UserProfileName=user_profile_name,
                AppType=app_type,
                AppName=app_name
            )

        return "Deleting Canvas app."

    except ClientError as e:
        if error.response['Error']['Code'] == 'ResourceInUse':
            print("Resource In Use")
            return

        raise e

実施される処理は下記となります。

  • SageMaker のアプリケーションの一覧情報を取得する
  • 取得したSageMaker のアプリケーションの一覧情報より、AppType が Canvas となっているかかつ Status が Deleted となっているかを確認する
  • Canvas となっていないかつ Canvas となっているが Status が Deleted となっている場合は処理を終了する
  • Canvas となっていて、Status が Deleted となっていない場合は、DomainId、UserProfileName、AppType、AppName を取得して、Canvas アプリケーションを削除する

動作確認

Lambdaのテスト実行より、動作確認をしていきます。
テストイベントを設定より、新しいイベントを作成して、イベント名を test と記入して、そのまま保存します。
その後、test を呼び出して、動作を確認します。
結果が出力され、Canvas アプリケーションの削除が実施されていることを確認できます。

Test Event Name
test

Response
"Deleting Canvas app."

Function Logs
START RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Version: $LATEST
Deleting Canvas app: default
END RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
REPORT RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  Duration: 2070.31 ms    Billed Duration: 2071 ms    Memory Size: 128 MB Max Memory Used: 76 MB  Init Duration: 272.23 ms

Request ID
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

SageMaker のコンソールから確認しますと、ステータスが Deleting となっているため、削除のプロセスが行われていることがわかります。

EventBridge Schedulerの作成

Lambda が正常に動作していることを確認できましたので、EventBridge Scheduler を作成していきます。
EventBridge > スケジューラ > スケジュール > スケジュールを作成より、作成します。

スケジュール名、パターンを設定します。
Cronベースのスケジュールで毎日特定の時間に稼働するように設定します。
今回は毎日 22:00 JST に稼働するように設定しております。

0 22 * * ? *

フレックスタイムウィンドウはオフにします。
時間枠は何も設定せずにそのまま次へ進みます。

次にターゲットとして、AWS Lambda Invoke を選択します。
作成した Lambda 関数を選択します。
それ以外の項目はデフォルトのままに設定して、スケジュールを作成します。

スケジューラーを作成しましたら、指定した時間に正常に動作するかを確認します。
正常に Lambda が動作した場合、作業は完了となります。

最後に

設定につきましては、以上となります。
SageMaker Canvas はアプリケーションを起動しているだけで、「1.9 USD/時間」の料金が発生します。
利用完了後に、削除を忘れますと、1日で 45.6 USD と高額の料金が発生します。
本記事で作成した仕組みを利用することで、削除忘れが防ぐことができます。
この記事が皆様のお役に立てば幸いです。

参考情報

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

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。