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 apply | stg apply | prd apply | 推奨度 |
|---|---|---|---|---|
| trunk-based | mainマージ後 | タグ or 手動 | タグ or 手動承認 | ★★★ |
| ブランチ=環境 | devブランチpush | stgブランチpush | mainブランチ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. 関連記事
- GitHub ActionsでTerraformを実行する方法 — 実装例
- GitHub Actions: 複数AWSアカウントへのデプロイ — マルチアカウント
- Terragrunt vs Terraform Workspaces — DRY化の2択 — 環境管理
- モノレポ vs マルチリポ — リポジトリ設計 — リポジトリ構成
- GitHub Actions: PR時にterraform planをコメントで返す — PRコメント
- Terraform Cloud vs GitHub Actions — プラットフォーム比較
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/