Terraform

terraform state pull/push 徹底理解: 低レベルでの状態操作

2026-04-19
NicheeLab編集部

Terraform の状態(state)は IaC 運用の中核です。ふだんは apply/plan とバックエンドが安全に扱いますが、障害対応や監査では低レベルの直接操作が必要になることがあります。本稿では terraform state pull/push を中心に、破壊的変更を避けるための手順と注意点を整理します。

HashiCorp 公式の基本仕様に沿い、バージョン依存となりやすい挙動には注意書きを添えています。試験対策(プロ/上級)の観点から、コマンド間の使い分けやロック、バックエンド差異も押さえます。

pull/push の成り立ちと前提知識

terraform state pull は現在の状態をバックエンドから取得して標準出力に JSON で出します。状態は読み取りのみで、インフラやバックエンドを変更しません。対して terraform state push はローカルの tfstate ファイルをバックエンドへ書き戻します。バックエンドやロックの制約に強く依存し、誤用は破壊的な差分や競合を招きます。

state は serial(世代番号)と lineage(系統 ID)を持ち、正しい後続世代のみが受理されます。push は通常 serial 不一致で拒否されますが、-force により強制上書きも可能です。強制上書きは最後の手段であり、同時実行の停止・ロック取得・直前バックアップ取得・直後の plan 検証が必須です。

  • pull は安全な読み取り。通常ロックを奪わないが、実行中の apply と併走させない
  • push は書き込み操作。バックエンドにより未対応/制限あり。実行中の他ジョブを必ず停止
  • 状態は secrets を含み得る。取り扱い・保管・転送は厳重に
  • バックエンドのロック機構(S3+DynamoDB、Azure Blob Lease、GCS preconditions など)を理解する
コマンド/操作主目的典型ユースケース変更の有無
terraform state pull状態の取得(監査/バックアップ)バックアップ取得、JSON 検査、監査なし(読み取りのみ)
terraform state push状態の復旧/置換障害復旧、誤削除後のロールバック(最終手段)あり(状態の書換)
terraform state mv/rm状態エントリの移動/除去モジュール再編、誤 import の修正あり(状態編集)
terraform import既存実リソースの取り込み手動作成リソースの IaC 化あり(状態追加)
apply -refresh-only状態の実環境反映ドリフト是正(状態のみ更新)あり(状態更新)

pull/push のデータフローとロック(概念図)

(read) pull / (write) pushlock (write)Terraform CLIpull / push / mvBackendS3/GCS/Azure/HTTP/TFCState serial/lineage 検証

状態メタ情報の確認と比較

# 現在の状態を取得し、メタ情報を確認
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)

terraform state pull の安全な使い方

pull は調査・監査・バックアップの起点として有用です。実行中の plan/apply がなければ基本的に安全です。取得した JSON は機密を含む可能性があるため、出力先とアクセス権に注意してください。

管理型バックエンドでは組織/ワークスペース権限により取得が制限される場合があります。実行前に認証状態(terraform login 等)と権限を確認し、長期保存は暗号化ストレージに限定します。

  • 実行中の Terraform ジョブがないことを確認
  • 取得前にバックアップの命名規則と保存先を決める
  • JSON を jq で要約してレビュー(全体を広範に配布しない)
  • 必要に応じて -no-color など出力整形と併用(標準出力を安全に扱う)
チェック項目推奨補足
同時実行の有無無しを確認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 || true

terraform state push のリスクと安全な復旧手順

push は状態の置換です。誤用は大規模な差分や破壊的変更を誘発します。通常運用では使わず、障害復旧や誤操作のロールバック等の最終手段として限定してください。サポートの有無・ロックの前提はバックエンドに依存します。

安全な復旧は「同時実行停止 → 事前バックアップ → 検証 → ロック取得(可能なら) → push → 直後に plan で二重検証」の順で行います。serial 不一致で拒否された場合、理由を調査しない強制上書きは避けます。

  • CI/CD と手動実行を全停止し、ロックと変更凍結を宣言
  • 現行 state の pull と、復旧候補の tfstate を比較
  • バックエンドのロック/世代管理の動作を再確認
  • push 後は terraform plan を行い、想定外の destroy/add がないか確認
ステップ目的失敗時の対応
停止/告知競合防止再開禁止のまま原因分析
バックアップロールバック保険別保管へ多重保存
比較/検証復旧候補の妥当性確認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 は使わないのが無難です。

  • S3: DynamoDB ロック推奨。SSE-KMS 等で暗号化。バージョニング有効化で復旧容易化
  • GCS: 世代管理(Object Versioning)と条件付き書込で同時実行を防止
  • AzureRM: Blob のリースでロック。SSE/ACL を適切に設定
  • HTTP: サーバ実装次第。push/lock 未対応のことがある
  • Terraform Cloud/Enterprise: サービス管理の state。CLI の一部サブコマンドは制限される場合がある。公式手順を参照
バックエンドロック方式(例)push/pull 留意点(一般論)
S3(+DynamoDB)DynamoDB アイテムpull は一般的に可。push は要停止・要ロック・失敗時原因調査
GCS条件付き書込pull は可。push は並行書込防止を担保して実行
Azure BlobBlob Leasepull は可。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 など)と監査証跡を備えたストレージに限定し、共有チャネル(メール/チャット)への貼付は厳禁です。

  • バックエンドは必ず暗号化(SSE, CMEK)とバージョニングを有効化
  • pull の出力は期限付保管とアクセス最小化
  • jq で要約し、機微情報の拡散を抑制
  • 不要になったバックアップの安全消去(シュレッド/安全削除)
対象推奨コントロール備考
バックエンド暗号化・バージョニング・ロック監査ログとアラート連携
ローカル出力暗号化ディスク・権限最小化自動削除ポリシー
配布要約のみ・共有禁止承認制ワークフロー

監査用の安全な要約サンプル

# リソース件数と 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 してもコードがないと管理できません。用語の混同を避けましょう。

  • backend 移行は terraform init -migrate-state を選ぶ
  • ドリフトの是正は apply -refresh-only を優先(従来の refresh は非推奨版で注意)
  • リソースの移設は terraform state mv、除外は terraform state rm
  • pull は読み取り、push は置換。push はロックと停止の下でのみ
目的正解になりやすい操作誤答パターン
バックエンド移行init -migrate-statestate push で手動移送
ドリフト調査pull + planpush での上書き修正
モジュール再編state mvimport や手動再作成

よくある選択肢の見分け方(例)

# 既存 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 を古いバックアップに戻す必要がある。最も安全な手順はどれか。

  1. 全ジョブ停止とロックを確認し、現行 state を pull して退避後、復旧候補を検証してから terraform state push を行い、直後に plan で差分を確認する
  2. S3 バケットに直接バックアップファイルを上書きアップロードし、CI/CD を流して差分を自動修正する
  3. terraform refresh を実行してから復旧候補を push する。refresh が失敗したら -force で上書きする
  4. バックエンドを一時的に local に変更し、ローカルで編集後に元の S3 に戻す

正解: 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 で実環境との差分も確認すると安全です。

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

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の記事一覧 (101件)
© 2026 NicheeLab All rights reserved.