mito’s blog

IT技術メインの雑記。思い立ったが吉日。

[Terraform] 再作成や変更が起きない、動的属性をもつパラメータがある

本記事の内容は、公式ドキュメントに記載されているわけではなく、GitHubのissueを確認し検証した内容のため、正しくない可能性があります。

まとめ

Terraformには、再作成や変更が起きない、動的属性をもつパラメータがあります。
通常、毎回変わるパラメータには、ignore_changesを指定してtfstateの変更を無視させることがあります。 ここでいう「動的属性をもつパラメータ」とは、ignore_changesを指定しなくても、それ相当の動きをします。 動的属性をもつパラメータは、実リソースとtfstateに差分があったとしてもplanやapplyに影響しません(再作成や変更は行わない)。

例えば、AWS EC2のパブリックIPアドレスは動的属性として扱われています。
これにより、再起動してパブリックIPアドレスに変更があっても、再作成や変更のトリガーにはなりません。
terraform applyを実行すると、結果は0 added, 0 changed, 0 destroyed.となり、tfstateのパブリックIPアドレスが更新されます。

参考 github.com

github.com

検証

terraformで作成したEC2を停止→再起動してパブリックIPアドレスを変え、terraform planの結果やtfstateを確認します。

環境

OSは「Ubuntu 22.04.3 LTS」、Terraformは「v1.9.4」です。

terraformでEC2インスタンスを作る

以下のコードでEC2インスタンスを作ります。
リージョンやクレデンシャル情報は、環境変数にセットしておきます。

resource "aws_instance" "example" {
  ami           = "ami-06b21ccaeff8cd686" #東京リージョンのAmazonLinux2023AMI
  instance_type = "t2.micro"

  tags = {
    Name = "Example_terraform"
  }
}


terraform applyを実行し、tfstateを確認します。

{
  "version": 4,
  "terraform_version": "1.9.4",
(略)
            "public_dns": "ec2-13-230-98-202.ap-northeast-1.compute.amazonaws.com",
            "public_ip": "13.230.98.202",
(略)
  ],
  "check_results": null
}


EC2インスタンスを停止後、起動して差分を確認する

AWSコンソールで停止→起動してパブリックIPアドレスを変えました。
結果、terraform planで差分は出ませんでした。この時点で、tfstateと割り振られたパブリックIPアドレスは異なります。

$ terraform plan
aws_instance.example: Refreshing state... [id=i-049e024097907a1a5]

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 applyしても再作成されませんでした。
ただし、tfstateのパブリックIPアドレスが更新されていました。

$ terraform apply
aws_instance.example: Refreshing state... [id=i-049e024097907a1a5]

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.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
$ no


0 added, 0 changed, 0 destroyed.であり、更新したことがわかるメッセージなどはありません。

$ diff terraform.tfstate terraform.tfstate.backup 
4c4
<   "serial": 5,
---
>   "serial": 4,
96,97c96,97
<             "public_dns": "ec2-43-207-112-92.ap-northeast-1.compute.amazonaws.com",
<             "public_ip": "43.207.112.92",
---
>             "public_dns": "ec2-13-230-98-202.ap-northeast-1.compute.amazonaws.com",
>             "public_ip": "13.230.98.202",


所感

tfファイルを変更していないのに再作成になる話(=tfstate更新)はよく聞くのですが、tfファイルを変更しておらず再作成や変更もないのにtfstateが更新されるパターンもあります。
Terraform Registryaws_instanceのpublic_ipにも記載はないので、いずれどこかに記載されたらありがたいなと思います。