Fusic Tech Blog

Fusion of Society, IT and Culture

Terraform state mv整理(resourceをmoduleに変えただけなのに何でdestroy!?)
2021/10/26

Terraform state mv整理(resourceをmoduleに変えただけなのに何でdestroy!?)

切っ掛け

Terraformスクリプトをリファクタリングしているとよく出ます。

AWS上のリソース触ってないし、変える積りもないし、
Terraformの書き方を変えただけなのに何でplanやapplyしたらdestroyしようとする??
「No changes.」が正しい気がするけど???

この場合は terraform state mv を使うとdestoryされないリファクタリングが可能です。 😌

問題状況再現

まず、リファクタリングを再現する前に terraform apply でAWS上にリソース(S3)を1つ作ります。

#####################################################
# 最初の terraform apply
#####################################################
resource "aws_s3_bucket" "root" {
  bucket        = "state-mv-a-1"
  acl           = "private"
  force_destroy = true
}

#####################################################
# 二回目の terraform apply(コメントアウト中)
#####################################################
# module s3_module {
#   source   = "./modules"
# }

applyすると名前が state-mv-a-1 であるS3が1つ作られます

この状態でリファクタリングする積りで、module s3_moduleresource "aws_s3_bucket" "root" と同じように作ります。

まず、リファクタリングのために相対パスで ./modules/s3.tf を作ったとします。

#####################################################
# resource "aws_s3_bucket" "root" と同じです
#####################################################
resource "aws_s3_bucket" "s3_module" {
  bucket        = "state-mv-a-1"
  acl           = "private"
  force_destroy = true
}

以下のように resource コメントアウト、 module s3_module をコメントアウト解除してplanしてみます。

#####################################################
# 最初の terraform apply(コメントアウト中)
#####################################################
# resource "aws_s3_bucket" "root" {
#   bucket        = "state-mv-a-1"
#   acl           = "private"
#   force_destroy = true
# }

#####################################################
# 二回目の terraform apply
#####################################################
module s3_module {
  source   = "./modules"
}

destroyとcreateを同時に実行しようとします。もし、S3が実際使用中なら困りますね。😇😇

問題解決

S3などでTerraformのstateを管理している場合はバックアップした後にすることをお勧めします

Terraformはクラウドのリソース(AWSなど)を管理するために状態をファイルにして追跡してます。その状態が state です。

state では resourcemodule を別の状態で管理してます。\ これによって resource で書かれたものを中身を同じくした module に書き換えたら、 state から見ると resourceが消えた、moduleが新しくできた になります。\ Terraformで作業する人はクラウド上のリソースが何も変わってないことを認識してますし、ただTerraformスクリプトの書き方を変えただけです。 この時はTerraformの state を調整したら問題解決されます。

Terraform stateドキュメント : https://www.terraform.io/docs/cli/commands/state/mv.html#usage

上の 問題状況再現 で作った問題を解決するためには terraform state mv aws_s3_bucket.root module.s3_module.aws_s3_bucket.root コマンドを実行すればいいです。 🎉

Choi Jiho

Choi Jiho

Company : Fusic CO., LTD Program Language : PHP, Go, Ruby