AWS SAMとは?初心者でもわかる基礎知識
AWS SAM(Serverless Application Model)は、サーバーレスアプリケーションを構築するためのオープンソースフレームワークです。AWS Lambda、Amazon API Gateway、DynamoDBなどのサーバーレスリソースを簡単に定義し、デプロイすることができます。
AWS SAMが解決する3つの開発課題
- 複雑な設定の簡素化
- CloudFormationテンプレートの記述量を大幅に削減
- サーバーレスリソースに特化したシンプルな構文
- 設定ミスのリスクを低減
- ローカル開発環境の統一
sam localコマンドによるローカルテスト環境の提供- Lambda関数のローカル実行が可能
- APIのエンドポイントをローカルで確認可能
- デプロイメントの効率化
- シンプルなコマンドでのデプロイ
- 段階的なデプロイメント戦略の実現
- ロールバックの容易さ
従来のサーバーレス開発との違い
| 観点 | 従来の方法 | AWS SAM |
|---|---|---|
| テンプレート記述量 | 多い(詳細な設定が必要) | 少ない(簡略化された構文) |
| ローカルテスト | 困難(実環境が必要) | 容易(ローカル環境で可能) |
| デプロイ手順 | 複雑(複数のステップ) | シンプル(単一コマンド) |
| 学習コスト | 高い(多くの知識が必要) | 低い(直感的な API) |
AWS SAMのメリット・デメリット
メリット:
- 開発効率の向上
- シンプルな構文による素早い開発
- 豊富なサンプルテンプレートの利用
- 統合されたツールチェーンの提供
- コスト削減
- ローカルテストによる AWS 利用料の削減
- 効率的なリソース管理
- 運用コストの最適化
- 品質向上
- 標準化されたベストプラクティス
- 一貫性のある開発環境
- 自動化されたテスト環境
デメリット:
- 柔軟性の制限
- SAM特有の制約が存在
- 一部の高度なカスタマイズが困難
- すべてのAWSサービスをサポートしているわけではない
- 追加の学習コスト
- SAM特有の概念の理解が必要
- 新しいツールチェーンの習得
- トラブルシューティングのスキル
- ベンダーロックイン
- AWS特有の実装への依存
- 他のクラウドプロバイダーへの移行が困難
- AWSのサービス更新への追従が必要
AWS SAMは、特にAWSでのサーバーレスアプリケーション開発を始める際の最適な選択肢となります。開発効率の向上とローカルテスト環境の充実により、サーバーレスアプリケーションの開発・運用がより身近なものとなります。ただし、プロジェクトの要件や制約を考慮した上で、採用を検討することが重要です。
AWS SAM環境構築の手順と注意点
AWS SAMを使用するための環境構築について、必要なツールのインストールから認証情報の設定まで、詳しく解説します。
必要なツールのインストール方法
- AWS CLIのインストール
# Windows(PowerShell管理者権限) msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi # macOS brew install awscli # Linux curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install
- AWS SAM CLIのインストール
# Windows(PowerShell管理者権限) choco install aws-sam-cli # macOS brew tap aws/tap brew install aws-sam-cli # Linux wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip unzip aws-sam-cli-linux-x86_64.zip -d sam-installation sudo ./sam-installation/install
- Dockerのインストール
- Docker Desktopからインストーラーをダウンロード
- ローカルでのLambda関数実行に必要
- 開発環境の準備
- VS Code等のテキストエディタ
- Python, Node.js等の実行環境(使用する言語に応じて)
AWS認証情報の設定ポイント
- IAMユーザーの作成
- AWS Management Consoleにログイン
- IAMダッシュボードから新規ユーザー作成
- 必要な権限の付与:
json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cloudformation:*", "sam:*", "lambda:*", "apigateway:*", "iam:*", "s3:*" ], "Resource": "*" } ] }
- 認証情報の設定
# AWS CLIの設定 aws configure # 以下の情報を入力 AWS Access Key ID: [アクセスキーID] AWS Secret Access Key: [シークレットアクセスキー] Default region name: [リージョン名(例:ap-northeast-1)] Default output format: json
- プロファイルの設定(複数環境の場合)
# 開発環境用プロファイル aws configure --profile dev # 本番環境用プロファイル aws configure --profile prod
トラブルシューティング
- 一般的なエラーと対処法 エラー 原因 対処法
AWS SAM CLI not foundパスが通っていない 環境変数の設定を確認Docker daemon not runningDockerが起動していない Docker Desktopの起動Unable to locate credentials認証情報未設定aws configureの実行Permission denied権限不足 IAMポリシーの確認・修正 - 環境別の注意点 Windows:
- PowerShellの実行ポリシー設定
- WSL2との連携設定
- パスの区切り文字の違いに注意 macOS/Linux:
- パーミッションの適切な設定
$PATHへの追加確認- シンボリックリンクの取り扱い
- 動作確認の方法
# バージョン確認 sam --version aws --version docker --version # SAMテンプレートの検証 sam validate # ローカル環境のテスト sam local start-api
環境構築時は、特に認証情報の設定と必要な権限の付与に注意が必要です。また、ローカル開発環境でのテストには、Dockerが正常に動作している必要があります。トラブル発生時は、まず各コンポーネントのバージョンと設定を確認することをお勧めします。
AWS SAMによるローカル開発の実践手順
AWS SAMを使用したローカル開発環境の構築から、実際の開発手順まで、実践的な内容を解説します。
プロジェクトの作成と基本構成
- 新規プロジェクトの作成
# プロジェクトの初期化 sam init # 対話式の設定 Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 What package type would you like to use? 1 - Zip (artifact is a zip uploaded to S3) 2 - Image (artifact is an image uploaded to ECR) Package type: 1 Which runtime would you like to use? 1 - nodejs18.x 2 - python3.9 3 - ruby2.7 Runtime: 2 Project name: my-serverless-app
- プロジェクトの基本構造
my-serverless-app/ ├── .aws-sam/ # ビルドアーティファクト ├── events/ # テストイベント │ └── event.json ├── src/ # ソースコード │ ├── handlers/ # Lambda関数 │ └── layers/ # Lambdaレイヤー ├── tests/ # テストコード ├── samconfig.toml # SAM設定ファイル └── template.yaml # SAMテンプレート
- 開発環境のセットアップ
# 仮想環境の作成(Python使用時) python -m venv .venv source .venv/bin/activate # Unix系 .venv\Scripts\activate # Windows # 依存パッケージのインストール pip install -r requirements.txt # 開発用パッケージの追加 pip install pytest pytest-mock boto3
template.yamlの書き方と重要な設定項目
- 基本的なテンプレート構造
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAMアプリケーションのサンプル
Globals:
Function:
Timeout: 30
MemorySize: 128
Runtime: python3.9
Environment:
Variables:
STAGE: dev
Parameters:
Stage:
Type: String
Default: dev
AllowedValues:
- dev
- stg
- prod
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/handlers/hello_world/
Handler: app.lambda_handler
Events:
HelloApi:
Type: Api
Properties:
Path: /hello
Method: get
# DynamoDBテーブルの定義例
UsersTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: userId
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
- 重要な設定項目の解説 設定項目 説明 使用例 CodeUri 関数コードの場所
CodeUri: src/handlers/function/Handler エントリーポイントHandler: app.lambda_handlerEvents トリガーの定義 API Gateway, SNS等のイベント設定 Environment 環境変数 ステージ、API키等の設定 Policies IAMポリシー リソースアクセス権限の設定 - 共通設定(Globals)の活用
Globals:
Function:
Timeout: 30
MemorySize: 128
Runtime: python3.9
Tags:
Environment: !Ref Stage
Environment:
Variables:
STAGE: !Ref Stage
LOG_LEVEL: INFO
Lambda関数のローカルテスト方法
- ローカルでの関数呼び出し
# 関数の直接呼び出し sam local invoke HelloWorldFunction --event events/event.json # APIのローカル起動 sam local start-api # APIのテスト curl http://localhost:3000/hello
- テストイベントの作成(events/event.json)
{
"httpMethod": "GET",
"path": "/hello",
"queryStringParameters": {
"name": "SAM"
},
"headers": {
"Accept": "application/json"
}
}
- デバッグの設定(VS Code使用時)
{
"version": "0.2.0",
"configurations": [
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "Debug SAM Local",
"invokeTarget": {
"target": "template",
"templatePath": "template.yaml",
"logicalId": "HelloWorldFunction"
},
"lambda": {
"payload": {
"json": {
"httpMethod": "GET",
"path": "/hello"
}
}
}
}
]
}
- ユニットテストの実装例(tests/unit/test_handler.py)
import json
import pytest
from src.handlers.hello_world import app
def test_lambda_handler():
event = {
"httpMethod": "GET",
"queryStringParameters": {"name": "SAM"}
}
response = app.lambda_handler(event, None)
assert response["statusCode"] == 200
body = json.loads(response["body"])
assert "message" in body
assert "Hello SAM" in body["message"]
ローカル開発環境でのテストを効率的に行うことで、デプロイ前のバグを早期に発見し、開発サイクルを短縮することができます。特に、sam localコマンドを活用することで、AWS環境を使用することなくローカルでの動作確認が可能になります。
本番環境へのデプロイ手順と運用管理
AWS SAMを使用した本番環境へのデプロイ手順と、効果的な運用管理の方法について解説します。
デプロイメントパイプラインの構築方法
- AWS CodePipelineを使用したCI/CD構築
# template.yaml内にパイプライン定義を追加
Resources:
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: Source
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: '1'
Configuration:
RepositoryName: !Ref RepositoryName
BranchName: main
OutputArtifacts:
- Name: SourceCode
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: '1'
Configuration:
ProjectName: !Ref BuildProject
InputArtifacts:
- Name: SourceCode
OutputArtifacts:
- Name: BuildOutput
- デプロイメント設定ファイル(samconfig.toml)
version = 0.1[default] [default.deploy] [default.deploy.parameters]
stack_name = “my-serverless-app” s3_bucket = “my-deployment-bucket” s3_prefix = “my-serverless-app” region = “ap-northeast-1” confirm_changeset = true capabilities = “CAPABILITY_IAM” parameter_overrides = “Stage=prod”
[prod] [prod.deploy.parameters] stack_name = “my-serverless-app-prod” parameter_overrides = “Stage=prod”- デプロイコマンドの実行
# ビルド sam build # テスト環境へのデプロイ sam deploy --config-env dev # 本番環境へのデプロイ sam deploy --config-env prod
ステージング環境の作成とテスト
- 環境別の設定管理 環境 用途 特徴 dev 開発 機能開発、ユニットテスト stg 検証 統合テスト、性能テスト prod 本番 実運用環境
- 環境変数の管理
# 環境別のパラメータストアの使用
aws ssm put-parameter \
--name "/myapp/prod/database-url" \
--value "prod-db-url" \
--type SecureString
# template.yamlでの参照
Parameters:
DatabaseUrl:
Type: AWS::SSM::Parameter::Value<String>
Default: /myapp/${Stage}/database-url
- 統合テストの実施
# tests/integration/test_api.py
import requests
import pytest
@pytest.mark.integration
def test_api_endpoint():
base_url = "https://api.example.com" # ステージング環境のURL
response = requests.get(f"{base_url}/hello")
assert response.status_code == 200
data = response.json()
assert "message" in data
本番環境での監視設定とアラート
- CloudWatchメトリクスの設定
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Events:
HelloApi:
Type: Api
AutoPublishAlias: live
DeploymentPreference:
Type: Linear10PercentEvery10Minutes
Alarms:
- ErrorAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Lambda function error rate > 0
MetricName: Errors
Threshold: 0
Period: 300
EvaluationPeriods: 1
ComparisonOperator: GreaterThanThreshold
Namespace: AWS/Lambda
Statistic: Sum
- 主要な監視項目 メトリクス 説明 推奨閾値 Duration 関数実行時間 p95 < 1000ms Errors エラー数 0 Throttles スロットル数 0 ConcurrentExecutions 同時実行数 < 設定値の80% IteratorAge イベント処理の遅延 < 1分
- アラート通知の設定
Resources:
AlertTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub ${AWS::StackName}-alerts
Subscription:
- Protocol: email
Endpoint: alert@example.com
HighErrorAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmActions:
- !Ref AlertTopic
AlarmDescription: High error rate detected
MetricName: Errors
Namespace: AWS/Lambda
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 1
ComparisonOperator: GreaterThanThreshold
本番環境への展開は慎重に行う必要があります。段階的なデプロイメント戦略を採用し、適切な監視とアラート設定を行うことで、安定した運用を実現できます。特に、CloudWatchを活用した監視体制の構築は、問題の早期発見と迅速な対応に不可欠です。
AWS SAMのベストプラクティスと実践的なTips
実務でAWS SAMを活用する際の重要なベストプラクティスと、本番環境での実践的なTipsを解説します。
セキュリティ強化のための設定方法
- 最小権限の原則の適用
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
Runtime: python3.9
Policies:
# 必要最小限の権限を定義
- Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
Resource: !GetAtt MyTable.Arn
Condition:
StringEquals:
aws:RequestedRegion: !Ref AWS::Region
- 機密情報の安全な管理
Resources:
SecureFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
# 直接値を書かず、Systems Managerパラメータストアを使用
API_KEY: '{{resolve:ssm-secure:/myapp/api-key:1}}'
DB_PASSWORD: '{{resolve:secretsmanager:MyDBSecret:SecretString:password}}'
- セキュリティグループとVPCの設定
Resources:
VPCFunction:
Type: AWS::Serverless::Function
Properties:
VpcConfig:
SecurityGroupIds:
- !Ref LambdaSecurityGroup
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Policies:
- VPCAccessPolicy: {}
コスト最適化のためのアーキテクチャ設計
- Lambda関数の最適化
Globals:
Function:
# メモリサイズの最適化
MemorySize: 256
# タイムアウトの適切な設定
Timeout: 6
# 環境変数のキャッシュ
Environment:
Variables:
POWERTOOLS_SERVICE_NAME: myapp
POWERTOOLS_METRICS_NAMESPACE: myapp
# レイヤーの活用
Layers:
- !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:19
- リソースの効率的な利用
Resources:
# DynamoDBのオートスケーリング設定
UsersTable:
Type: AWS::DynamoDB::Table
Properties:
BillingMode: PAY_PER_REQUEST
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
SSESpecification:
SSEEnabled: true
# S3のライフサイクルルール設定
StorageBucket:
Type: AWS::S3::Bucket
Properties:
LifecycleConfiguration:
Rules:
- Id: TransitionToIA
Status: Enabled
Transitions:
- TransitionInDays: 30
StorageClass: STANDARD_IA
- コスト監視の設定
Resources:
CostAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Daily estimated charges > $10
Namespace: AWS/Billing
MetricName: EstimatedCharges
Statistic: Maximum
Period: 21600 # 6時間
EvaluationPeriods: 1
Threshold: 10
ComparisonOperator: GreaterThanThreshold
大規模開発での注意点と対策
- モジュール化とコード管理
# 共通のパラメータを定義(parameters.yaml)
Parameters:
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- stg
- prod
# 共通のポリシーを定義(policies.yaml)
Policies:
CommonLambdaPolicy:
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
# メインテンプレート(template.yaml)
Transform: AWS::Serverless-2016-10-31
Resources:
ApiFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src/api
Policies:
- !Include policies.yaml#CommonLambdaPolicy
- デプロイメント戦略
Resources:
ApiFunction:
Type: AWS::Serverless::Function
Properties:
AutoPublishAlias: live
DeploymentPreference:
Type: Linear10PercentEvery10Minutes
Hooks:
PreTraffic: !Ref PreTrafficHook
PostTraffic: !Ref PostTrafficHook
Alarms:
- !Ref FunctionErrorAlarm
- チーム開発のためのベストプラクティス カテゴリ ベストプラクティス 実装方法 コード管理 モノレポ構成 src/配下に機能別ディレクトリ テスト 自動テスト GitHub Actions/CodeBuild レビュー PRテンプレート .github/pull_request_template.md ドキュメント 自動生成 AWS SAM CLI generate-docs
- トラブルシューティングのためのロギング設定
# app.py
import logging
from aws_lambda_powertools import Logger, Tracer, Metrics
logger = Logger()
tracer = Tracer()
metrics = Metrics()
@logger.inject_lambda_context
@tracer.capture_lambda_handler
def lambda_handler(event, context):
try:
# ビジネスロジック
logger.info("Processing request", extra={
"event": event
})
metrics.add_metric(name="SuccessfulRequests", unit="Count", value=1)
return {
"statusCode": 200,
"body": "Success"
}
except Exception as e:
logger.exception("Error processing request")
metrics.add_metric(name="FailedRequests", unit="Count", value=1)
raise
AWS SAMを使用した大規模開発では、セキュリティ、コスト、運用性のバランスを取ることが重要です。適切なモジュール化とCI/CDパイプラインの構築、そして包括的なモニタリング体制の確立により、効率的な開発と運用が可能になります。