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

Dynamically create nested blocks using the count meta-argument #33105

Open
hknutsen opened this issue Apr 27, 2023 · 4 comments
Open

Dynamically create nested blocks using the count meta-argument #33105

hknutsen opened this issue Apr 27, 2023 · 4 comments
Labels
enhancement new new issue not yet triaged

Comments

@hknutsen
Copy link

Terraform Version

Terraform v1.4.5
on linux_amd64

Use Cases

It's possible to dynamically create resources using either the for_each or count meta-argument.

It's possible to dynamically create nested blocks using only the for_each meta-argument.

By adding support for dynamically creating nested blocks using the count meta-argument, it'd simplify the creation of conditional nested blocks.

Attempted Solutions

Conditional creation of nested block using the for_each meta argument.

variable "identity_enabled" {
  description = "Should the system-assigned identity be enabled?"
  type        = bool
  default     = false
}

resource "azurerm_linux_web_app" "example" {
  # omitted

  dynamic "identity" {
    for_each = var.identity_enabled ? [1] : []

    content {
      type = "SystemAssigned"
    }
  }
}

output "identity_principal_id" {
  description = "The principal ID of the system-assigned identity."
  value       = try(azurerm_linux_web_app.example.identity[0].principal_id, null)
}

Notice how this solution relies on either passing a list containing an arbitrary value 1 or an empty list to for_each in order to conditionally create the identity block.

Proposal

Conditional creation of nested block using the count meta argument.

variable "identity_enabled" {
  description = "Should the system-assigned identity be enabled?"
  type        = bool
  default     = false
}

resource "azurerm_linux_web_app" "example" {
  # omitted

  dynamic "identity" {
    count = var.identity_enabled ? 1 : 0

    content {
      type = "SystemAssigned"
    }
  }
}

output "identity_principal_id" {
  description = "The principal ID of the system-assigned identity."
  value       = try(azurerm_linux_web_app.example.identity[0].principal_id, null)
}

Notice how this solution simplifies the conditional creation of the identity block by specifying if 1 or 0 blocks should be created.

References

No response

@hknutsen hknutsen added enhancement new new issue not yet triaged labels Apr 27, 2023
@jbardin
Copy link
Member

jbardin commented Apr 28, 2023

Hi @hknutsen,

Thanks for filing the issue. Resource blocks are defined by the configuration whether they represent an ordered series of instances (count) or an unordered map of instances (for_each). Nested blocks however have their type defined by the schema, so any concept of block expansion needs to apply equally to all schema types. Blocks themselves can be of a list, set, or labeled map types, and for this reason we have the for_each argument to the dynamic block rather than count. Since the configuration does not differentiate between ordered and unordered block values, I don't think it's likely that we would introduce a count argument which can only apply to a single type.

@vincer
Copy link
Contributor

vincer commented Apr 28, 2023

The reality of it is that the for_each = var.something ? [1] : [] is a pretty common sight when we simply want to include a block on simple boolean condition. But it's an awkward syntax and has caused multiple questions in code reviews.

Allowing the use of count would at least be consistent and allow for the also common count = var.something ? 1 : 0.

@digglife

This comment was marked as off-topic.

@mateustanaka

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement new new issue not yet triaged
Projects
None yet
Development

No branches or pull requests

5 participants