Answers: <p>The old volume is never detached because <code>skip_destroy = true</code>.  From the terraform docs:</p>
  
  <blockquote>
    <p>skip_destroy - (Optional, Boolean) Set this to true if you do not wish to detach the volume from the instance to which it is attached at destroy time, and instead just remove the attachment from Terraform state. This is useful when destroying an instance which has volumes created by some other means attached.</p>
  </blockquote>
  
  <p>If you remove that, the old attachment will be destroyed and the attachment point should be available for the new attachment.</p>
  
  <p>You may need to manually delete the old attachment this one time, I believe Terraform may have already deleted it from the state.</p>
  
Answers: CC BY-SA 3.0
Answers: 2017-04-17T16:31:15.463Z
Answers: 2017-04-17T16:31:15.463Z
Answers: Theron Luhn
Body: <p>Is there a way to detach EBS volume from existing EC2 instance and attach a new EBS volume using <code>Terraform v0.9.2</code> ?</p>
  
  <p>I prefer to replace the volume rather than trying to destroy the instance and create a new one with new volume.</p>
  
  <p>File system is unmounted from the device within the operating system before detaching the volume and also there is no issue to detach the volume from AWS console.</p>
  
  <pre><code>resource "aws_ebs_volume" "create_volume" {
    availability_zone = "eu-central-1a"
    snapshot_id = "${data.aws_ebs_snapshot.mysql.id}"
    type = "gp2"
    tags {
      Name = "${var.instance_name}"
    }
  }
  
  resource "aws_volume_attachment" "mysql_data" {
    depends_on = ["null_resource.stop_mysql_service2"]
    device_name = "/dev/xvdf"
    volume_id = "${aws_ebs_volume.create_volume.0.id}"
    instance_id = "i-0d48be4266da"
    skip_destroy = true
    force_detach = true
  }
  
  $ ./terraform apply
  data.aws_ebs_snapshot.mysql: Refreshing state...
  aws_ebs_volume.create_volume: Creating...
    availability_zone: "" =&gt; "eu-central-1a"
    encrypted:         "" =&gt; "&lt;computed&gt;"
    iops:              "" =&gt; "&lt;computed&gt;"
    kms_key_id:        "" =&gt; "&lt;computed&gt;"
    size:              "" =&gt; "&lt;computed&gt;"
    snapshot_id:       "" =&gt; "snap-0afb2303c60f"
    tags.%:            "" =&gt; "1"
    tags.Name:         "" =&gt; "mysql"
    type:              "" =&gt; "gp2"
  aws_ebs_volume.create_volume: Still creating... (10s elapsed)
  aws_ebs_volume.create_volume: Creation complete (ID: vol-04c7f4)
  null_resource.stop_mysql_service2: Creating...
  null_resource.stop_mysql_service2: Provisioning with 'remote-exec'...
  null_resource.stop_mysql_service2 (remote-exec): Connecting to remote host via SSH...
  null_resource.stop_mysql_service2 (remote-exec):   Host: mysql
  null_resource.stop_mysql_service2 (remote-exec):   User: ubuntu
  null_resource.stop_mysql_service2 (remote-exec):   Password: false
  null_resource.stop_mysql_service2 (remote-exec):   Private key: true
  null_resource.stop_mysql_service2 (remote-exec):   SSH Agent: true
  null_resource.stop_mysql_service2 (remote-exec): Connected!
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2: Still creating... (10s elapsed)
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec):  * Attempt to shutdown MySQL Community Server 5.6.35 timed out
  null_resource.stop_mysql_service2: Still creating... (20s elapsed)
  null_resource.stop_mysql_service2: Still creating... (30s elapsed)
  null_resource.stop_mysql_service2: Creation complete (ID: 1850529311883)
  aws_volume_attachment.mysql_data: Creating...
    device_name:  "" =&gt; "/dev/xvdf"
    force_detach: "" =&gt; "true"
    instance_id:  "" =&gt; "i-0d48be4266da"
    skip_destroy: "" =&gt; "true"
    volume_id:    "" =&gt; "vol-04c7f4"
  aws_volume_attachment.mysql_data: Still creating... (10s elapsed)
  Error applying plan:
  
  1 error(s) occurred:
  
  * aws_volume_attachment.mysql_data: 1 error(s) occurred:
  
  * aws_volume_attachment.mysql_data: [WARN] Error attaching volume (vol-04c7f4) to instance (i-0d48be4266da), 
  message: "Invalid value '/dev/xvdf' for unixDevice. Attachment point /dev/xvdf is already in use", code: "InvalidParameterValue"
  
  Terraform does not automatically rollback in the face of errors.
  Instead, your Terraform state file has been partially updated with
  any resources that successfully completed. Please address the error
  above and apply again to incrementally change your infrastructure.
  </code></pre>
  
Tags: <amazon-web-services><terraform>
Title: How do I detach an existing volume and attach a new volume with Terraform?
UserDisplayName: Berlin
ThreadText: # How do I detach an existing volume and attach a new volume with Terraform?
  
  (Asked by: username_0 on 2017-04-17)
  
  Is there a way to detach EBS volume from existing EC2 instance and attach a new EBS volume using `Terraform v0.9.2` ?
  
  I prefer to replace the volume rather than trying to destroy the instance and create a new one with new volume.
  
  File system is unmounted from the device within the operating system before detaching the volume and also there is no issue to detach the volume from AWS console.
  
  ```
  resource "aws_ebs_volume" "create_volume" {
    availability_zone = "eu-central-1a"
    snapshot_id = "${data.aws_ebs_snapshot.mysql.id}"
    type = "gp2"
    tags {
      Name = "${var.instance_name}"
    }
  }
  
  resource "aws_volume_attachment" "mysql_data" {
    depends_on = ["null_resource.stop_mysql_service2"]
    device_name = "/dev/xvdf"
    volume_id = "${aws_ebs_volume.create_volume.0.id}"
    instance_id = "i-0d48be4266da"
    skip_destroy = true
    force_detach = true
  }
  
  $ ./terraform apply
  data.aws_ebs_snapshot.mysql: Refreshing state...
  aws_ebs_volume.create_volume: Creating...
    availability_zone: "" => "eu-central-1a"
    encrypted:         "" => "<computed>"
    iops:              "" => "<computed>"
    kms_key_id:        "" => "<computed>"
    size:              "" => "<computed>"
    snapshot_id:       "" => "snap-0afb2303c60f"
    tags.%:            "" => "1"
    tags.Name:         "" => "mysql"
    type:              "" => "gp2"
  aws_ebs_volume.create_volume: Still creating... (10s elapsed)
  aws_ebs_volume.create_volume: Creation complete (ID: vol-04c7f4)
  null_resource.stop_mysql_service2: Creating...
  null_resource.stop_mysql_service2: Provisioning with 'remote-exec'...
  null_resource.stop_mysql_service2 (remote-exec): Connecting to remote host via SSH...
  null_resource.stop_mysql_service2 (remote-exec):   Host: mysql
  null_resource.stop_mysql_service2 (remote-exec):   User: ubuntu
  null_resource.stop_mysql_service2 (remote-exec):   Password: false
  null_resource.stop_mysql_service2 (remote-exec):   Private key: true
  null_resource.stop_mysql_service2 (remote-exec):   SSH Agent: true
  null_resource.stop_mysql_service2 (remote-exec): Connected!
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2: Still creating... (10s elapsed)
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec): .
  null_resource.stop_mysql_service2 (remote-exec):  * Attempt to shutdown MySQL Community Server 5.6.35 timed out
  null_resource.stop_mysql_service2: Still creating... (20s elapsed)
  null_resource.stop_mysql_service2: Still creating... (30s elapsed)
  null_resource.stop_mysql_service2: Creation complete (ID: 1850529311883)
  aws_volume_attachment.mysql_data: Creating...
    device_name:  "" => "/dev/xvdf"
    force_detach: "" => "true"
    instance_id:  "" => "i-0d48be4266da"
    skip_destroy: "" => "true"
    volume_id:    "" => "vol-04c7f4"
  aws_volume_attachment.mysql_data: Still creating... (10s elapsed)
  Error applying plan:
  
  1 error(s) occurred:
  
  * aws_volume_attachment.mysql_data: 1 error(s) occurred:
  
  * aws_volume_attachment.mysql_data: [WARN] Error attaching volume (vol-04c7f4) to instance (i-0d48be4266da), 
  message: "Invalid value '/dev/xvdf' for unixDevice. Attachment point /dev/xvdf is already in use", code: "InvalidParameterValue"
  
  Terraform does not automatically rollback in the face of errors.
  Instead, your Terraform state file has been partially updated with
  any resources that successfully completed. Please address the error
  above and apply again to incrementally change your infrastructure.
  
  ```
  
  **Tags:** amazon-web-services, terraform
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-04-17. Score: 10 | Accepted answer
  
  The old volume is never detached because `skip_destroy = true`. From the terraform docs:
  
  > skip\_destroy - (Optional, Boolean) Set this to true if you do not wish to detach the volume from the instance to which it is attached at destroy time, and instead just remove the attachment from Terraform state. This is useful when destroying an instance which has volumes created by some other means attached.
  
  If you remove that, the old attachment will be destroyed and the attachment point should be available for the new attachment.
  
  You may need to manually delete the old attachment this one time, I believe Terraform may have already deleted it from the state.
  
  
  ---
  
  