PR

AWS Serverless Application Model (SAM) を使用してSaaSを構築するハンズオンガイド


はじめに

AWS Serverless Application Model (SAM) は、AWS上でサーバーレスアプリケーションを効率的に構築、デプロイ、管理するためのオープンソースフレームワークです。SAMを使用すると、Lambda、API Gateway、DynamoDBなどのサーバーレスサービスを迅速に統合し、アプリケーションを構築できます。本記事では、SAMを用いてSaaSプロダクトを構築するための手順を詳細に解説します。


1. SAMの基礎とアーキテクチャ

SAMとは?

AWS SAMは、AWS上でサーバーレスアプリケーションを迅速に構築できるオープンソースのフレームワークです。SAMは、インフラのコード化、デプロイ、管理を効率化し、Lambda関数、API Gateway、DynamoDB、S3などをシンプルに統合します。

アーキテクチャの理解

SaaSアプリケーションの構築には、以下のAWSリソースを使用します。

  • Lambda: サーバーレスな計算処理
  • API Gateway: HTTPリクエストをLambda関数にルーティング
  • DynamoDB: 高スケーラブルなNoSQLデータベース
  • S3: 静的コンテンツのホスティング
  • CloudWatch: ログと監視

SAMを使用することで、これらのリソースをコードで簡単に定義し、管理できます。


2. SaaSアーキテクチャの設計

マルチテナント設計

SaaSの最大の特徴は、複数の顧客(テナント)が同じアプリケーションインスタンスを共有することです。SAMを使用してマルチテナントの構成を作成する場合、以下を考慮します:

  • データ隔離: 各テナントのデータは分離されている必要があります。これを実現するために、DynamoDBでテナントごとのデータを管理します。
  • アクセス管理: IAMポリシーを用いて、各テナントのデータへのアクセスを管理します。

サブスクリプション管理

サブスクリプション管理には、決済ゲートウェイ(例:Stripe)を利用して顧客のサブスクリプションを管理します。顧客ごとに異なるプランを提供し、API経由で支払い処理を行います。


3. AWS SAMのセットアップ

AWS CLIとSAM CLIのインストール

まずは、AWS CLIとSAM CLIをインストールします。

プロジェクトの初期化

SAM CLIを使ってプロジェクトを初期化します。以下のコマンドで新しいSAMプロジェクトを作成します。

sam init

プロジェクトの種類、ランタイムを選択し、基本的な構成を整えます。


4. テンプレートの作成

SAMテンプレートの基本構造

SAMテンプレート(template.yaml)は、AWSリソースを定義するための中心的なファイルです。以下のように、Lambda関数やAPI Gatewayの設定を記述します。

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: hello_world.handler
      Runtime: nodejs14.x
      MemorySize: 128
      Timeout: 3

リソース定義

SAMテンプレートにリソースを追加していきます。例えば、DynamoDBやAPI Gatewayなどのリソースを定義します。

AWS SAM CLI で表示されるテンプレート一覧の詳細解説

以下に、AWS SAM CLI で表示されるテンプレート一覧の詳細解説をビジネス用途に即した視点で整理し、それぞれのユースケースや活用ポイントを簡潔にご紹介します。SaaS開発やアーキテクチャ設計の足がかりとして最適な選択を判断する材料になります。


1. Hello World Example

内容:最も基本的なテンプレート。シンプルなLambda + API Gateway構成。
用途:SAM入門・動作確認。
活用:まずSAMの開発フローに慣れるための第一歩に。


2. Data processing

内容:S3にファイルがアップロードされたらLambdaが処理を行う構成。
用途:ETL、画像処理、ログ解析等のバッチ処理に最適。
活用:SaaSのデータ取り込みや一括処理フローに利用可。


3. Hello World Example with Powertools for AWS Lambda

内容:Powertoolsを活用したベストプラクティス版 Hello World。
用途:可観測性(ロギング、トレース、メトリクス)を意識した設計に。
活用:本番運用を前提としたLambda開発の雛形に。


4. Multi-step workflow

内容:Step Functions を使った複数Lambdaによる逐次処理。
用途:ワークフロー自動化、非同期処理、業務オーケストレーション。
活用:SaaS内の登録・承認プロセス、バッチ的なデータ変換処理に有用。


5. Scheduled task

内容:EventBridge Scheduler(旧CloudWatch Events)でLambdaを定期実行。
用途:定期レポート生成、DBクリーニングなどの定期業務。
活用:SaaSのバッチタスクやヘルスチェック等に活用。


6. Standalone function

内容:API Gatewayなし、単体でLambda関数のみを定義。
用途:内部処理、バッチ、非公開関数などに。
活用:非同期イベント連携や内部ユーティリティロジックに。


7. Serverless API

内容:複数のAPIエンドポイント + Lambda + DynamoDB構成。
用途:REST APIベースのアプリに最適。
活用:SaaSの中核となるAPIサーバー構築に直結。(SaaS開発のテンプレートに推奨)


8. Infrastructure event management

内容:インフライベント(例:EC2作成等)をトリガーにLambdaを実行。
用途:自動タグ付け、監査、ガバナンス施策など。
活用:SaaSのアカウント管理や運用自動化機能と相性良好。


9. Lambda Response Streaming

内容:Lambdaからのレスポンスをストリーミング形式で返す例。
用途:大容量応答やストリーミングAPI構築時に使用。
活用:レポート生成やチャート配信などに。


10. GraphQLApi Hello World Example

内容:AppSync + Lambda + DynamoDBによるGraphQL API構成。
用途:柔軟なAPI設計が必要な場合。
活用:複雑なUI要求や、SPAとの親和性が高い。


11. Full Stack

内容:バックエンド(Lambda/API)+ フロントエンド(Reactアプリ)構成。
用途:サーバーレスSPAアプリのフル構成。
活用:短期開発やプロトタイピングに最適。


12. Lambda EFS example

内容:LambdaとAmazon EFSを接続してファイル操作を実装。
用途:大量ファイル処理、旧アーキテクチャの移行対応。
活用:CSV処理、ログストレージ等に。


13. Serverless Connector Hello World Example

内容:SAM Connectors を用いた複数リソース連携の定義例。
用途:シンプルなリソース間接続をYAMLだけで構築。
活用:DynamoDBやSQSなどとの明示的な接続設定を簡易に。


14. Multi-step workflow with Connectors

内容:Step Functions + Connectors構成の複雑なワークフロー例。
用途:実用的な業務処理のオーケストレーションに。
活用:帳票出力、データ変換、メール送信連携など。


15. DynamoDB Example

内容:DynamoDBへのCRUD操作を含むサーバーレス構成。
用途:データ永続化のベーシック構成。
活用:ユーザー情報やトランザクション管理機能に。


16. Machine Learning

内容:LambdaからSageMakerを呼び出す構成。
用途:推論APIやバッチ処理でMLを導入したい場合。
活用:SaaSにおける推薦機能や自動判定処理に拡張可。


SaaS構築に最適なテンプレート選定(結論)

目的推奨テンプレート
REST API構築7 – Serverless API
UI付きSaaS構築11 – Full Stack
Stripe連携や課金処理設計7 + カスタム実装(Stripe SDK)
高度なフロー制御4 or 14 – Multi-step workflow
セキュアなコンテンツ配信7 + CloudFront/WAF追加構成

SAM CLI を使用してプロジェクトを初期化する際の各プロンプトに対する解説と推奨方針

Use the most popular runtime and package type? (python3.13 and zip) [y/N]: y

Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]:

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]:

Would you like to set Structured Logging in JSON format on your Lambda functions? [y/N]:

Project name [sam-app]:

大文字がデフォルト値です。以下は、SAM CLI を使用してプロジェクトを初期化する際の各プロンプトに対する解説と推奨方針です。特に商用SaaS開発に適した選択肢の観点で解説します。


Use the most popular runtime and package type? (python3.13 and zip) [y/N]: y

  • 意味:Python 3.13(現時点で最新安定版)+ZIPパッケージ方式を使うかの選択。
  • 推奨y
  • 理由:再現性と移植性が高く、SAMでの一般的な構成。ZIPは小規模・中規模な関数で最も扱いやすい。

🔍 Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]:

  • 意味:AWS X-Ray による関数の実行トレース(分散トレーシング)を有効にするか。
  • 推奨
    • 商用・本番運用想定 → y
    • ローカル開発・PoC段階 → N
  • 理由:複数Lambda・API連携などでパフォーマンス問題の特定に有効。特にSaaSでは障害調査工数を削減可能。

📊 Would you like to enable monitoring using CloudWatch Application Insights? [y/N]:

  • 意味:CloudWatch Application Insights による自動的なパフォーマンス/障害監視を有効にするか。
  • 推奨
    • 中〜大規模・商用運用 → y
    • 個人開発・予算優先 → N
  • 理由:詳細監視が自動化されて便利だが、コスト増加に注意。料金計算が複雑なため本番前に試験導入を推奨。

📄 Would you like to set Structured Logging in JSON format on your Lambda functions? [y/N]:

  • 意味:ログ出力を JSON 形式で構造化するかどうか。
  • 推奨y
  • 理由:ログ分析やCloudWatch Insights活用において圧倒的に便利。モニタリング・デバッグ効率が格段に向上

🏷️ Project name [sam-app]:

  • 意味:SAM プロジェクトの名前。
  • 推奨:任意のわかりやすい名前(例:saas-api, ml-ingest, billing-service など)
  • ポイント
    • ステージ名(dev, prod)や用途(auth, core)などを接尾辞に含めるとCI/CD構成でも整理しやすくなります。

💡まとめ(SaaS開発向け設定例):

項目推奨設定
ランタイムとパッケージy(Python3.13 + ZIP)
X-Ray トレーシングy(本番を見据えるなら)
Application InsightsN(コスト優先。商用は y 検討)
Structured Loggingy(JSON形式ログ)
プロジェクト名saas-core-api など明確な名称

対話式 CLI のルール:「大文字がデフォルト」

AWS SAM CLI(や他の多くのCLIツール)では、プロンプトの [y/N][Y/n] の表記が示す通り:

  • **大文字の方がデフォルト**
  • 何も入力せずに Enter を押した場合、その 大文字の選択肢 が自動的に適用されます。

📝 sam init 後のCLI対話解説


✅ 1. Telemetry の案内

SAM CLI now collects telemetry...
  • 目的: 利用状況を匿名で収集して改善に活用。
  • 無効化したい場合: setx SAM_CLI_TELEMETRY 0(Windows)または export SAM_CLI_TELEMETRY=0(Unix系)

✅ 2. テンプレートのソース選択

Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
  • 1: AWS公式テンプレート
  • 2: GitHub等の外部リポジトリURL指定も可能

✅ 3. テンプレート選択

Template: 1  # Hello World Example
  • 選択肢 1 の内容:最小構成のAPI Gateway + Lambda(GET /hello
    → 初学者〜プロトタイプ開発に最適

✅ 4. ランタイムとパッケージ形式の確認

Use the most popular runtime and package type? (python3.13 and zip) [y/N]: y
  • yes の場合
    • ランタイム:python3.13
    • パッケージ形式:zip(=コードと依存をzipにまとめてデプロイ)
  • 代替として Image パッケージ(Dockerベース)も可能

✅ 5. X-Ray トレーシングの有効化

Would you like to enable X-Ray tracing...? [y/N]:
  • X-Ray:Lambdaの内部呼び出しトレース可視化(パフォーマンス分析に有効)
  • 実運用では yes を推奨(特に複数サービス連携時)

✅ 6. CloudWatch Application Insights

Would you like to enable monitoring using CloudWatch Application Insights? [y/N]:
  • Lambdaや他リソースの 自動モニタリング/異常検出
  • 本格運用では有効だが、費用が発生する点に留意

✅ 7. Structured Logging(JSON形式ログ)

Would you like to set Structured Logging in JSON format...? [y/N]:
  • メリット
    • ログ分析(CloudWatch Logs Insights)で強力な検索が可能
    • Datadogなど外部モニタリングとも連携しやすい
  • 通常は yes を推奨

✅ 8. プロジェクト名の指定

Project name [sam-app]:
  • 空Enter ⇒ sam-app フォルダが作成される
  • 名前を明示すると、別プロジェクトとの区別が明確になる(推奨)

✅ 9. テンプレートクローンと初期構成

Cloning from https://github.com/aws/aws-sam-cli-app-templates...
  • 選択したテンプレートが GitHub から取得され、ローカルに雛形を展開
  • samconfig.toml により、今後の操作が自動化・省略可能

✅ 10. 生成後の推奨コマンド

[*] Create pipeline...
[*] Validate SAM template...
[*] Test Function in the Cloud...
コマンド概要
sam pipeline init --bootstrapCodePipelineなどの自動化構築
sam validateテンプレート構文チェック
sam sync --watchホットリロード的なクラウド反映(開発中に便利)

✅ 次のステップ(実用的な流れ)

  1. cd sam-app
  2. コード修正(例:hello_world/app.py
  3. sam build
  4. sam deploy --guided で初回デプロイ
  5. sam sync --watch でクラウド上にリアルタイム反映

5. コア機能の構築

以下は、AWS SAMで構築した「Hello Worldテンプレート」をベースに、主要リソース(Cognito、DynamoDB、Lambda、API Gateway)を含み、今後の追加にも容易に拡張できます。SaaSアプリへ発展させるための構成設計およびハンズオン手順です。

生成された構造

sam-app/
├── README.md
├── events/
│ └── event.json
├── hello_world/
│ ├── __init__.py
│ ├── app.py # Lambda関数のエントリーポイント
│ └── requirements.txt
├── template.yaml

🔧 システム構成概要(最小コスト構成)

コンポーネント使用サービス目的・備考
認証/ユーザー管理Amazon Cognitoユーザー登録、ログイン、JWTトークン発行
APIサーバーAPI Gateway + AWS LambdaREST API 構築。トークン検証はJWTレベルで行う
バックエンドAWS Lambda (Python)ビジネスロジック実装
データベースAmazon DynamoDBマルチテナント対応、NoSQLによるコスト・スケーラビリティ重視
フロントエンドNext.js(CloudFront経由でデプロイ)静的コンテンツ + 認証統合
決済Stripeサブスクリプション管理(Lambda連携)
CI/CDGitHub Actions + SAM CLI自動ビルド・自動デプロイ
モニタリング/運用監視CloudWatch Logs / Alarms障害・性能監視用

template.yaml の追記

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SaaS Core Functionalities with Auth, Billing, Infra, CI/CD, and Monitoring

Globals:
Function:
Timeout: 10
Runtime: python3.13
Tracing: Active
LoggingConfig:
LogFormat: JSON

Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: saas-user-pool

CognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
UserPoolId: !Ref CognitoUserPool
GenerateSecret: false

CustomersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Customers
AttributeDefinitions:
- AttributeName: customerId
AttributeType: S
KeySchema:
- AttributeName: customerId
KeyType: HASH
BillingMode: PAY_PER_REQUEST

SubscriptionFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/functions/subscription/
Handler: app.lambda_handler
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref CustomersTable
Environment:
Variables:
STRIPE_API_KEY: "{{resolve:secretsmanager:stripe-api-key}}"

SubscriptionApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
DefaultAuthorizer: CognitoAuth
AddDefaultAuthorizerToCorsPreflight: false
Authorizers:
CognitoAuth:
UserPoolArn: !GetAtt CognitoUserPool.Arn
DefinitionBody:
openapi: 3.0.1
info:
title: SaaS API
version: '1.0'
paths:
/subscribe:
post:
x-amazon-apigateway-integration:
uri: !Sub
- arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${FunctionArn}/invocations
- { FunctionArn: !GetAtt SubscriptionFunction.Arn }
httpMethod: POST
type: aws_proxy

Outputs:
ApiUrl:
Description: "API Gateway endpoint URL"
Value: !Sub "https://${SubscriptionApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"

CognitoUserPoolId:
Description: "Cognito User Pool ID"
Value: !Ref CognitoUserPool

Lambda関数の作成

Lambda関数を作成し、ビジネスロジックを実装します。例えば、サブスクリプションの作成や顧客データの更新を行う関数を作成します。

  • /src/functions/subscription/app.pylambda_handler を実装。
  • 顧客IDの登録やStripe連携を行います。
# src/functions/subscription/app.py
import json
import boto3
import stripe
import os

stripe.api_key = os.environ['STRIPE_API_KEY']
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Customers')

def lambda_handler(event, context):
data = json.loads(event['body'])
customer_id = data['customerId']
email = data['email']

# Stripe顧客作成
customer = stripe.Customer.create(email=email)

# DynamoDBへ登録
table.put_item(Item={"customerId": customer_id, "email": email, "stripeId": customer.id})

return {
"statusCode": 200,
"body": json.dumps({"message": "Customer created", "stripeCustomerId": customer.id})
}

API Gatewayの設定

API Gatewayを設定し、Lambda関数とHTTPリクエストを接続します。API Gatewayは、HTTPリクエストを受け付け、それをLambda関数に転送する役割を担います。


6. サブスクリプション管理

Stripe統合

顧客の支払い処理には、Stripeを使用します。Lambda関数内でStripe SDKを使って、サブスクリプションの作成や更新を行います。

  • Lambda関数内に stripe.Subscription.create(...) を追加することで、定期課金プラン作成も可能。
  • Stripe APIキーは Secrets Manager に保存し、Environment.Variables により安全に参照。

7. 共通インフラ

DynamoDBによるデータ管理

顧客情報やサブスクリプション情報をDynamoDBで管理します。DynamoDBは高スケーラブルなNoSQLデータベースであり、SaaSアプリケーションには最適です。

DynamoDB構成済み(CustomersTable

CloudFront + WAFによるセキュリティ強化

CloudFrontを利用して静的コンテンツをキャッシュし、WAFを使ってアプリケーションを攻撃から保護します。CloudFront+WAFは、Next.js フロントの静的ファイルを S3 に配置して追加予定。


8. CI/CDの実装

GitHub Actionsによる自動デプロイ

コードの変更をGitHubにプッシュすると、自動的にSAMアプリケーションがデプロイされるようにCI/CDパイプラインを構築します。これにより、開発フローを効率化します。

# .github/workflows/deploy.yml
name: Deploy SAM App

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.10
- name: Install AWS SAM
run: pip install aws-sam-cli
- name: Build
run: sam build
- name: Deploy
run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --stack-name saas-app --capabilities CAPABILITY_IAM --region ap-northeast-1
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

9. テストとデプロイ

ローカルでのテスト

SAM CLIのsam localコマンドを使用して、Lambda関数やAPI Gatewayをローカルでテストします。

# ローカルテスト
sam local invoke SubscriptionFunction --event events/event.json

本番環境へのデプロイ

アプリケーションが完成したら、以下のコマンドを使ってAWS環境にデプロイします。

# デプロイ
sam deploy --guided

10. 監視とロギング

CloudWatch LogsとCloudWatch Alarmsによる監視

Lambda関数やAPI GatewayのログをCloudWatch Logsに送信し、エラーやパフォーマンスの監視を行います。また、CloudWatch Alarmsを設定して、特定のイベントに対応します。

  • Tracing: ActiveLogFormat: JSON 設定済み。
  • 必要に応じて AWS::CloudWatch::Alarm を追加。

11. 最適化とスケーリング

オートスケーリングの設定

Lambda関数の同時実行数やDynamoDBのスループットを適切に設定して、アプリケーションのスケーラビリティを確保します。

  • DynamoDBは PAY_PER_REQUEST モードを採用(オートスケーリング不要)。
  • Lambdaは同時実行数により自動スケール。必要に応じて ReservedConcurrentExecutions を設定可能。

12. まとめと次のステップ

本記事では、AWS SAMを活用してSaaSアプリケーションを構築する方法を解説しました。SAMを使用することで、サーバーレスアーキテクチャの構築が迅速かつ効率的に行えます。次のステップとして、監視やセキュリティ強化、パフォーマンスの最適化を検討してください。


このガイドを実践することで、AWS SAMを使用したSaaSアプリケーション開発の基本を押さえ、実際に運用可能なシステムを構築できるようになります。

コメント

タイトルとURLをコピーしました