✈️

SaaS Builder Toolkit for AWS 勉強メモ

に公開

はじめに

SaaS Builder Toolkit for AWS(以下、SBT)を実際に触ってみて、どのようなツールなのかを理解してみました。

SBTとは: SaaSのマルチテナント管理を実現するためのAWS公式ツールキットです。
詳細はこちらの資料をご覧ください。

やったこと

この公式リポジトリのTutorialを実施するだけ。
(日本語のdocもありますが、2025/10/18時点で内容が古そうでした。)

https://github.com/awslabs/sbt-aws/tree/main/docs/public

(コンテンツの解説は以下の記事を読ませていただきました。)
https://dev.classmethod.jp/articles/sbt-tenant-onboarding/

(そもそも論コントロールプレーンって何?という方はBlackbeltの資料読みましょう。)
https://www.youtube.com/watch?v=duNdZVaWQ_o

わかったこと

このチュートリアルではサンプルとして、対象テナントに必要なリソースをS3としたときのコントロールプレーンとアプリケーションプレーンを構築できます。

https://github.com/awslabs/sbt-aws/tree/main/docs/public#putting-it-all-together

↑ここで書かれているようなアプリケーションプレーンの実装の通り、
このコード上で該当のテナントに必要なリソースを構築するShellスクリプトを記述してデプロイすることで、
このテナントをAPI的に構築できるようにするエンドポイントが作られます。

後は、テナント追加に際してはAPIを叩くだけ。
(テナント作成に合わせて、テナント管理情報もDynamoDBに管理されます。)

sbtで作成されるDynamoDBのテナント管理リソース

デプロイされたリソースのイメージ

基本的にSaaS Builder Toolkitで作成されるリソースについてはあまり意識しないので、どういうものかイメージつきづらいですね。

今回使ったSaaS Builder Toolkitを利用したサンプルコードを上げておきます。
https://github.com/theMistletoe/aws-sbt-study

テナント作成フローの詳細

加えて、実際のデプロイされたコードも載せておきます。(リポジトリにも上がっています。)
テナント作成は /tenant-registrations エンドポイントへのPOSTリクエストで実行されます。

処理の流れ:

  1. DynamoDBにテナント登録情報を保存
  2. Tenant APIを呼び出してテナントIDを取得
  3. EventBridgeにオンボーディングイベントを送信(非同期処理)
tenant_regist.py
@app.post("/tenant-registrations")
@tracer.capture_method
def create_tenant_registration():
    json_body = app.current_event.json_body
    tenant_registration_id = str(uuid.uuid4())
    tenant_data = json_body.get("tenantData", {})
    tenant_data["tenantRegistrationId"] = tenant_registration_id
    tenant_registration_data = json_body.get("tenantRegistrationData", {})

    # Create tenant registration
    tenant_registration_item = {
        "tenantRegistrationId": tenant_registration_id,
        "sbtaws_active": True,
    } | tenant_registration_data

    try:
        tenant_registration_table.put_item(
            Item=tenant_registration_item,
            ConditionExpression=Attr("tenantRegistrationId").not_exists(),
        )
    except ClientError as e:
        logger.error(f"Error creating tenant registration: {str(e)}")
        raise InternalServerError("Unknown error during processing!")

    response = requests.post(f"{tenant_api_url}tenants", json=tenant_data, auth=auth)
    if response.status_code != HTTPStatus.CREATED:
        raise InternalServerError("Failed to create tenant")

    tenant_id = response.json()["data"]["tenantId"]
    # add tenant id to the tenant-registration after creating it to ensure
    # that the tenant registration is created without issue
    __update_tenant_registration(tenant_registration_id, {"tenantId": tenant_id})

    __create_control_plane_event(
        json.dumps(
            tenant_registration_data
            | tenant_data
            | {"tenantId": tenant_id}
        ),
        onboarding_detail_type,
    )

    return {
        "data": {
            "tenantRegistrationId": tenant_registration_id,
            "tenantId": tenant_id,
            "message": "Tenant registration initiated",
        }
    }, HTTPStatus.CREATED

該当コード: https://github.com/theMistletoe/aws-sbt-study/blob/main/deployed_code/tenant_regist.py

思ったこと

  • このサンプル自体はリソースが作成されるだけで、例えば中に展開されるアプリをデプロイするCICDパイプラインに関する記述はない。そこもAWSリソースでコントロールできるのであればテナント作成の処理に記述してしまってもいいのかもだが、別サービスをCICDに使っている場合は、別途作業など工夫が必要そうな気もする。
  • アプリケーションプレーンの作成処理をShellで頑張って書いているが、IaC的な記述がしやすそうな気がする。CDKなどと投稿できるのだろうか

以上

GitHubで編集を提案

Discussion