Create_before_destroy affects other resources without lifecycle

Hi,

Perhaps this is expected behavior but I’m not sure and curious if someone can confirm.

In Terraform we can enforce object creation before destroying with create_before_destroy = true lifecycle attribute. When resource is created, the previous instance is marked as “deposed object” and eventually destroyed. Everywhere I can read that applies to resources with this lifecycle settings, but I can see the same happens to resources that the object with create_before_destroy depends on, even if that object is not part of the plan.

For example, if I’m attaching few policies to the aws_iam_role and I have aws_iam_instance_profile with create_before_destroy = true and depends_on = [ aws_iam_role_policy_attachment.workers_policies ], as follows:

data "aws_iam_policy_document" "workers_assume_role_policy" {
  statement {
    sid = "EKSWorkerAssumeRole"

    actions = [
      "sts:AssumeRole",
    ]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "workers" {
  name                  = "test"
  assume_role_policy    = data.aws_iam_policy_document.workers_assume_role_policy.json
  force_detach_policies = true
}

resource "aws_iam_instance_profile" "workers" {
  name_prefix = "test"
  role        = aws_iam_role.workers.name

  lifecycle {
    create_before_destroy = true
  }

  depends_on = [
    aws_iam_role_policy_attachment.workers_policies
  ]
}

locals {
  workers_policies = ["arn:aws:iam::aws:policy/AmazonEC2FullAccess", "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"]
}

resource "aws_iam_role_policy_attachment" "workers_policies" {
  count      = length(local.workers_policies)
  role       = aws_iam_role.workers.name
  policy_arn = local.workers_policies[count.index]
}

The attachments are first created, marked as “deposed” and destroyed, so when I would change the name of any workers_policies I would get it removed after first apply, or both if I would change the order for example. It works fine if I would remove depends_on from instance_profile.

It’s a bit simplified example. I know it might be an issue just when count is used and can be easily workarounded with for_each, but I’m more curious about the whole mechanism of inheriting lifecycle behavior by other resources.

I would appreciate any confirmation or link to docs/threads if I missed something.

Thank you,
Wojtek

Hi @wojtekm,

Correct, it is not possible for Terraform to apply resources with create_before_destroy without also re-ordering all dependencies to match. I made some notes here for reference.

Thank you @jbardin for confirmation and additional notes :slight_smile: