Terraform × AWS SAM で実現するサーバーレス開発とIaC管理のベストプラクティス
はじめに
現場のクラウド開発では、サーバーレス技術を活用しながら、同時に確実なインフラ管理も求められます。
AWSにおいては Terraform と AWS SAM(Serverless Application Model)の組み合わせが、開発と運用のバランスを取るうえで有効です。
この記事では、Terraform で環境を管理しつつ、SAM で Lambda コードをデプロイするベストプラクティスを解説します。
TerraformとSAMの使い分け課題
Terraform はクラウドインフラを統一的に管理できる便利なツールですが、Lambda や API Gateway のように粒度が細かく頻繁に変更されるサービスでは、SAM の方が運用しやすいケースが多くあります。
使い分け例
Terraform が管理するリソース
- S3バケット
- IAM Role
- CloudFormation Stack(SAMテンプレートを参照)
SAM が管理するリソース
template.yaml
- LambdaコードとAPI定義
構成図解(Mermaid)
実装ステップ
このセクションでは、TerraformとSAMそれぞれでの構成手順を紹介します。
🏗 Terraformで管理するリソース構成
以下は、SAMテンプレートをS3に置き、CloudFormation経由でスタックを管理するためのTerraformコード例です。
resource "aws_s3_bucket" "sam" {
bucket = "my-sam-template"
}
resource "aws_cloudformation_stack" "sam_app" {
name = "my-sam-stack"
template_url = "https://s3.amazonaws.com/my-sam-template/template.yaml"
capabilities = ["CAPABILITY_IAM"]
}
-
aws_s3_bucket
: SAMテンプレートを配置するS3バケット -
aws_cloudformation_stack
: SAMのtemplate.yamlを適用するためのCloudFormationスタック
⚙️ SAMで管理する template.yaml
の例
以下は、SAMテンプレート(template.yaml
)で Lambda 関数と API Gateway イベントを定義した構成です。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs18.x
CodeUri: ./src
Events:
Api:
Type: Api
Properties:
Path: /hello
Method: get
-
Transform
:SAMテンプレートを使用するための指定 -
CodeUri
:Lambda関数のコードが格納されているローカルまたはS3のパス -
Handler
:Lambdaのエントリーポイント(例:index.handler
) -
Events
:API Gateway経由でトリガーされるルーティング設定
✅ デプロイフローの補足
1. sam build
sam build
2. sam package
sam package \
--output-template-file packaged.yaml \
--s3-bucket my-sam-bucket
-
--output-template-file
:CloudFormationに渡すテンプレートファイルの出力先 -
--s3-bucket
:アップロード先のS3バケット名(事前に作成が必要)
3. sam deploy
sam deploy \
--template-file packaged.yaml \
--stack-name my-sam-app \
--capabilities CAPABILITY_IAM
💡 補足Tips
sam deploy --guided
この実行により samconfig.toml
が作成され、次回以降は以下のように短縮して実行できます:
sam deploy
📝 よくある注意点
- S3バケットは事前に作成しておく必要があります
- IAMロールの設定ミスは
ROLLBACK_IN_PROGRESS
を引き起こします -
CodeUri
の誤指定やテンプレートの不整合に注意
CI/CD連携例(GitHub Actions)
name: Deploy SAM via Terraform
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install SAM CLI
run: |
pip install aws-sam-cli
- name: Build and Package
run: |
sam build
sam package \
--output-template-file packaged.yaml \
--s3-bucket ${{ secrets.SAM_BUCKET }}
- name: Terraform Apply
run: |
terraform init
terraform apply -auto-approve
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GitHubサンプルリポジトリ
🚧 現在準備中です。公開し次第、リンクを更新します。
まとめ
- Terraform はインフラの構築と管理に最適
- SAM はアプリケーションロジックの開発・デプロイに適している
- 責務を分離することで、チーム全体の生産性が向上する