【完全ガイド】TerraformとAWS SAMを組み合わせてLambdaを安全・柔軟に管理する方法

# Terraform × AWS SAM で実現するサーバーレス開発とIaC管理のベストプラクティス

## はじめに

現場のクラウド開発では、サーバーレス技術を活用しながら、同時に確実なインフラ管理も求められます。

AWSにおいては Terraform と AWS SAM（Serverless Application Model）の組み合わせが、開発と運用のバランスを取るうえで有効です。

この記事では、**Terraform で環境を管理しつつ、SAM で Lambda コードをデプロイするベストプラクティス**を解説します。




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/54f1dd6c-c8a5-41f4-a706-60f1c73ba0f6.png)









---

## TerraformとSAMの使い分け課題

Terraform はクラウドインフラを統一的に管理できる便利なツールですが、Lambda や API Gateway のように粒度が細かく頻繁に変更されるサービスでは、**SAM の方が運用しやすいケースが多くあります**。

### 使い分け例

#### Terraform が管理するリソース

- S3バケット
- IAM Role
- CloudFormation Stack（SAMテンプレートを参照）

#### SAM が管理するリソース

- `template.yaml`
- LambdaコードとAPI定義


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/fb9cc4a2-d5dd-455e-9dfb-3bef818d8a6d.png)


---

## 構成図解（Mermaid）

```mermaid
graph TD
  A[Developer]
  B[SAM CLI]
  C[S3 Bucket]
  D[CloudFormation Stack]
  E[Lambda Function]
  F[API Gateway]
  A --> B --> C --> D --> E --> F
```


## 実装ステップ

このセクションでは、TerraformとSAMそれぞれでの構成手順を紹介します。

---

### 🏗 Terraformで管理するリソース構成

以下は、SAMテンプレートをS3に置き、CloudFormation経由でスタックを管理するためのTerraformコード例です。

```hcl
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 イベントを定義した構成です。

```yaml
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`

```bash
sam build
```

#### 2. `sam package`

```bash
sam package \
  --output-template-file packaged.yaml \
  --s3-bucket my-sam-bucket
```

- `--output-template-file`：CloudFormationに渡すテンプレートファイルの出力先  
- `--s3-bucket`：アップロード先のS3バケット名（事前に作成が必要）  

#### 3. `sam deploy`

```bash
sam deploy \
  --template-file packaged.yaml \
  --stack-name my-sam-app \
  --capabilities CAPABILITY_IAM
```

### 💡 補足Tips

```bash
sam deploy --guided
```

この実行により `samconfig.toml` が作成され、次回以降は以下のように短縮して実行できます：

```bash
sam deploy
```

### 📝 よくある注意点

- S3バケットは事前に作成しておく必要があります  
- IAMロールの設定ミスは `ROLLBACK_IN_PROGRESS` を引き起こします  
- `CodeUri` の誤指定やテンプレートの不整合に注意  

## CI/CD連携例（GitHub Actions）

```yaml
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 はアプリケーションロジックの開発・デプロイに適している  
- 責務を分離することで、チーム全体の生産性が向上する  

## 参考リンク

- [Terraform AWS Provider Docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)
- [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)
- [CloudFormation Stack Resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-stack.html)