1

I have this in my main.tf and

dynamic "identity" {
    for_each = var.identity == [] ? [] : [1]
    content {
      type         = lookup(var.identity, "type", null)
      #identity_ids = lookup(var.identity, "identity_ids", null)
    }
}

I have defined variable as below.

variable "identity" {
  description = "creates the identity for Logic App."
  type    = any
  default = []
}

Removing identity block from input does not remove assigned identity. Terraform does not detect the change. Can some1 help ?

Also Logic App standard only supports SystemAssigned but doc says something else : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/logic_app_standard

Suraj
  • 135
  • 2
  • 8
  • Can you provide full context of your code? Also `lookup` is for maps, but your variable is a list. – Marcin Dec 09 '21 at 00:37
  • So I created a logic app standard resource with SystemAssigned identity and now I want to remove it. I tried with default value as null as well but no change. – Suraj Dec 09 '21 at 01:36

1 Answers1

2

There seems to be some type confusion in your configuration here, but Terraform isn't able to detect and report it because you didn't give a specific type constraint for your variable.

Specifically, it's not clear whether you intended var.identity to be a list of objects or a single object. You declared the default as [], suggesting you meant a list, but the content of the dynamic "identity" block treats var.identity as if it's just a single object.

I'm going to write this out both ways, so you can choose which one meets your actual requirement.


For a list of "identities" with one identity block each:

variable "identities" {
  type = list(object({
    type         = string
    identity_ids = set(string)
  }))
  default = []
}

resource "example" "example" {
  dynamic "identity" {
    for_each = var.identities
    content {
      type         = each.value.type
      identity_ids = each.value.identity_ids
    }
  }
}

For a single "identity" object that is optional:

variable "identities" {
  type = object({
    type         = string
    identity_ids = set(string)
  })
  default = null
}


resource "example" "example" {
  dynamic "identity" {
    for_each = var.identities[*]
    content {
      type         = each.value.type
      identity_ids = each.value.identity_ids
    }
  }
}

In this second example, notice that:

  • The type constraint for variable "identities" is now just for an object type directly, without the list(...) from the first example.
  • The default value for that variable is now null, which is the typical way to represent the absence of a single value.
  • The dynamic "identity" block's for_each expression uses the [*] operator, called the "splat operator", which has a special behavior where it'll convert a null value into an empty list and a non-null value into a single-element list, thus producing a suitable collection value for the for_each argument.

I would recommend always writing type constraints for your input variables, because then Terraform can give you better feedback in situations like yours where you were not consistent in the types you were using. If you use any in a type constraint then Terraform will have less insight into what you are intending and so its error messages will typically be less specific and possibly even misleading, if it makes an incorrect assumption about what your goals were.

Martin Atkins
  • 62,420
  • 8
  • 120
  • 138