AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

Terraform 内に EC2 リソースが含まれるときは ignore_changes に ami を指定する

Terraform で EC2 を作成する

ときには、 AMI 参照をパラメータストア経由で行うと良い。 このように。

aws_instance
resource "aws_instance" "ec2"{
  ami = data.aws_ssm_parameter.amazonlinux2.value

...

}
aws_ssm_parameter
# Parameter Store のパブリックパラメーターを利用して AMI ID を取得
# https://dev.classmethod.jp/articles/retrieve-latest-ami-id-of-amazonlinux-2023/
data "aws_ssm_parameter" "amazonlinux2" {
  name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" # x86_64
  # name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2" # ARM
  # name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-x86_64-ebs" # Minimal Image (x86_64)
  # name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-arm64-ebs" # Minimal Image (ARM)
}

パブリックパラメーターの呼び出し

参考

docs.aws.amazon.com

qiita.com

これだと terraform (plan|apply) 実行時に destroy が走る場合がある

タイトルがすべてシリーズ。

これだと、AWS が用意してくれている AMI の id を直接参照している。 ので AWS 側で AMI を更新すると ami id が変更されて、aws_instance (EC2 リソース) が「ムムッ変更やんけ!」というように受け取り、 deestroy -> create という自体になる。 その動作は望んでないんだけど、仕組みを説明されたら「それはそう!」となるやつ。

なので、以下のように aws_instance 内の ignore_changes に ami を除外する設定を追記する。

resource "aws_instance" "ec2"{
  ami = data.aws_ssm_parameter.amazonlinux2.value

...

  # ami id が更新されてもインスタンスを再作成しない (無視する)
  lifecycle {
    ignore_changes = [
      ami
    ]
  }

}

コレでよい。 plan, apply 実行時に壊れるのなんでだろう、と気付くまで半年かかったのでワイは愚か。 (基本的に target で指定して ECS へリリースしていたので、問題に気付くまで遅れたという邪悪な理由がある。)