📛

Terraformで既存のリソース名を変更する

2023/06/18に公開

はじめに

terraformで既存リソースの名前を変更したく、方法を調べたのでメモします。
tfstateファイルはs3にある前提で検証を進めます。

参考

こちらの記事を参考にさせていただきました。
main.tfの書き換えでリソース名を変更するとどのようになるか、わかりやすく書かれています。
https://zenn.dev/machamp/articles/modify-terraform-resource-name

環境

terraform 1.4.6

方針

tfstateに記載されているリソース名を変更することで実現したいと思います。
公式ドキュメントのこちらにサンプルの記載があります。
https://developer.hashicorp.com/terraform/cli/commands/state/mv#example-rename-a-resource

事前準備

こちらをapplyします。
バックエンドはs3です。

検証用main.tf
main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.65.0"
    }
  }
  backend "s3" {
    bucket = "<s3バケット>"
    key    = "<tfstateパス>"
    region = "ap-northeast-1"
  }
}

provider "aws" {
  region = "ap-northeast-1"
  default_tags {
    tags = {
      env       = "test"
      provision = "terraform"
    }
  }
}

resource "aws_s3_bucket" "s3" {
}

検証

リネーム

リソース名を変更します。

main.tf
- resource "aws_s3_bucket" "s3" {
+ resource "aws_s3_bucket" "s3-renamed" { 
}

s3のtfstateを持ってくる

s3にあるtfstateファイルをローカルへ持ってきます。
terraform state pullは標準出力に出力するため、ローカルファイルへリダイレクトしましょう。

$ terraform state pull > terraform.tfstate

この後のmvでtfstateが必要であるため、このように持ってくる必要があります。
エラーの様子

$ terraform state mv -state=terraform.tfstate aws_s3_bucket.s3 aws_s3_bucket.s3-renamed
No state file was found!

State management commands require a state file. Run this command
in a directory where Terraform has been run or use the -state flag
to point the command to a specific state location.

state mvする

tfstateにリソース名が記録されているから、それを書き換えてリソース名を変更しよう!
のイメージです

$ terraform state mv -state=terraform.tfstate aws_s3_bucket.s3 aws_s3_bucket.s3-renamed
Move "aws_s3_bucket.s3" to "aws_s3_bucket.s3-renamed"
Successfully moved 1 object(s).

diffする

terraform state mvを使用するとバックアップファイルが出力されます。

$ ls -1
main.tf
terraform.tfstate # 更新されたtfstate
terraform.tfstate.1687059891.backup # これ

あたらしく更新されたterraform.tfstateと比較してみましょう

$ diff terraform.tfstate terraform.tfstate.1687059891.backup 
4c4
<   "serial": 2,
---
>   "serial": 1,
11c11
<       "name": "s3-renamed",
---
>       "name": "s3",

terraform.tfstateが更新されているようです。
serialとnameが変わっているためOKそうですね。

s3のtfstateを持っていく

さきほどの逆です。
このコマンドを実行するとリネーム後の新しいstateを使用します。

$ terraform state push terraform.tfstate

動作確認

planしても変更がでないこと

$ terraform plan
aws_s3_bucket.s3-renamed: Refreshing state... [id=terraform-xxxxxxxxxxxxxxxxxxxxxxxxxxx]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

リソース名を確認して変更後の値になること

$ terraform state list
aws_s3_bucket.s3-renamed

が確認できました!

注意

公式ドキュメントは直接編集を推奨していません。
やむをえない場合を除き、今回のようにドキュメントに従うのがよいと思います。
https://developer.hashicorp.com/terraform/language/state#inspection-and-modification

Discussion