【Terraform】Autoscaling GroupのLaunch Configurationを変更するのに失敗した話
先日、新しいECS ClusterをTerraformで作った。EC2インスタンスは1台のみだが、Launch Configurationを用意してAutoscaling Groupを作成した。
resource "aws_launch_configuration" "ecs_cluster" { name = "ecs_cluster" image_id = data.aws_ami.aws_optimized_ecs.id iam_instance_profile = aws_iam_instance_profile.ecs-cluster.name security_groups = [aws_security_group.ecs-cluster.id] user_data = file("${path.module}/user_data.sh") instance_type = "t3.medium" root_block_device { delete_on_termination = true encrypted = false volume_size = "30" volume_type = "gp2" } }
しかしその後、key_nameの登録を忘れておりEC2インスタンスにssh接続できないことに気づいたため、Launch Configurationを修正した。
resource "aws_launch_configuration" "ecs_cluster" {
name = "ecs_cluster"
image_id = data.aws_ami.aws_optimized_ecs.id
iam_instance_profile = aws_iam_instance_profile.ecs-cluster.name
security_groups = [aws_security_group.ecs-cluster.id]
user_data = file("${path.module}/user_data.sh")
instance_type = "t3.medium"
+ key_name = "ecs_cluster"
root_block_device {
delete_on_termination = true
encrypted = false
volume_size = "30"
volume_type = "gp2"
}
}
ところが、この状態で terraform apply
しようとしても失敗してしまった。
Error: error deleting Autoscaling Launch Configuration (terraform-20201203072824459100000004): ResourceInUse: Cannot delete launch configuration terraform-20201203093824531400000001 because it is attached to AutoScalingGroup ecs_cluster
これは、TerraformがLaunch Configurationを一旦削除し、同名のものを新しく作って追加しようとしているため。 terraform plan
の結果は Plan: 1 to add, 1 to change, 1 to destroy.
となっており、 changeはAutoscaling Groupを、addとdestroyはLaunch Configurationを指している。
これを避けるためには2つの処理が必要となる。まず lifecycle
の中で create_before_destroy = true
を追加すること。通常であれば、resourceに対するupdateができない場合Terraformは古い方をdestroyしてから新しい方をcreateするが、この指定をすると先に新しいresourceのcreateが行われ、その後古い方をdestroyするようになる。これにより、Autoscaling Groupが起動しているのにLaunch Configurationがなくなってしまうということが起こらない。
もう一つは、 name
の指定をやめるか、あるいは name_prefix
の指定に変えること。これにより、新旧のLaunch Configurationが異なる名前を持つようになる。この指定を行わないと、同じ名前を持った新旧のresourceが一時的に併存することになってしまい、applyに失敗する可能性がある。
resource "aws_launch_configuration" "ecs_cluster" { - name = "ecs_cluster" + name_prefix = "ecs_cluster_" image_id = data.aws_ami.aws_optimized_ecs.id iam_instance_profile = aws_iam_instance_profile.ecs-cluster.name security_groups = [aws_security_group.ecs-cluster.id] user_data = file("${path.module}/user_data.sh") instance_type = "t3.medium" key_name = "ecs_cluster" + lifecycle { + create_before_destroy = true + } root_block_device { delete_on_termination = true encrypted = false volume_size = "30" volume_type = "gp2" } }
このようにすると terraform apply
が成功した。