0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Terraformのtfstateファイルを直接編集してみた

0
Last updated at Posted at 2026-04-03

はじめに

tfstateの直接編集を実際にやったことがないため、EC2を1台だけデプロイした簡単な環境で試してみることにしました。

検証用の環境を作る

まず、検証用のTerraformコードを用意します。
EC2を1台デプロイするだけのシンプルな構成で、stateはローカルに保存します。

# main.tf
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

resource "aws_instance" "test" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.small"

  tags = {
    Name = "tfstate-edit-test"
  }
}

terraform initterraform apply を実行して、EC2を作成します。

terraform init
terraform apply

tfstateの中身を覗いてみる

apply が完了すると、カレントディレクトリに terraform.tfstate が生成されます。
中身はJSON形式で、大まかにこんな構造になっています。

{
  "version": 4,
  "terraform_version": "1.13.1",
  "serial": 1,
  "lineage": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "outputs": {},
  "resources": [...]
}

各フィールドの役割はこちらです。

フィールド 役割
version tfstateのフォーマットバージョン。現行は 4 固定
terraform_version このstateを最後に更新したTerraformのバージョン
serial stateが更新されるたびに+1される通番。競合検知に使われる
lineage stateファイルの一意なID。別のstateを誤って上書きしないためのもの
outputs output ブロックで定義した値の格納先。未定義なら空
resources 管理しているリソースの一覧。ここに各リソースの属性値が入る

resources の中にある aws_instance.test を見ると、attributes にインスタンスタイプなどの値が記録されています。

{
  "mode": "managed",
  "type": "aws_instance",
  "name": "test",
  "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
  "instances": [
    {
      "attributes": {
        "ami": "ami-0292622b22bd52948",
        "instance_type": "t3.small",
        "id": "i-XXXXXXXXXXXXXXXXXXXX",
        "tags": {
          "Name": "tfstate-edit-test"
        },
        ...
      },
      "dependencies": [
        "data.aws_ami.amazon_linux_2023"
      ]
    }
  ]
}

terraform planattributes の値と .tf ファイルの定義を比較して差分を出します。
ただし、単純に比較しているわけではなく、事前にrefreshという処理が挟まります。

terraform planのrefresh動作を知っておく

tfstateを直接編集する前に、terraform plan の動作を理解しておく必要があります。

refreshとは: AWSなどのプロバイダに問い合わせて、実際のリソースの現在の状態を取得する処理です。tfstateに記録された値と実際のインフラの間にズレがないかを確認するために行われます。

terraform plan は実行時に以下の順序で動きます。

  1. AWSの実際の状態を読み取る(refresh)
  2. 読み取った値でstateをメモリ上で更新する
  3. その更新後のstateと**.tf ファイルを比較**して差分を出す

ここで注意したいのが、planapply でrefresh結果の扱いが異なる点です。

  • terraform plan: refresh結果はメモリ上に保持される。tfstateファイルは更新されない
  • terraform apply: refresh結果がtfstateファイルにも書き込まれる

つまり、tfstateの instance_type を手で書き換えても、planの最初のステップでAWSから実際の値を取得してメモリ上で上書きしてしまいます。

例えば、tfstateだけ t3.micro に書き換えて terraform plan を実行しても、AWSの実インスタンスが t3.small のままなら、refreshで t3.small に戻されて差分は出ません。
ただし、これはメモリ上の話なので、tfstateファイル自体は t3.micro のまま残ります。

この動作をスキップするオプションが -refresh=false です。

terraform plan -refresh=false

これならAWSへの問い合わせをせず、tfstateファイル上の値と .tf を直接比較します。
以降の検証ではこのオプションも活用していきます。

図解すると下記のような形。
またrefreshで上書きされない属性もあるため、必ず実リソースの全ての情報がメモリ上のstateに反映されるわけではないです。

image.png

やってみる: tfstateを直接編集して差分を消す

AWSコンソールから手動でインスタンスタイプを t3.small から t3.micro に変更してしまった、という状況を想定します。.tf ファイルも t3.micro に修正済みです。

# main.tf の該当箇所を修正
instance_type = "t3.micro"

この状態で terraform plan を実行すると、refreshによってAWSから実際の値(t3.micro)が取得されます。refreshed後のstateと .tf はどちらも t3.micro なので、適用すべき変更(planned changes)はありません。

image.png

一見すると差分がないように見えますが、tfstateファイルの中身は t3.small のまま更新されていません(plan はファイルを書き換えないため)。

image.png

-refresh=false をつけてrefreshをスキップすると、tfstateファイルの値がそのまま使われるので差分が見えます。

terraform plan -refresh=false

スクリーンショット 2026-04-03 105820.png

普通なら terraform apply すれば解決しますが、今回はあえてtfstateの直接編集で差分を消してみます。

手順

1. バックアップを取る

cp terraform.tfstate terraform.tfstate.backup

2. tfstateの instance_type を書き換える

terraform.tfstate をエディタで開き、instance_type の値を t3.micro に変更します。

"instance_type": "t3.micro",

3. serial を+1する

"serial": 2,

serial を更新しないと、リモートバックエンド(S3など)を使っている場合に書き込みが拒否される可能性があります。ローカルstateでも念のため上げておきます。
※追記)ローカルではserialは更新しなくてもエラーがでませんでした。

4. terraform plan -refresh=false で確認

terraform plan -refresh=false

image.png

差分が消えました。JSONの構文を壊していたり値が間違っていれば、この時点でエラーや差分として検出されるので、失敗してもすぐ気づけます。もしうまくいかなければ、バックアップから terraform.tfstate を復元すれば大丈夫です。

まとめ

tfstateの直接編集、やってみると意外とシンプルでした。
JSONの該当箇所を書き換えて serial を上げるだけです。
壊しても terraform plan ですぐ気づけますし、バックアップがあれば復元もできます。

ただし、普段の運用では terraform state rm + terraform import ほうが当たり前ですが安全で確実です。
直接編集は「仕組みを理解するため」や「他の手段だとリスクが高いケース」に限定するのがよさそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?