Terraform

Terraform の CI/CD: plan/apply の自動化を堅牢に設計する

2026-04-19
NicheeLab編集部

本稿は、Terraform の plan/apply を CI/CD に組み込み、変更の可視化と安全なデプロイを両立するための実務指針をまとめたものです。

変更計画の固定化、状態のロック、承認ゲート、バージョン固定といった試験で問われやすい要点を、現場で使える形に落とし込んで解説します。

前提とゴール

目的は、Terraform の plan 結果を人が確認できる形で固定し、その同一の計画だけを本番に適用するパイプラインを作ることです。これにより、レビュー後にコードや外部状態が変化しても、適用内容がすり替わらないことを保証します。

想定読者は、クラウドの権限分離やリモートバックエンド運用の基本を理解している中〜上級者です。Terraform のバージョン管理、プロバイダのロックファイル、リモートバックエンドでのロックは、以降の内容の基盤となります。

  • Terraform/Provider のバージョンは固定する(.terraform.lock.hcl を VCS にコミット)
  • 状態ファイルはリモート管理し、ロックを有効化する(例: S3 + DynamoDB, azurerm, gcs)
  • CI は plan を生成・保存、CD は承認後にその plan を apply する

パイプライン設計の原則

plan と apply は必ず別フェーズに分離し、apply は保存済み plan ファイルをそのまま適用します。apply フェーズで plan をやり直さない設計が重要です。

CI 実行環境と CD 実行環境で Terraform とプロバイダのバージョンを合わせます。plan ファイルは Terraform/プロバイダのバージョンや OS に依存するため、同一バージョン前提で運用します。

  • 不変性: plan をバイナリ出力(-out)し、その同一ファイルだけを適用する
  • 再現性: Terraform/Provider バージョン固定とロックファイルのコミット
  • 安全性: -input=false、サービスプリンシパルは最小権限、状態はリモート + ロック
  • 可観測性: -detailed-exitcode で変更有無を機械判定、plan をアーティファクト化
  • 承認: 人的レビューの後段に apply を配置、環境ごとに権限・並列性を制御

plan/apply 分離の基本パイプライン

Devcommit / pushCIfmt / init / validate / planPlan Artifactplan.bin (review)CDapply plan (approval後)CI は Remote State (lock) を参照、CD は Manual Approval 後に apply

参照実装: 最小の CI/CD ステージング

以下は、1) 変更の静的検査、2) 初期化、3) 検証、4) 計画の保存、5) 手動承認、6) 計画の適用、の順に進む最小構成の例です。CI/CD 製品に依存しないよう、シェル手順で表します。

バックエンド設定や可変値(機密情報)は CI のシークレットストアや環境変数から注入し、-input=false で対話を禁止します。

  • plan は plan.bin として保存し、ハッシュ化して改ざん検出を行う
  • apply は plan.bin を直接指定(terraform apply plan.bin)し、plan を再生成しない
  • -detailed-exitcode により、差分がなければ apply ステージをスキップ

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 を再実行しない)。

  • ディレクトリ分割: envs/prod, envs/stg などで最も直感的。状態も明確に分割
  • ワークスペース: 同一構成でテナント/環境を切り替える運用に適合
  • 承認ゲート: 人手承認、RBAC、変更理由の記録、plan アーティファクトのハッシュ検証

状態管理・ロック・並行制御

リモートバックエンドは、状態の一元管理とロックを提供します。S3 + DynamoDB ロック、azurerm、gcs など主要バックエンドはロック機構を備えています。-lock はデフォルトで true ですが、CI/CD では明示しておくと意図が伝わります。

並行制御は二重で行います。第一にバックエンドのロック、第二に CI/CD のキューイング(同一環境の apply を逐次化)です。これにより、並走 apply による状態破損を防ぎます。別環境・別状態間の並列は許容しやすくなります。

  • バックエンドは変更しない限り terraform init -migrate-state を不要にする設計にする
  • 他状態の出力参照は data "terraform_remote_state" を用い、明示的に依存関係を表現
  • ロールバックは Git の revert + 新規 plan/apply の手順で扱う(状態の直接編集は避ける)

運用パターン比較と試験対策ポイント

Terraform の自動化は、大別すると DIY な汎用 CI/CD、Terraform Cloud/Enterprise の VCS 連携、API 駆動の実行に分かれます。選定は、状態管理・ポリシー・承認 UX・コストなどで比較します。

試験観点では、plan の固定化と apply の分離、リモート状態とロック、バージョン固定、最小権限、-detailed-exitcode の意味、そしてポリシー適用(Sentinel など)の位置付けが頻出です。

  • plan は人が確認、apply は機械が忠実に実行
  • 同一 plan の適用により「レビューしたもの」と「適用されたもの」を一致させる
  • Sentinel/OPA などのポリシーは plan 段階または適用前ゲートで評価
観点汎用 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 に組み込みたい。レビュー後にコードや外部状態が変化しても、承認された内容と異なる変更が本番に適用されないことを最も強く保証する方法はどれか。

  1. plan を -out でバイナリ保存し、そのファイルを承認後に apply する。apply では plan を再生成しない。
  2. apply 前に常に最新の plan を取り直し、差分がなければ適用する。
  3. plan のテキスト出力を保存し、apply は同じコマンドラインで再実行する。
  4. main ブランチへのマージを保護すれば、plan/apply の分離は不要である。

正解: A

保存済み plan ファイルをそのまま適用することで、レビュー時に承認された計画と適用内容の同一性を最も強く担保できる。apply 直前に plan を再実行すると、コードや外部状態の変化により計画が変わる可能性がある。

よくある質問

plan ファイルはどの環境でも適用できるか?

いいえ。plan は Terraform 本体とプロバイダのバージョン、OS/アーキテクチャに依存します。同一のバージョンセットと同一の構成、同一のリモート状態を前提に適用してください。異なる環境間の汎用配布を前提にすべきではありません。

本番の apply を全自動(無人)にしてよいか?

推奨は人手承認のゲートを挟むことです。手動承認後に自動 apply とするのは一般的ですが、-auto-approve は RBAC や監査ログと併用し、誰が何を承認したかを残してください。

機密変数はどのように渡すべきか?

CI/CD のシークレットストアや Terraform Cloud の機密変数を利用し、-var での平文指定は避けます。TF_VAR_name 環境変数や暗号化された tfvars ファイルを用い、リポジトリに機密を含めない運用にします。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Terraform

Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける

Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...

Terraform

Terraform Authoring & Ops Pro: 上位資格の範囲と対策

上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...

Terraform

Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす

Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...

Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...

Terraform

Terraform Data Source徹底理解:既存リソースの参照で壊さず足す

Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...

Terraformの記事一覧 (102件)
© 2026 NicheeLab All rights reserved.