本稿は、Terraform の plan/apply を CI/CD に組み込み、変更の可視化と安全なデプロイを両立するための実務指針をまとめたものです。
変更計画の固定化、状態のロック、承認ゲート、バージョン固定といった試験で問われやすい要点を、現場で使える形に落とし込んで解説します。
目的は、Terraform の plan 結果を人が確認できる形で固定し、その同一の計画だけを本番に適用するパイプラインを作ることです。これにより、レビュー後にコードや外部状態が変化しても、適用内容がすり替わらないことを保証します。
想定読者は、クラウドの権限分離やリモートバックエンド運用の基本を理解している中〜上級者です。Terraform のバージョン管理、プロバイダのロックファイル、リモートバックエンドでのロックは、以降の内容の基盤となります。
plan と apply は必ず別フェーズに分離し、apply は保存済み plan ファイルをそのまま適用します。apply フェーズで plan をやり直さない設計が重要です。
CI 実行環境と CD 実行環境で Terraform とプロバイダのバージョンを合わせます。plan ファイルは Terraform/プロバイダのバージョンや OS に依存するため、同一バージョン前提で運用します。
plan/apply 分離の基本パイプライン
以下は、1) 変更の静的検査、2) 初期化、3) 検証、4) 計画の保存、5) 手動承認、6) 計画の適用、の順に進む最小構成の例です。CI/CD 製品に依存しないよう、シェル手順で表します。
バックエンド設定や可変値(機密情報)は CI のシークレットストアや環境変数から注入し、-input=false で対話を禁止します。
CI/CD 参照スクリプト(疑似例)
# CI: 計画の生成
set -euo pipefail
# 1) フォーマットと静的検査
terraform fmt -check -recursive
terraform init \
-input=false
# 2) バリデーション
terraform validate -no-color
# 3) ワークスペース/環境の選択
# export TF_WORKSPACE=staging
# terraform workspace select "$TF_WORKSPACE" || terraform workspace new "$TF_WORKSPACE"
# 4) 変更計画の作成(詳細終了コードで差分検出)
set +e
terraform plan \
-out=plan.bin \
-lock=true \
-input=false \
-no-color \
-detailed-exitcode
rc=$?
set -e
if [ "$rc" -eq 0 ]; then
echo "差分なし。apply は不要"; exit 0
elif [ "$rc" -eq 2 ]; then
echo "差分あり。plan.bin を保存して承認待ちへ";
sha256sum plan.bin > plan.bin.sha256
# ここで CI のアーティファクトに plan.bin とハッシュを保存
else
echo "plan 失敗"; exit $rc
fi
# --- 手動承認ゲート(人のレビュー)---
# CD: plan の適用(同一バージョンの Terraform/Provider 前提)
sha256sum -c plan.bin.sha256
terraform init -input=false
terraform apply -input=false -auto-approve plan.bin環境の分離は、ディレクトリ分割(env ディレクトリ単位で状態分離)、ワークスペース(1 つの構成で複数状態)、もしくはリポジトリ分割のいずれかで行います。いずれの場合も状態は物理的に分かれ、apply の並列実行が干渉しないようロックが働く設計が必要です。
レビューと承認は plan の可視化を中心に据えます。レビュー対象は HCL の差分だけでなく、plan のリソース追加・変更・削除の要約です。承認後の apply は、承認時に生成された plan.bin を適用します(apply の直前に plan を再実行しない)。
リモートバックエンドは、状態の一元管理とロックを提供します。S3 + DynamoDB ロック、azurerm、gcs など主要バックエンドはロック機構を備えています。-lock はデフォルトで true ですが、CI/CD では明示しておくと意図が伝わります。
並行制御は二重で行います。第一にバックエンドのロック、第二に CI/CD のキューイング(同一環境の apply を逐次化)です。これにより、並走 apply による状態破損を防ぎます。別環境・別状態間の並列は許容しやすくなります。
Terraform の自動化は、大別すると DIY な汎用 CI/CD、Terraform Cloud/Enterprise の VCS 連携、API 駆動の実行に分かれます。選定は、状態管理・ポリシー・承認 UX・コストなどで比較します。
試験観点では、plan の固定化と apply の分離、リモート状態とロック、バージョン固定、最小権限、-detailed-exitcode の意味、そしてポリシー適用(Sentinel など)の位置付けが頻出です。
| 観点 | 汎用 CI/CD(DIY) | Terraform Cloud: VCS 連携実行 | Terraform Cloud: API/CLI 駆動 |
|---|---|---|---|
| 状態管理/ロック | S3+DynamoDB / azurerm / gcs 等を自前構成 | TFC が管理(ロック内蔵) | TFC が管理(ロック内蔵) |
| plan の保存/承認 | CI のアーティファクト保存 + 手動承認 | UI 上で plan 確認と承認(ポリシーチェック連携可) | API 経由で plan 取得・承認フローを外部化 |
| ポリシー | OPA/conftest 等を組込(別途運用) | Sentinel(エディションに依存) | Sentinel(エディションに依存) |
| 実行環境の整備 | Terraform/Provider のバージョン固定を自前で維持 | TFC がバージョン管理(ワークスペース設定) | TFC がバージョン管理(ワークスペース設定) |
| 権限とシークレット | OIDC/短期資格情報でクラウドに接続(CI 側で管理) | ワークスペース変数で安全に管理 | ワークスペース変数で安全に管理 |
| 学習/運用コスト | 柔軟だが初期構築と保守の負担大 | UI とガードレールで運用容易 | 柔軟な統合だが API 設計が必要 |
Pro
問題 1
チームは Terraform の変更を CI/CD に組み込みたい。レビュー後にコードや外部状態が変化しても、承認された内容と異なる変更が本番に適用されないことを最も強く保証する方法はどれか。
正解: A
保存済み plan ファイルをそのまま適用することで、レビュー時に承認された計画と適用内容の同一性を最も強く担保できる。apply 直前に plan を再実行すると、コードや外部状態の変化により計画が変わる可能性がある。
plan ファイルはどの環境でも適用できるか?
いいえ。plan は Terraform 本体とプロバイダのバージョン、OS/アーキテクチャに依存します。同一のバージョンセットと同一の構成、同一のリモート状態を前提に適用してください。異なる環境間の汎用配布を前提にすべきではありません。
本番の apply を全自動(無人)にしてよいか?
推奨は人手承認のゲートを挟むことです。手動承認後に自動 apply とするのは一般的ですが、-auto-approve は RBAC や監査ログと併用し、誰が何を承認したかを残してください。
機密変数はどのように渡すべきか?
CI/CD のシークレットストアや Terraform Cloud の機密変数を利用し、-var での平文指定は避けます。TF_VAR_name 環境変数や暗号化された tfvars ファイルを用い、リポジトリに機密を含めない運用にします。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...