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 running
Dockerが起動していない 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_handler
Events トリガーの定義 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パイプラインの構築、そして包括的なモニタリング体制の確立により、効率的な開発と運用が可能になります。