Amazon Web Services ブログ

Amazon SageMaker のカスタムサブスクリプションワークフローによるデータガバナンスの加速

本記事は 2025 年 10 月 24 日 に公開された「Accelerate data governance with custom subscription workflows in Amazon SageMaker」を翻訳したものです。

Amazon SageMaker は、データの発見と開発を行える統合データ / AI 開発環境です。SageMaker には、Amazon EMRAWS GlueAmazon AthenaAmazon RedshiftAmazon Bedrock といった AWS の分析サービスや AI/ML サービスが統合されています。

組織は、データマーケットプレイスでガバナンス統制を維持しながら、データアセットを効率的に管理する必要があります。機微なデータセットや本番システムでは手動承認ワークフローが依然として重要ですが、機微でないデータセットでは承認プロセスの自動化が求められています。本記事では、SageMaker 内でサブスクリプションリクエストの承認を自動化し、データ利用者のデータアクセスを迅速化する方法を紹介します。

前提条件

本ウォークスルーの前提条件は以下のとおりです。

  • AWS アカウント – アカウントをお持ちでない場合は、こちらから作成できます。アカウントには以下の権限が必要です。
    • SageMaker ドメインの作成と管理
    • IAM ロールの作成と管理
    • Lambda 関数の作成と呼び出し
  • SageMaker ドメイン – ドメイン作成手順は Amazon SageMaker Unified Studio ドメインの作成 – クイックセットアップ を参照してください。
  • デモプロジェクト – SageMaker ドメインにデモプロジェクトを作成します。手順は プロジェクトの作成 を参照してください。本例ではプロジェクトプロファイルで All capabilities を選択します。
  • SageMaker ドメイン ID、プロジェクト ID、プロジェクトロール ARN – 既存のデータセット / リソースへの権限付与とサブスクリプション自動承認コードで後ほど使用します。これらの情報は、SageMaker コンソールのプロジェクト詳細ページにある Project details タブから取得できます。

  • AWS CLI のインストールAWS Command Line Interface (AWS CLI) バージョン 2.11 以降が必要です。
  • Python のインストール – Python バージョン 3.8 以降が必要です。
  • IAM 権限 – 管理者権限を持つユーザーでサインインしてください。
  • Lambda 権限 – Lambda 実行ロールに適切な IAM 権限を設定します。以下は本ソリューションのテストで使用したサンプルロールです。ご利用環境に適用する前に、AWS リージョンとアカウント ID を指定し、最小権限の原則に基づいて調整してください。Lambda 実行ロールの作成について詳しくは、実行ロールを使用した Lambda 関数のアクセス許可の定義 を参照してください。
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "datazone:ListSubscriptionRequests",
                    "datazone:AcceptSubscriptionRequest",
                    "datazone:GetSubscriptionRequestDetails",
                    "datazone:GetDomain",
                    "datazone:ListProjects"
                ],
                "Resource": "<<Domain-ARN>>"
            },
            {
                "Effect": "Allow",
                "Action": "sts:AssumeRole",
                "Resource": "<<Domain-ARN>>",
                "Condition": {
                    "StringEquals": {
                        "aws:PrincipalArn": "<<Lambda ARN>>"
                    }
                }
            },
            {
                "Effect": "Allow",
                "Action": "sns:Publish",
                "Resource": "<<SNS-ARN>>"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": [
                    "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*",
                    "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*"
                ]
            }
        ]
    }

ソリューション概要

カスタムワークフローソリューションを詳しく見る前に、Amazon SageMaker のサブスクリプションと承認のワークフローを理解しておきましょう。アセットが SageMaker カタログに公開されると、データ利用者がアセットを発見できるようになります。データ利用者は、SageMaker カタログでアセットを見つけると、業務上の妥当性と想定されるユースケースを記載したサブスクリプションリクエストを送信し、アセットへのアクセスを申請します。リクエストは保留状態となり、データ提供者またはアセット所有者にレビュー依頼が通知されます。データ提供者はガバナンスポリシー、利用者の資格情報、業務背景に基づいてリクエストを評価します。データ提供者はリクエストを承認、却下、またはデータ利用者に追加情報を要求できます。承認されると、SageMaker は AcceptSubscriptionRequest イベントをトリガーし、アクセス権限の自動プロビジョニングを開始します。サブスクリプションが承認されると、データ利用者にアセットへのアクセスを付与する履行プロセスが開始されます。SageMaker は AWS Lake Formation と緊密に統合され、きめ細かな権限管理を実現します。サブスクリプションが承認されると、SageMaker は Lake Formation の API を自動的に呼び出し、サブスクライバーの IAM ロールに対してデータベース、テーブル、カラムレベルの権限を付与します。Lake Formation は中央権限エンジンとして機能し、サブスクリプションの承認を自動的にデータアクセス権へ変換します。システムはデータソース上のリソースベースのポリシーをプロビジョニングおよび更新します。プロビジョニングが完了すると、データ利用者は Athena、Redshift、EMR などのクエリエンジンを通じて、サブスクライブしたデータにすぐにアクセスできるようになります。Lake Formation はクエリ実行時に権限を適用します。

デフォルトでは、公開されたアセットへのサブスクリプションリクエストはデータ所有者による手動承認が必要です。ただし、Amazon SageMaker はアセットレベルでサブスクリプションリクエストの自動承認をサポートしています。データアセットを公開するときに、サブスクリプション承認を不要にすることを選べます。この場合、当該アセットへの受信サブスクリプションリクエストはすべて自動的に承認されます。まず、アセットレベルで自動承認を設定する手順を説明します。

アセットレベルでの自動承認の設定

自動承認を設定するには、データ提供者は以下の手順に従います。

  1. データ提供者として SageMaker Unified Studio ポータルにログインします。Assets に移動し、対象のアセットを選択します。
  2. Assets を選択し、自動承認を設定したいアセットを選びます。
  3. アセット詳細ページの右ペインで Edit Subscription 設定を見つけます。

  4. Subscription Required の横の Edit を選択します。
    1. ダイアログボックスで Not Required を選択します。
    2. 選択内容を確定します。

SageMaker のサブスクリプションワークフローのカスタマイズ

本番環境や機微データを扱う場面では手動承認ワークフローが不可欠ですが、リスクの低い環境や機微でないデータセットについては承認を効率化・自動化したい場面もあります。プロジェクトレベルでの自動化を実現するため、イベント駆動型のカスタムソリューションで SageMaker の標準承認ワークフローを拡張できます。AWS のサーバーレスアーキテクチャを活用し、AWS LambdaAmazon EventBridge ルール、Amazon Simple Notification Service (Amazon SNS) を組み合わせて自動承認ワークフローを構築します。サブスクリプション承認の自動化により、ガバナンスを維持しつつ管理負荷を軽減し、重要度の低い環境での開発サイクルを迅速化できます。イベント駆動型アプローチにより承認リクエストがリアルタイムで処理され、監査証跡が維持されます。また、プロジェクトの特性やデータの機密レベルに応じて異なる承認ルールを適用するように設定できます。

カスタムワークフローは以下の手順で構成されます。

  1. データ利用者が公開されたデータアセットへのサブスクリプションリクエストを送信します。
  2. SageMaker がリクエストを検出し、サブスクリプションイベントを生成して EventBridge に自動送信します。
  3. EventBridge が指定された Lambda 関数をトリガーします。
  4. Lambda 関数が SageMaker に AcceptSubscriptionRequest API 呼び出しを送信します。
  5. 関数は Amazon SNS を通じて通知も送信します。
  6. AWS Lake Formation が承認されたサブスクリプションを処理し、関連するアクセス制御リスト (ACL) と権限セットを更新します。
  7. Lake Formation がデータ利用者のプロジェクト AWS Identity and Access Management (IAM) ロールにアクセス権限を付与します。
  8. データ利用者がリクエストしたデータアセットにアクセスできるようになり、データの利用を開始できます。

次の図は、本ソリューションの全体アーキテクチャを示しています。

主なメリット

本ソリューションは AWS Lambda と Amazon EventBridge を使って SageMaker のサブスクリプションリクエスト承認を自動化し、組織とエンドユーザーに以下のメリットをもたらします。

  • スケーラビリティ – 大量のサブスクリプションリクエストを自動的に処理
  • コスト効率 – 従量課金制で、アイドルリソースのコストが発生しない
  • 保守の最小化 – サーバーレス構成のためインフラ管理が不要
  • 柔軟なトリガー – イベント駆動、スケジュール、手動の各実行モードに対応
  • 監査コンプライアンスAWS CloudTrail によるログ記録と追跡

手順

ここでは、Amazon SageMaker でカスタムサブスクリプションリクエスト承認ワークフローを実装する詳細な手順を説明します。

Lambda 関数の作成

Lambda 関数を作成する手順は以下のとおりです。

  1. Lambda コンソールのナビゲーションペインで Functions を選択します。
  2. Create function を選択します。
  3. Author from scratch を選択します。
  4. Function name に関数名を入力します。
  5. Runtime でランタイムを選択します (本記事では Python 3.9 以降を使用)。
  6. Create function を選択します。

  7. Lambda 関数ページで Configuration タブを選択し、続いて Permissions を選択します。
  8. SageMaker プロジェクトを設定するときに使用する実行ロールをメモしておきます。

SNS トピックの作成

本ソリューションでは SNS トピックを作成します。自動承認用の SNS トピックを作成する手順は以下のとおりです。

  1. Amazon SNS コンソールのナビゲーションペインで Topics を選択します。
  2. Create topic を選択します。
  3. TypeStandard を選択します。
  4. Name にトピック名を入力します。
  5. Create topic を選択します。

  6. SNS トピック詳細ページで、後ほど Lambda 関数で使用する SNS トピック Amazon Resource Name (ARN) をメモしておきます。

  7. Subscription タブで Create Subscription を選択します。
  8. ProtocolEmail を選択します。
  9. Endpointデータ利用者のメールアドレスを入力します。

EventBridge ルールの作成

サブスクリプションリクエストイベントをキャプチャする EventBridge ルールを作成する手順は以下のとおりです。

  1. EventBridge コンソールのナビゲーションペインで Rules を選択します。
  2. Create rule を選択します。
  3. Name にルール名を入力します。
  4. Rule typeRule with event pattern を選択します。

    イベントパターンを選ぶと、サブスクリプションリクエスト発生時に自動承認ワークフローがトリガーされます。定期的にルールを実行したい場合は、Schedule を選択することもできます。詳しくは Amazon EventBridge でスケジュールされたルールを作成する を参照してください。
  5. Next を選択します。

  6. Event sourceAWS events or EventBridge partner events を選択します。
  7. Creation methodUse pattern form を選択します。
  8. Event sourceAWS services を選択します。
  9. AWS serviceDataZone を選択します。
  10. Event typeSubscription Request Created を選択します。

  11. ターゲットを設定し、Lambda 関数と SNS トピックの両方にイベントをルーティングします。
  12. Next を選択します。

  13. 本記事ではタグの設定は省略し、Next を選択します。

  14. 設定を確認し、Create rule を選択します。

自動化ワークフローの設定

自動化ワークフローを設定する手順は以下のとおりです。

  1. Lambda コンソールで、作成した関数を開きます。
  2. Lambda 関数をトリガーする EventBridge ルールを設定します。
  3. イベント通知の送信先として SNS トピックを設定します。

Lambda 関数へのコードの設定

Lambda 関数を設定する手順は以下のとおりです。

  1. Lambda コンソールで、作成した関数を開きます。
  2. 以下のコードを関数に追加します。先ほどメモしたドメイン ID、プロジェクト ID、SNS トピック ARN を指定します。
    import boto3
    import json
    import logging
    import os
    from botocore.exceptions import ClientError
    
    # Configure logging
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    def lambda_handler(event, context):
        """Lambda function to auto-approve subscription requests in Amazon SageMaker"""
        try:
            # Initialize clients
            datazone_client = boto3.client('datazone')
            sns_client = boto3.client('sns')
            
            # Get configuration from environment variables or use hardcoded values
            domain_id = os.environ.get('DOMAIN_ID', '<domain_id>')
            project_id = os.environ.get('PROJECT_ID', '<project_id>')
            sns_topic_arn = os.environ.get('SNS_TOPIC_ARN', '<sns_topic_arn>')
            
            # Get pending subscription requests
            pending_requests = get_pending_requests(datazone_client, domain_id, project_id)
            
            if not pending_requests:
                logger.info("No pending subscription requests found")
                return
            
            # Process requests
            for request in pending_requests:
                approve_request(datazone_client, sns_client, domain_id, request, sns_topic_arn)
                
        except Exception as e:
            logger.error(f"Error: {str(e)}")
    
    def get_pending_requests(client, domain_id, project_id):
        """Get all pending subscription requests"""
        requests = []
        next_token = None
        
        try:
            while True:
                params = {
                    'domainIdentifier': domain_id,
                    'status': 'PENDING',
                    'approverProjectId': project_id
                }
                
                if next_token:
                    params['nextToken'] = next_token
                
                response = client.list_subscription_requests(**params)
                
                if 'items' in response:
                    requests.extend(response['items'])
                
                next_token = response.get('nextToken')
                if not next_token:
                    break
                    
            logger.info(f"Found {len(requests)} pending requests")
            return requests
            
        except ClientError as e:
            logger.error(f"Error listing requests: {e}")
            return []
    
    def approve_request(datazone_client, sns_client, domain_id, request, sns_topic_arn):
        """Approve a subscription request and send notification"""
        request_id = request.get('id')
        if not request_id:
            return
            
        try:
            # Approve the request
            datazone_client.accept_subscription_request(
                domainIdentifier=domain_id,
                identifier=request_id,
                decisionComment="Subscription request is auto-approved by Lambda"
            )
            
            # Send notification
            asset_name = request.get('assetName', 'Unknown asset')
            
            message = f"Your subscription request has been auto-approved by Lambda. You can now access this asset."
            
            sns_client.publish(
                TopicArn=sns_topic_arn,
                Subject=f"Subscription Request is auto-approved by Lambda",
                Message=message
            )
            
            logger.info(f"Approved request {request_id} for {asset_name}")
            
        except Exception as e:
            logger.error(f"Error processing request {request_id}: {e}")
  3. Test を選択して Lambda 関数コードをテストします。Lambda コードのテストについて詳しくは、コンソールでの Lambda 関数のテスト を参照してください。
  4. Deploy を選択してコードをデプロイします。

SageMaker での Lambda 実行ロールとプロジェクト実行ロールの設定

手順は以下のとおりです。

  1. SageMaker Unified Studio で、公開用プロジェクトを開きます。
  2. ナビゲーションペインで Members を選択します。
  3. Add members を選択します。
  4. Lambda 実行ロールとプロジェクト実行ロールを Contributor として追加します。

ソリューションのテスト

ソリューションをテストする手順は以下のとおりです。

  1. SageMaker Unified Studio でデータカタログに移動し、設定済みのアセットで Subscribe を選択してサブスクリプションリクエストを開始します。

  2. ナビゲーションペインで Subscription requests を選択して送信済みリクエストを確認し、Approved タブを選んで自動承認を確認します。

  3. View subscription を選択し、承認者が Lambda 実行ロールで、理由が「Auto-approved by Lambda」になっていることを確認します。

  4. CloudTrail コンソールで Event history を選択し、発生したイベントを確認して自動承認の監査証跡をレビューします。

クリーンアップ

今後の課金を避けるため、ウォークスルー中に作成したリソースをクリーンアップします。以下の手順では AWS マネジメントコンソールを使いますが、AWS CLI でも実施できます。

  1. SageMaker ドメインを削除します。AWS CLI を使う場合は、以下のコマンドを実行します。
    aws sagemaker delete-project --project-name <project-name>
    aws datazone delete-domain –identifier <domain_identifier>
  2. Amazon SNS トピックおよびサブスクリプションを削除するします。AWS CLI を使う場合は、以下のコマンドを実行します。
    aws sns delete-topic --topic-arn <topic-arn>
  3. Lambda 関数を削除します。AWS CLI を使う場合は、以下のコマンドを実行します。
    aws lambda delete-function --function-name <Lambda function name>

まとめ

イベント駆動型アーキテクチャと SageMaker を組み合わせることで、データガバナンスを自動化するコスト効率の高いソリューションを構築できます。サーバーレスアプローチでデータアクセスリクエストを自動処理しつつコンプライアンスを維持でき、データの増加にも効率的にスケールできます。このソリューションにより、データチームは運用コストを抑えながら迅速にインサイトを得られます。コンプライアンスとシステムの効率性を両立したい企業に適しています。

詳しくは Amazon SageMaker Unified Studio のページを参照してください。

著者について

Nira Jaiswal

Nira Jaiswal

Nira は、AWS のプリンシパルデータソリューションアーキテクトです。戦略的なお客様と協力し、革新的なデータ / 分析ソリューションの設計と導入を行っています。スケーラブルなクラウドベースのプラットフォームの設計を得意としており、組織がデータ投資の価値を最大化できるよう支援しています。分析、AI/ML、ストーリーテリングを組み合わせて、複雑な情報を具体的な改善提案に変え、測定可能なビジネス価値を生み出すことに情熱を注いでいます。

Ajit Tandale

Ajit Tandale

Ajit は、AWS のシニアソリューションアーキテクトで、データと分析を専門としています。戦略的なお客様と連携し、AWS サービスとオープンソース技術を使って、セキュアでスケーラブルなデータシステムの設計を行っています。専門分野はデータレイクの設計、データパイプラインの実装、ビッグデータ処理ワークフローの最適化で、組織のデータアーキテクチャのモダナイゼーションを支援しています。仕事以外では読書とサイエンスフィクション映画が好きです。


この記事は Kiro が翻訳を担当し、Solutions Architect の Woosuk Choi がレビューしました。