Terraform-provider-aws: EC2 Instance with EBS be destroyed and created every time

Created on 4 May 2018  ยท  11Comments  ยท  Source: hashicorp/terraform-provider-aws

_This issue was originally opened by @a9tm as hashicorp/terraform#17991. It was migrated here as a result of the provider split. The original body of the issue is below._


I launched an EC2 instance from my AMI, it includes an additional EBS volume for data, and this instance be destroyed and recreated every time terraform plan/apply. How can I make this instance persist?

Terraform Version

Terraform v0.11.6
+ provider.aws v1.15.0

Terraform Configuration Files

# Launch an EC2 Instance for Jenkins
resource "aws_instance" "my_jenkins" {
  # Snapshot of old Jenkins server
  ami = "ami-xxxxxxxx"
  instance_type = "t2.medium"

  subnet_id = "${var.net_public_var}"

  vpc_security_group_ids = [
    "${var.my_sg_jenkins_var}",
  ]
  key_name = "${aws_key_pair.my_keypair.key_name}"
  root_block_device {
    volume_type = "gp2"
    volume_size = "16"
    delete_on_termination = true
  }
  ebs_block_device = {
    volume_type = "gp2"
    volume_size = "256"
    delete_on_termination = false
    device_name = "/dev/sdf"
  }
  volume_tags {
    Name = "my_jenkins_vol"
  }
  tags {
    Name = "my_jenkins_server"
  }
  user_data = "${file("${path.module}/user_data.txt")}"
}

Debug Output

Crash Output

Expected Behavior


Instance be created once time

Actual Behavior

Instance be destroyed and recreated all the time

Terraform will perform the following actions:

-/+ module.ec2.aws_instance.my_jenkins (new resource required)
      id:                                                "i-027212axxxx" => <computed> (forces new resource)
      ami:                                               "ami-7994xxxx" => "ami-7994xxxx"
      associate_public_ip_address:                       "false" => <computed>
      availability_zone:                                 "eu-central-1a" => <computed>
      ebs_block_device.#:                                "1" => "1"
      ebs_block_device.xxxx.delete_on_termination: "" => "false" (forces new resource)
      ebs_block_device.xxxx.device_name:           "" => "/dev/sdf" (forces new resource)
      ebs_block_device.xxxx.encrypted:             "" => <computed> (forces new resource)
      ebs_block_device.xxxx.snapshot_id:           "" => <computed> (forces new resource)
      ebs_block_device.xxxx.volume_id:             "" => <computed>
      ebs_block_device.xxxx.volume_size:           "" => "256" (forces new resource)
      ebs_block_device.xxxx.volume_type:           "" => "gp2" (forces new resource)
      ebs_block_device.xx.delete_on_termination:  "false" => "false"
      ebs_block_device.xx.device_name:            "/dev/sdf" => "" (forces new resource)
      ephemeral_block_device.#:                          "0" => <computed>
      get_password_data:                                 "false" => "false"
      instance_state:                                    "running" => <computed>
      instance_type:                                     "t2.medium" => "t2.medium"
      ipv6_address_count:                                "" => <computed>
      ipv6_addresses.#:                                  "0" => <computed>
      key_name:                                          "my_common_key" => "my_common_key"
      network_interface.#:                               "0" => <computed>
      network_interface_id:                              "eni-0e67d545xxxx" => <computed>
      password_data:                                     "" => <computed>
      placement_group:                                   "" => <computed>
      primary_network_interface_id:                      "eni-0e67d545xxxx" => <computed>
      private_dns:                                       "ip-10-0-11-140.eu-central-1.compute.internal" => <computed>
      private_ip:                                        "10.0.11.140" => <computed>
      public_dns:                                        "" => <computed>
      public_ip:                                         "" => <computed>
      root_block_device.#:                               "1" => "1"
      root_block_device.0.delete_on_termination:         "true" => "true"
      root_block_device.0.volume_id:                     "vol-0cdaa69xxxx" => <computed>
      root_block_device.0.volume_size:                   "16" => "16"
      root_block_device.0.volume_type:                   "gp2" => "gp2"
      security_groups.#:                                 "0" => <computed>
      source_dest_check:                                 "true" => "true"
      subnet_id:                                         "subnet-77e7xxxx" => "subnet-77e7xxxx"
      tags.%:                                            "1" => "1"
      tags.Name:                                         "ym_jenkins_server" => "my_jenkins_server"
      tenancy:                                           "default" => <computed>
      user_data:                                         "5a90f7d84f328093bc6342a3e9c5dc9ed670ab2c" => "5a90f7d84f328093bc6342a3e9c5dc9ed670ab2c"
      volume_tags.%:                                     "1" => "1"
      volume_tags.Name:                                  "my_jenkins_vol" => "ym_jenkins_vol"
      vpc_security_group_ids.#:                          "1" => "1"
      vpc_security_group_ids.33852xxxx:                 "sg-fd29xxxx" => "sg-fd29xxxx"

Steps to Reproduce

Additional Context

References

bug servicec2 stale

Most helpful comment

I found this as I was trying to figure out why my EC2 instances were getting rebuilt every time I ran terraform apply. For mine it was because I had specified security_groups = "<mylist>"]. The problem went away when I corrected it to vpc_security_group_ids = "<mylist>".

All 11 comments

I can't reproduce this on terraform 0.11.7 w/ AWS provider 1.24.0. Does this happen for you with the latest terraform and provider?

Also, while it may not matter here, the normal AWS expectation is that block devices are /dev/vx* instead of /dev/sd* so it's possible that your drift is from your block device of /dev/sdf rather than /dev/vxdf.

If this still happens with the latest terraform and provider, and changing your block device doesn't resolve it, I would suggest you run Terraform in debug mode and attach the debug log to this issue.

  • @a9tm

It still happens to me on :

Terraform v0.11.7
+ provider.aws v1.23.0
+ provider.template v1.0.0

As a workaround I got it to work properly with:

lifecycle {
    ignore_changes  = ["ebs_block_device"]
    prevent_destroy = false
  }

This is also happening to me. ebs_block_device is giving me (forces new resource)
@heldersepu work around worked for me

This happens to me as well, for multiple block devices it seems like terraform is not properly tracking the second volume onward.

Also, while it may not matter here, the normal AWS expectation is that block devices are /dev/vx* instead of /dev/sd* so it's possible that your drift is from your block device of /dev/sdf rather than /dev/vxdf.

I also do not think this is true, given the documentation here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html

There are a handful of AMIs I've been misfortunate enough to use that require the devices to be named in the /dev/sd range.

Guys, after a long time with this issue I discovered that the documentation of Terraform is a real piece of shit.

When you need to create and attach an EBS block device with your instance and you want that this code work when you need to expand or make some changes, you CAN'T use "ebs_block_device" inside the resource of "aws_instance", you will have to use the resource "aws_ebs_volume" and the other resource "aws_volume_attachment" together like my example below:

provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "${var.aws_region}"
}

resource "aws_instance" "test-instance" {
ami = "${var.ami}"
instance_type = "t2.nano"
subnet_id = "${aws_subnet.test-subnet.id}"
key_name = "${var.aws_key_name}"
private_ip = "${var.test_instance_ip}"
associate_public_ip_address = true
vpc_security_group_ids = ["${aws_security_group.test-sg.id}"]
root_block_device {
volume_size = 20
}
tags {
Name = "test-instance"
}
}

resource "aws_volume_attachment" "ebs_att" {
device_name = "/dev/sdb"
volume_id = "${aws_ebs_volume.test-ebs.id}"
instance_id = "${aws_instance.test-instance.id}"
}

resource "aws_ebs_volume" "test-ebs" {
availability_zone = "us-east-2a"
size = 10
type = "gp2"

tags {
Name = "test-ebs"
}
}

My example has a lot of variables from another files, but I hope that you all understand the idea.

@frovai you are damn right. Not only the documentation is terrible but also terraform itself. I have the same exact problem with terraform import. Same bug. It says that the instance on aws is imported successfully but then when you do the plan and then the apply, terraform wants to destroy and recreate it at any cost ! This is frankly very dumb. Moreover the terraform import does not create "yet" the configuration for the instance but you have to write it manually yourself.

Terraform v0.11.7

  • provider.aws v1.11.0
  • provider.cloudflare v0.1.0

I found this as I was trying to figure out why my EC2 instances were getting rebuilt every time I ran terraform apply. For mine it was because I had specified security_groups = "<mylist>"]. The problem went away when I corrected it to vpc_security_group_ids = "<mylist>".

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

Was this page helpful?
0 / 5 - 0 ratings