Terraformのリソースを別のtfstateファイルに移動する

2020年12月8日

Terraform

Terraform でリソースを作成した後に、別の tfstate ファイルに移動する方法を紹介します。長く Terraform を本番環境に適用し続けていると、Terraform のリソースを別の tfstate に分割したり、別れているリソースをひとつにまとめたりしたくなったりします。今回紹介する方法で、リソースを再作成することなく Terraform のリソースを別の tfstete ファイルに移動することができます。リモートで tfstate ファイルを管理している場合や、モジュールをまとめて移動する際にも使えます。

Terraform のバージョンは v0.12.29 です。

目次

  1. 検証用の環境を作る
  2. リソースをローカルの tfstate ファイルへ移動
  3. ローカルで tfstate ファイル間のリソース移動
  4. 移動先の tfstate ファイルを上書き
  5. ソースコードを変更する

検証用の環境を作る

以下のようにディレクトリとファイルを作成します。

tf-state-mv-example
├── from
│   └── main.tf
└── to
    └── main.tf

from/main.tf

resource "null_resource" "foo" {}
resource "null_resource" "bar" {}

to/main.tf

resource "null_resource" "baz" {}

null_resourceは何もしない特殊なリソースです。他の環境に影響を与えることなく、安全にリソースの tfstate 間の移動を試すことができます。詳細は Provisioners Without a Resource - Terraform by HashiCorp を参照。

from ディレクトリに移動し

cd from

リソースを作成します。

terraform init
terraform apply

作成されたリソースを確認します。

terraform state list
null_resource.foo
null_resource.bar

続いて to ディレクトリに移動し

cd ../to

リソースを作成します。

terraform init
terraform apply

作成されたリソースを確認します。

terraform state list
null_resource.baz

それぞれのディレクトリに tfstete ファイルができました。これから from ディレクトリの tfstate にあるリソースを to ディレクトリの tfstate に移動します。今回はローカルに tfstete がありますが、リモートで tfstate ファイルを管理している場合にも同じ方法が使えます。

tf-state-mv-example
├── from
│   ├── main.tf
│   └── terraform.tfstate
└── to
    ├── main.tf
    └── terraform.tfstate

準備はここまでです。この後、リソースの移動を行います。

リソースをローカルの tfstate ファイルへ移動

from ディレクトリに移動し

cd ../from

移動するリソースを確認します。

terraform state list
null_resource.foo
null_resource.bar

リソースは 2 個あります。このうち null_resource.foo リソースを to ディレクトリの tfstate に移動させます。

terraform state mv コマンドを実行し、null_resource.foo リソースをローカルの from.tfstate ファイルに移動します。コマンドの詳細は Command: state mv - Terraform by HashiCorp を参照。

terraform state mv -state-out=from.tfstate \
    null_resource.foo null_resource.foo
Move "null_resource.foo" to "null_resource.foo"
Successfully moved 1 object(s).

from ディレクトリ内に from.tfstate ファイルができ、リソースが移動します。

tf-state-mv-example
├── from
│   ├── main.tf
│   ├── terraform.tfstate
│   └── from.tfstate

terraform state list コマンドで、元の tfstate ファイルからリソースが削除されていることを確認します。

terraform state list
null_resource.bar

ローカルで tfstate ファイル間のリソース移動

次に to ディレクトリに移動します。

cd ../to

terraform state pull コマンドを実行し、移動先である to ディレクトリの tfstate ファイルをローカルにコピーします。コマンドの詳細は Command: state pull - Terraform by HashiCorp を参照。

terraform state pull > to.tfstate

to ディレクトリ内に to.tfstate ができます。

tf-state-mv-example
├── to
│   ├── main.tf
│   ├── terraform.tfstate
│   └── to.tfstate

terraform state mv コマンドで from.tfstate のリソースを to.tfstate に移動します。

terraform state mv -state=../from/from.tfstate \
    -state-out=to.tfstate \
    null_resource.foo null_resource.foo

実行結果。to.tfstate ファイルにリソースが移動しました。

Move "null_resource.foo" to "null_resource.foo"
Successfully moved 1 object(s).

移動先の tfstate ファイルを上書き

移動先の tfstate を to.tfstate で上書きします。terraform state list コマンドで上書きする前の状態を確認しておきます。最初の状態から変化していません。

terraform state list
null_resource.baz

terraform state push コマンドで tfstate を上書きします。コマンドの詳細は Command: state push - Terraform by HashiCorp を参照。

terraform state push to.tfstate

再度 terraform state list コマンドを実行してリソースが移動したことを確認をします。

terraform state list
null_resource.baz
null_resource.foo

ソースコードを変更する

リソースの移動に合わせ、ソースコードも変更します。

from/main.tf

resource "null_resource" "bar" {}

to/main.tf

resource "null_resource" "foo" {}
resource "null_resource" "baz" {}

移動元と移動先で terraform plan の差分がなければ完了です。

terraform plan
No changes. Infrastructure is up-to-date.

-技術ブログ
-