はじめに
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をインストールします。
- 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 Insights | N (コスト優先。商用は y 検討) |
Structured Logging | y (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 --bootstrap | CodePipelineなどの自動化構築 |
sam validate | テンプレート構文チェック |
sam sync --watch | ホットリロード的なクラウド反映(開発中に便利) |
✅ 次のステップ(実用的な流れ)
cd sam-app
- コード修正(例:
hello_world/app.py
) sam build
sam deploy --guided
で初回デプロイ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 Lambda | REST API 構築。トークン検証はJWTレベルで行う |
バックエンド | AWS Lambda (Python) | ビジネスロジック実装 |
データベース | Amazon DynamoDB | マルチテナント対応、NoSQLによるコスト・スケーラビリティ重視 |
フロントエンド | Next.js(CloudFront経由でデプロイ) | 静的コンテンツ + 認証統合 |
決済 | Stripe | サブスクリプション管理(Lambda連携) |
CI/CD | GitHub 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.py
にlambda_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: Active
とLogFormat: JSON
設定済み。- 必要に応じて
AWS::CloudWatch::Alarm
を追加。
11. 最適化とスケーリング
オートスケーリングの設定
Lambda関数の同時実行数やDynamoDBのスループットを適切に設定して、アプリケーションのスケーラビリティを確保します。
- DynamoDBは
PAY_PER_REQUEST
モードを採用(オートスケーリング不要)。 - Lambdaは同時実行数により自動スケール。必要に応じて
ReservedConcurrentExecutions
を設定可能。
12. まとめと次のステップ
本記事では、AWS SAMを活用してSaaSアプリケーションを構築する方法を解説しました。SAMを使用することで、サーバーレスアーキテクチャの構築が迅速かつ効率的に行えます。次のステップとして、監視やセキュリティ強化、パフォーマンスの最適化を検討してください。
このガイドを実践することで、AWS SAMを使用したSaaSアプリケーション開発の基本を押さえ、実際に運用可能なシステムを構築できるようになります。
コメント