PR

AWS SAM ではじめるフルスタックサーバーレス開発ハンズオン

はじめに

本記事では、初心者向けに AWS SAM(Serverless Application Model)を用いて、以下の構成を持つフルスタックWebアプリケーションを最小構成で構築する手順を丁寧に解説します。

  • バックエンド:Lambda(Python)+ API Gateway + DynamoDB
  • フロントエンド:Next.js(静的ビルド)+ S3 + CloudFront

無料枠の範囲で完結し、かつ再現性・拡張性の高いテンプレートをベースにしています。


前提条件

  • AWS CLI, SAM CLI, Node.js, Python3.11 のインストール済み
  • AWSアカウントがあること(IAMユーザーは管理者権限推奨)
  • GitHubアカウント(CI/CDなど拡張する場合)

ディレクトリ構成

my-sam-app/
├── src/                 # バックエンド(Lambda)
│   └── app.py
├── frontend/           # フロントエンド(Next.js)
│   └── ...
├── template.yaml       # SAMテンプレート
└── README.md

1. SAM プロジェクトの初期化

sam init --runtime python3.13 --name my-sam-app
cd my-sam-app

2. Lambda 関数(FastAPI 例)

src/app.py

from fastapi import FastAPI
from mangum import Mangum
import os
import boto3

app = FastAPI()
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(os.environ["TABLE_NAME"])

@app.get("/items/{item_id}")
def read_item(item_id: str):
    response = table.get_item(Key={"id": item_id})
    return response.get("Item", {})

handler = Mangum(app)

3. SAM テンプレート template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Full-stack serverless app with Lambda (Python), API Gateway, DynamoDB, S3, and CloudFront

Globals:
Function:
Runtime: python3.13
Timeout: 10
MemorySize: 256

Resources:

### Lambda Function ###
ApiFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
CodeUri: src/
Events:
Api:
Type: Api
Properties:
Path: /{proxy+}
Method: ANY
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref AppTable
Environment:
Variables:
TABLE_NAME: !Ref AppTable

### DynamoDB ###
AppTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: AppDataTable
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH

### S3 for Frontend ###
WebAppBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${AWS::StackName}-webapp"
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: index.html
AccessControl: PublicRead

### CloudFront Distribution ###
WebAppCDN:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
Origins:
- DomainName: !GetAtt WebAppBucket.RegionalDomainName
Id: WebAppOrigin
S3OriginConfig: {}
DefaultCacheBehavior:
TargetOriginId: WebAppOrigin
ViewerProtocolPolicy: redirect-to-https
AllowedMethods: ["GET", "HEAD", "OPTIONS"]
CachedMethods: ["GET", "HEAD"]
ForwardedValues:
QueryString: false
DefaultRootObject: index.html
ViewerCertificate:
CloudFrontDefaultCertificate: true
HttpVersion: http2

Outputs:
ApiEndpoint:
Description: "API Gateway endpoint"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
FrontendURL:
Description: "Frontend CDN URL"
Value: !GetAtt WebAppCDN.DomainName

4. デプロイ手順

sam build
sam deploy --guided
  • プロンプトに従ってスタック名、リージョン、S3バケット名など入力

5. フロントエンド(Next.js)構築とS3アップロード

cd frontend
npm install
npm run build
npm run export
aws s3 sync out/ s3://[作成されたS3バケット名] --delete

6. CloudFront URLで確認

# SAM Outputs に表示された CloudFront ドメインにアクセス
https://xxxxxxx.cloudfront.net/

7. 更新・開発・再デプロイ手順

バックエンドの修正 → 再デプロイ

# app.py を編集したら以下を実行
sam build
sam deploy

フロントエンドの修正 → S3再アップロード

npm run build
npm run export
aws s3 sync out/ s3://[対象のS3バケット名] --delete

まとめ

このテンプレートをベースにすることで、

  • 高速な初期構築
  • 無料枠中心の低コスト運用
  • API拡張やCI/CD、認証(Cognito)などへのスムーズな発展

が可能になります。今後は、GitHub Actions による CI/CD、自動テスト導入、ACM + Route 53 による独自ドメイン化なども視野に入れて拡張していくとよいでしょう。


次回予告

  • SAM + GitHub Actions でCI/CD完全自動化
  • APIテストの自動化(pytest + coverage)
  • フロントエンドにCognito認証を追加する

お気に入り登録&フォローで通知をお見逃しなく!

コメント

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