Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect destroy behaviour with target on terraform 0.12.6 #22549

Open
timota opened this issue Aug 21, 2019 · 2 comments
Open

Incorrect destroy behaviour with target on terraform 0.12.6 #22549

timota opened this issue Aug 21, 2019 · 2 comments
Labels
config enhancement v0.12 Issues (primarily bugs) reported against v0.12 releases

Comments

@timota
Copy link

timota commented Aug 21, 2019

When trying to destroy aws_ebs_volume created with help of for_each, related and not related to it aws_volume_attachment resources also marked for remove

Terraform Version

Terraform v0.12.6
+ provider.aws v2.24.0

Terraform Configuration Files

locals {
  name                = "tst-instance"
  number_of_instances = 2
  inst_map = [for i in range(local.number_of_instances) :
    {
      name = format("%s-%02d", local.name, i + 1)
    }
  ]

  inst_disk_map = {
    "tst-instance-01-vol-sdf" = {
      inst = "tst-instance-01"
      name = "sdf"
      size = 1
    }
    "tst-instance-01-vol-sdg" = {
      inst = "tst-instance-01"
      name = "sdg"
      size = 1
    }
    "tst-instance-02-vol-sdf" = {
      inst = "tst-instance-02"
      name = "sdf"
      size = 1
    }
    "tst-instance-02-vol-sdg" = {
      inst = "tst-instance-02"
      name = "sdg"
      size = 1
    }

  }

}

resource "aws_instance" "instance" {
  for_each      = toset(local.inst_map[*].name)
  ami           = "ami-22741f5a"
  instance_type = "t2.micro"
  subnet_id     = "subnet-0172fd32874f0df4a"

}

resource "aws_ebs_volume" "volume" {
  for_each = local.inst_disk_map

  availability_zone = "us-west-2a"
  size              = each.value.size
}

resource "aws_volume_attachment" "volume_attachment" {
  for_each = local.inst_disk_map

  device_name = each.value.name
  instance_id = aws_instance.instance[each.value.inst].id
  volume_id   = aws_ebs_volume.volume[each.key].id

}

Expected Behavior

Only aws_ebs_volume and related attachment should be removed. Other attachments that related to another volumes should stay untouched.

Actual Behavior

Terraform will perform the following actions:

  # aws_ebs_volume.volume["tst-instance-01-vol-sdf"] will be destroyed
  - resource "aws_ebs_volume" "volume" {

  # aws_volume_attachment.volume_attachment["tst-instance-01-vol-sdf"] will be destroyed
  - resource "aws_volume_attachment" "volume_attachment" {

  # aws_volume_attachment.volume_attachment["tst-instance-01-vol-sdg"] will be destroyed
  - resource "aws_volume_attachment" "volume_attachment" {

  # aws_volume_attachment.volume_attachment["tst-instance-02-vol-sdf"] will be destroyed
  - resource "aws_volume_attachment" "volume_attachment" {

  # aws_volume_attachment.volume_attachment["tst-instance-02-vol-sdg"] will be destroyed
  - resource "aws_volume_attachment" "volume_attachment" {

Steps to Reproduce

terraform init
terraform apply
terraform plan -destroy -target='aws_ebs_volume.volume["tst-instance-01-vol-sdf"]'
@teamterraform
Copy link
Contributor

Hi @timota,

Unfortunately Terraform is working as designed here, because it's noticing that aws_volume_attachment.volume_attachment depends on aws_ebs_volume.volume in order to get the map of aws_ebs_volume.volume instances and then select the each.key element from it.

It sounds like the behavior you were expecting here -- reasonably -- is that Terraform would understand that each.key dynamically selects only a specific instance and thus create fewer dependencies. That is not how Terraform's graph model works today (the planning graph is in terms of whole resources rather than resource instances), so we asked the bot to mark this as an enhancement to make Terraform use a more granular dependency resolution mechanism.

That is not an easy change, so this is unlikely to be implemented in the near term. Note that -target is provided only for exceptional circumstances, such as recovering from mistakes or working around Terraform limitations. It is not recommended to use -target for routine operations, since this can lead to undetected configuration drift and confusion about how the true state of resources relates to configuration. For that reason, we do not tend to prioritize -target-related requirements when considering future architectural changes.

@ilunov-clgx
Copy link

@teamterraform please consider a use case for a -target and resources provisioned with for_each loops:
Let's say you have a code pattern that provisions 100 vms with disk attached. And you need to re-create only on of them. So what do you do? You invoke destroy with -target and target this one vm . What will terraform do ? - Destroys vm , its disk attachment and all other attachments of disks for other 99vms... How can i achieve the goal of re-creating one resource and not impacting the others without -target ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
config enhancement v0.12 Issues (primarily bugs) reported against v0.12 releases
Projects
None yet
Development

No branches or pull requests

4 participants