1
0

『実践Terraform』でaws_instance.example must be replacedではなくaws_instance.example will be updated in-placeと表示された

Posted at

はじめに

Terraform初学者です。

実践Terraform』という書籍で勉強しています。

書籍の中でaws_instance.example must be replacedという出力が想定されている箇所がありました。

しかし、現在のバージョンで試してみるとaws_instance.example will be updated in-placeと出力されてしまいます。

この違いの原因について調べたので備忘録としてまとめます。

この記事におけるバージョンは Terraform v1.9.5 です。

一方で書籍のバージョンは Terraform v0.12.5 です。

問題

第2章 基本操作2.2 リソースの更新のサンプルコードが対象です。

まず、次のようにEC2インスタンスにNameタグを追加してterraform applyした状態があります。

example/main.tf
resource "aws_instance" "example" {
  ami = "ami-0c3fd0f5d33134a76"
  instance_type = "t3.micro"

  tags = {
    Name = "example"
  }
}

その後、Apacheをインストールするために次のようにmain.tfを修正する流れです。

example/main.tf
resource "aws_instance" "example" {
  ami = "ami-0c3fd0f5d33134a76"
  instance_type = "t3.micro"

  user_data = <<EOF
    #!/bin/bash
    yum install -y httpd
    systemctl start httpd.service
  EOF
}

ここでterraform applyを実行すると、aws_instance.example must be replacedというメッセージが出る想定となっています。

このメッセージは「既存のリソースを削除して新しいリソースを作成する」という意味です。

実際の動作

ところが僕のローカル環境では代わりに、aws_instance.example will be updated in-placeというメッセージが出ました。

example % terraform apply
aws_instance.example: Refreshing state... [id=i-0473f6955dab192a1]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_instance.example will be updated in-place
  ~ resource "aws_instance" "example" {
        id                                   = "i-0473f6955dab192a1"
      ~ tags                                 = {
          - "Name" = "example" -> null
        }
      ~ tags_all                             = {
          - "Name" = "example" -> null
        }
      + user_data                            = "5f11f9fb893f5c269243dd3d8efe2bc57983f538"
        # (38 unchanged attributes hidden)

        # (8 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

実行結果も異なる

書籍では元のEC2インスタンスを削除して新しいEC2インスタンスが作成される想定となっています。

しかし実際には、新しいEC2インスタンスが作成されることなく、元のEC2インスタンスが更新されていました。

結論

結論として、Terraform自体の問題ではなくterraform-provider-awsのバージョンが原因でした。

terraform-provider-awsとは?

terraform-provider-awsとは、TerraformでAWSのリソースを管理するためのプラグインです。

このプラグインによりTerraformへAWS固有の機能を追加できます。

terraform initコマンドを実行したときに自動でダウンロードされていました。

terraform-provider-awsのバージョン4.2.0から仕様変更されたようです。

  • 4.1.0まで: リソースの置き換えでuser_dataを更新
  • 4.2.0から: リソースは置き換えずそのままuser_dataを更新

下記のPRで変更がマージされていました。

再現方法

第2章の最初のコードでterraform-provider-awsのバージョン指定を追記した上で、terraform initを実行します。

example/main.tf
# この部分を追加
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.1.0"  # このバージョンだと must be replaced が出る
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_instance" "example" {
  ami = "ami-0c3fd0f5d33134a76"
  instance_type = "t3.micro"
}

その後は流れに沿って進めると、書籍と同様にaws_instance.example must be replacedのメッセージが出ました。

EC2インスタンスの立ち上がり方も書籍と同様でした。

おわりに

実践Terraform』はとてもわかりやすいため、初学者にもおすすめです。

ただし出版が2019年なので現在とは異なる点もあります。

今後もそういった箇所が見つかったら、適宜調べてさらにTerraformの理解を深めていきたいと思います。

また、この記事に誤りがありましたらコメントにて教えていただけますと幸いです。

参考資料

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0