Terraform CI/CDのブランチ戦略

1. 概要

  • Terraform CI/CDにおけるブランチ戦略の選択肢
  • trunk-based development(トランクベース開発)
  • GitFlowとTerraformの相性
  • 環境ごとのapplyトリガーの設計

Terraformのブランチ戦略は「どのブランチへのpushで、どの環境にapplyするか」を決める設計です。アプリコードと同様の戦略を採用することもありますが、インフラ固有の注意点もあります。


2. 代表的なブランチ戦略

パターン1: trunk-based(推奨)

feature/xxx → main → [apply dev] → tag/v1.0 → [apply stg/prd]
# GitHub Actionsの例
on:
  push:
    branches: [main]     # mainへのpushでdev apply
    tags: ['v*']         # tagでstg/prd apply

jobs:
  apply-dev:
    if: github.ref == 'refs/heads/main'
    # dev環境にapply

  apply-prd:
    if: startsWith(github.ref, 'refs/tags/v')
    # prd環境にapply

パターン2: ブランチ = 環境

feature/xxx → dev → [apply dev]
dev → stg → [apply stg]
stg → main → [apply prd]
on:
  push:
    branches: [dev, stg, main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Set environment
        run: |
          case "${GITHUB_REF#refs/heads/}" in
            dev) echo "ENV=dev" >> $GITHUB_ENV;;
            stg) echo "ENV=stg" >> $GITHUB_ENV;;
            main) echo "ENV=prd" >> $GITHUB_ENV;;
          esac

      - name: Terraform Apply
        env:
          TF_VAR_environment: ${{ env.ENV }}
        run: terraform apply -auto-approve

3. PRベースのplan設計

どのブランチ戦略でも、PRはplan専用にするのがベストプラクティスです。

# Terraform側の基本設定
terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  backend "s3" {
    bucket         = "my-company-tfstate"
    key            = "app/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
    dynamodb_table = "terraform-lock"
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}
# PR = plan のみ
on:
  pull_request:
    branches: [main, dev, stg]

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      # plan → PRコメントに結果を投稿
      - name: Terraform Plan
        run: terraform plan -no-color

4. 環境ごとのapplyタイミング比較

戦略dev applystg applyprd apply推奨度
trunk-basedmainマージ後タグ or 手動タグ or 手動承認★★★
ブランチ=環境devブランチpushstgブランチpushmainブランチpush★★☆
手動のみ手動手動手動★☆☆(小規模向け)

5. 本番環境のapplyに必ず設けるべき安全策

# 本番applyには以下を設ける
jobs:
  apply-prd:
    environment: production    # GitHub Environmentsで承認ゲート
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
      # タグベースでapply
      - name: Terraform Apply
        run: terraform apply -auto-approve -var="environment=prd"

安全策チェックリスト:

  • PRで必ずplanを実行してレビューする
  • 本番applyにはGitHub Environmentsの手動承認ゲートを設ける
  • terraform plan -out=tfplanでplanを保存しそのままapplyに使う(apply前に変更がないことを保証)
  • applyのConcurrencyを1に制限して並列実行を防ぐ

6. 関連記事


7. まとめ

  • trunk-based(mainへのpushでdev、タグでprd)がシンプルで推奨
  • PRはplan専用、applyはmainマージ後またはタグで実行するのが基本設計
  • 本番applyには必ずGitHub Environmentsの手動承認ゲートを設ける
  • plan -out=tfplanでplanを保存してそのままapplyに使うことでapply直前の変更を防ぐ

対象バージョン: Terraform >= 1.9 / GitHub Actions (2024) 公式ドキュメント: https://trunkbaseddevelopment.com/