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

2020年12月8日

Terraform

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

目次

  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.

-技術ブログ
-