Terraform の状態(state)は IaC 運用の中核です。ふだんは apply/plan とバックエンドが安全に扱いますが、障害対応や監査では低レベルの直接操作が必要になることがあります。本稿では terraform state pull/push を中心に、破壊的変更を避けるための手順と注意点を整理します。
HashiCorp 公式の基本仕様に沿い、バージョン依存となりやすい挙動には注意書きを添えています。試験対策(プロ/上級)の観点から、コマンド間の使い分けやロック、バックエンド差異も押さえます。
terraform state pull は現在の状態をバックエンドから取得して標準出力に JSON で出します。状態は読み取りのみで、インフラやバックエンドを変更しません。対して terraform state push はローカルの tfstate ファイルをバックエンドへ書き戻します。バックエンドやロックの制約に強く依存し、誤用は破壊的な差分や競合を招きます。
state は serial(世代番号)と lineage(系統 ID)を持ち、正しい後続世代のみが受理されます。push は通常 serial 不一致で拒否されますが、-force により強制上書きも可能です。強制上書きは最後の手段であり、同時実行の停止・ロック取得・直前バックアップ取得・直後の plan 検証が必須です。
| コマンド/操作 | 主目的 | 典型ユースケース | 変更の有無 |
|---|---|---|---|
| terraform state pull | 状態の取得(監査/バックアップ) | バックアップ取得、JSON 検査、監査 | なし(読み取りのみ) |
| terraform state push | 状態の復旧/置換 | 障害復旧、誤削除後のロールバック(最終手段) | あり(状態の書換) |
| terraform state mv/rm | 状態エントリの移動/除去 | モジュール再編、誤 import の修正 | あり(状態編集) |
| terraform import | 既存実リソースの取り込み | 手動作成リソースの IaC 化 | あり(状態追加) |
| apply -refresh-only | 状態の実環境反映 | ドリフト是正(状態のみ更新) | あり(状態更新) |
pull/push のデータフローとロック(概念図)
状態メタ情報の確認と比較
# 現在の状態を取得し、メタ情報を確認
terraform state pull > current.tfstate
jq '{serial, lineage, resources: (.resources|length)}' current.tfstate
# 直近バックアップとの差分を軽量比較(計数/メタ)
jq '{serial, lineage}' current.tfstate backup-20240115.tfstate
diff <(jq -S '.resources[].type+"."+.resources[].name? // empty' current.tfstate | sort) \
<(jq -S '.resources[].type+"."+.resources[].name? // empty' backup-20240115.tfstate | sort)pull は調査・監査・バックアップの起点として有用です。実行中の plan/apply がなければ基本的に安全です。取得した JSON は機密を含む可能性があるため、出力先とアクセス権に注意してください。
管理型バックエンドでは組織/ワークスペース権限により取得が制限される場合があります。実行前に認証状態(terraform login 等)と権限を確認し、長期保存は暗号化ストレージに限定します。
| チェック項目 | 推奨 | 補足 |
|---|---|---|
| 同時実行の有無 | 無しを確認 | CI/CD 停止や手動ロックで担保 |
| 出力先 | 暗号化ストレージ | SSE 有効なバケットや KMS 暗号化ディスク |
| 検査方法 | jq などで要約 | serial/lineage/リソース件数から異常を早期発見 |
pull の実例と要約
# バックアップ取得(タイムスタンプ付)
ts=$(date +%Y%m%d-%H%M%S)
terraform state pull > backup-$ts.tfstate
# メタの健全性確認
jq '{serial, lineage, resCount: (.resources|length)}' backup-$ts.tfstate
# 秘匿情報がないか単純スキャン(過信は禁物)
egrep -in '(password|secret|token|apikey)' backup-$ts.tfstate || truepush は状態の置換です。誤用は大規模な差分や破壊的変更を誘発します。通常運用では使わず、障害復旧や誤操作のロールバック等の最終手段として限定してください。サポートの有無・ロックの前提はバックエンドに依存します。
安全な復旧は「同時実行停止 → 事前バックアップ → 検証 → ロック取得(可能なら) → push → 直後に plan で二重検証」の順で行います。serial 不一致で拒否された場合、理由を調査しない強制上書きは避けます。
| ステップ | 目的 | 失敗時の対応 |
|---|---|---|
| 停止/告知 | 競合防止 | 再開禁止のまま原因分析 |
| バックアップ | ロールバック保険 | 別保管へ多重保存 |
| 比較/検証 | 復旧候補の妥当性確認 | serial/lineage/件数差の根因究明 |
| ロック取得 | 書込の排他 | 取得不可なら時間帯変更や運用停止強化 |
| push/検証 | 反映と差分検証 | 即時リカバリか切戻し判断 |
push の手順(例: S3 バックエンド)
# 1) 現行を退避
terraform state pull > before-$ts.tfstate
# 2) 復旧候補(backup-20240115.tfstate)のメタ確認
jq '{serial, lineage}' backup-20240115.tfstate
# 3) 可能ならロックが取れる時間帯に実施(S3+DynamoDB のテーブルでロック監視)
# 4) push を試行(まずは -force なし)
terraform state push backup-20240115.tfstate
# serial 不一致などで拒否された理由を調査。どうしても必要な場合のみ、業務停止下で強制上書き
# terraform state push -force backup-20240115.tfstate
# 5) 直後に差分確認
terraform plan -refresh=false # まずは状態とコードの整合のみを確認
terraform plan # 続けて実環境も含めた差分を確認バックエンドはロック方式や API 制約が異なります。push/pull の可否と前提は各ドキュメントを確認してください。特に管理型バックエンドではサーバ側で世代と権限を厳密管理しており、push が未サポート/制限される場合があります。
バックエンド移行は terraform init -migrate-state を優先し、push での手動移送は避けます。HTTP バックエンドはサーバ実装が機能可否を決めるため、仕様整備がない環境では push は使わないのが無難です。
| バックエンド | ロック方式(例) | push/pull 留意点(一般論) |
|---|---|---|
| S3(+DynamoDB) | DynamoDB アイテム | pull は一般的に可。push は要停止・要ロック・失敗時原因調査 |
| GCS | 条件付き書込 | pull は可。push は並行書込防止を担保して実行 |
| Azure Blob | Blob Lease | pull は可。push はリース下で実施 |
| HTTP | サーバ実装依存 | サーバが対応しない場合は不可 |
| Terraform Cloud/Enterprise | サービス管理 | 権限/機能制限あり。公式の API/UI を確認 |
代表的な backend 設定例(HCL 抜粋)
# S3 バックエンド(例)
terraform {
backend "s3" {
bucket = "tfstate-prod"
key = "network/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "tfstate-lock"
encrypt = true
}
}
# GCS バックエンド(例)
terraform {
backend "gcs" {
bucket = "tfstate-prod-gcs"
prefix = "network"
}
}state はリソース属性を広範に含み、プロバイダが sensitive 属性で隠さない限り平文で格納されます。たとえバックエンドが暗号化していても、pull で出力したローカルファイルは平文 JSON です。アクセス制御と保管のガバナンスを設けてください。
監査は必要最小限のメタと件数要約から始め、全文配布は避けます。長期保存は鍵管理(KMS など)と監査証跡を備えたストレージに限定し、共有チャネル(メール/チャット)への貼付は厳禁です。
| 対象 | 推奨コントロール | 備考 |
|---|---|---|
| バックエンド | 暗号化・バージョニング・ロック | 監査ログとアラート連携 |
| ローカル出力 | 暗号化ディスク・権限最小化 | 自動削除ポリシー |
| 配布 | 要約のみ・共有禁止 | 承認制ワークフロー |
監査用の安全な要約サンプル
# リソース件数と types の一覧を抽出
jq '{serial, lineage, count: (.resources|length), types: ([.resources[].type] | unique)}' backup.tfstate
# 明示的な機微候補属性をサーチ
jq '.. | objects | to_entries[] | select(.key|test("(?i)(password|secret|token|apikey)"))' backup.tfstate出題は「どのコマンドが適切か」「安全に実施する順序は何か」が中心です。pull/push は低レベル操作であり、通常は mv/rm/import や init -migrate-state、apply -refresh-only で目的を達します。push は災害復旧の最終手段である点を強調して覚えます。
また、状態と実リソースの関係を正しく言語化できることが重要です。state を書き換えても実リソースは変わりません。逆に import してもコードがないと管理できません。用語の混同を避けましょう。
| 目的 | 正解になりやすい操作 | 誤答パターン |
|---|---|---|
| バックエンド移行 | init -migrate-state | state push で手動移送 |
| ドリフト調査 | pull + plan | push での上書き修正 |
| モジュール再編 | state mv | import や手動再作成 |
よくある選択肢の見分け方(例)
# 既存 VPC を IaC 管理下に
# 誤: state push で VPC の状態を置換
# 正: terraform import aws_vpc.main vpc-xxxx && plan
# provider の命名変更
# 正: terraform state replace-provider 'hashicorp/aws' 'hashicorp/aws' # アドレス修正の例Pro
問題 1
S3 バックエンド(ロックに DynamoDB を使用)で運用中。誤操作で state を古いバックアップに戻す必要がある。最も安全な手順はどれか。
正解: A
書込み前の停止・退避・検証・ロック・push・直後の plan 検証が安全手順です。S3 に直接上書きは世代検証やロックを迂回し危険。refresh の乱用や -force 前提も不適切。backend 切替での手編集は整合性を崩す恐れがあり、移行は init -migrate-state を用います。
terraform state pull はロックを取得しますか?
一般に pull は読み取りであり書込みロックは取りません。ただし実行中の run があると不整合なスナップショットを得る可能性があるため、計画/適用の実行とは重ねない運用を推奨します。
terraform state push はすべてのバックエンドで使えますか?
いいえ。バックエンドの実装に依存します。管理型バックエンドなどでは未サポート/制限される場合があります。利用可否と前提条件は各バックエンドの公式ドキュメントで確認してください。
push 後に最初に確認すべきことは?
直後に terraform plan を実行し、想定外の destroy/add がないかを確認します。まず -refresh=false でコードと状態の整合を見てから、通常の plan で実環境との差分も確認すると安全です。
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を用いた既存リソース参照の基本、選択基準、評価順序、...