TerraformでEC2のUserDataを変えると再起動する

EC2インスタンスを作成する際、resource "aws_instance" を使用するとUserDataを変更するとEC2インスタンスが再起動します。

モジュールを作成して、新しいインスタンスを作成するときにUserDataを変更したい場合に問題が発生します。

resource "aws_instance" "example" {
  # ...
  user_data = <<-EOF
    # ...
  EOF
}

上記のようなEC2インスタンスを作成するリソースを含むモジュールを作成し、必要な数だけ呼び出します。

module "instance_1" {
  source "./modules/ec2_instance"
  # ...
}

次に立ち上げるインスタンスを作成する前にUserDataへ変更を加えた場合、上記で作成したinstance_1のインスタンスが再起動します。

UserDataは初期起動時に実行したいスクリプトを書くので、すでに起動しているインスタンスは変更する必要がありません。

この問題を解決するためにignore_changes を使用して既存のインスタンスに変更を加えないようにします。

ignore_changes

ignore_changes は、Terraformの resource ブロックで使用される引数の1つです。 この引数を使用するとTerraformは指定されたリソースの特定の属性の変更を無視するようになります。

ignore_changesの基本的な使い方

ignore_changeslifecycleブロックのなかで以下のように使用します。

  lifecycle {
    ignore_changes = [
      変更を無視する属性
    ]
  }

ignore_changesで全属性の変更を無視する

すべての変更を無視する場合はallを指定します。

  lifecycle {
    ignore_changes = all
  }

UserDataの変更をignore_changesで無視する

UserDataはEC2インスタンスの起動スクリプトを指定するためのものです。

UserDataを変更するだけでEC2インスタンスが再起動されるという問題がありますが、 ignore_changes を使うと回避できます。

具体的には、以下のように ignore_changes を使用します。

resource "aws_instance" "example" {

  # ...

  lifecycle {
    ignore_changes = [
      user_data
    ]
  }
}

上記のコードでは、aws_instance リソースで ignore_changes を使用して user_data を指定しています。この設定により、UserDataが変更された場合でもEC2インスタンスは再作成されず、そのまま維持されます。

無視されたかどうかを確認

想定通り無視されたかどうかを確認するには、ignore_changes指定した属性を変更してみた上で、terraform planを実行して確認する。

$ terraform plan

適用済みのリソースに対して上記コマンドを実行し、差分が出なければオーケー。