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

Using count and for_each together #31565

Closed
paololazzari opened this issue Aug 3, 2022 · 7 comments
Closed

Using count and for_each together #31565

paololazzari opened this issue Aug 3, 2022 · 7 comments
Labels
enhancement new new issue not yet triaged waiting-response An issue/pull request is waiting for a response from the community

Comments

@paololazzari
Copy link

When using both together:

The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.

What's the reason for this limitation? This seems like such a weird thing.

My use case is identical to this one #30030

@paololazzari paololazzari added enhancement new new issue not yet triaged labels Aug 3, 2022
@jbardin
Copy link
Member

jbardin commented Aug 3, 2022

Hi @paololazzari,

Objects in terraform can be expanded into a number of instances, keyed by either a numeric index, or a string key; there is no way to use both as an index into the same structure. If there are multiple sources of key values for a resource, they can be combined into a single for_each expression using a single level of expansion.

We use GitHub issues for tracking bugs and enhancements, rather than for questions. While we can sometimes help with certain simple problems here, it's better to use the community forum where there are more people ready to help.

Thanks!

@jbardin jbardin closed this as not planned Won't fix, can't repro, duplicate, stale Aug 3, 2022
@paololazzari
Copy link
Author

Mine wasn't a question, it was an enhancement request which is why I opened it with with the "enhancement" tag. Can you reopen it please?

@jbardin
Copy link
Member

jbardin commented Aug 3, 2022

Hi @paololazzari,

Could you elaborate a bit on the points from the issue template, like what the intended use case is, and what the proposal would look like? The literal interpretation of using count+for_each is not possible in terraform as it exists now, which would be to structure all resources as nested maps in a list (or vise versa). While that could allow for using both expansion modes, it would also require rewriting how terraform evaluates all resources and configuration, and make configuration generally more complex. This means it's not likely something that will be implemented given other possible solutions.

If multiple nested levels of configuration are needed, forcing that to be only 2 levels deep and consisting of an ordered level and a map level is somewhat arbitrary and limiting. More flexibility can be gained by generating a flat data structure containing all of the desired instances without such limitations.

@jbardin jbardin reopened this Aug 3, 2022
@jbardin jbardin added the waiting-response An issue/pull request is waiting for a response from the community label Aug 3, 2022
@bastiandg
Copy link

Hey @paololazzari, I think I know what you are trying to achieve, correct me if I'm wrong. You want to create a resource with the for_each meta-argument, but on a condition. That can be achieved by adding the conditional to for_each and without count. See:

locals {
  workspace    = terraform.workspace
  for_each_set = toset(["1", "2", "3"])
}

resource "random_string" "conditional_for_each_resource" {
  for_each = local.workspace == "staging" ? local.for_each_set : []
  length   = 10
}

workspace default

$ terraform workspace list 
* default
  staging

$ terraform apply 

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

workspace staging

$ terraform workspace select staging 
Switched to workspace "staging".
$ terraform apply 

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

[…]

random_string.conditional_for_each_resource["3"]: Creating...
random_string.conditional_for_each_resource["1"]: Creating...
random_string.conditional_for_each_resource["2"]: Creating...
random_string.conditional_for_each_resource["1"]: Creation complete after 0s [id=TYl*-%z5#*]
random_string.conditional_for_each_resource["3"]: Creation complete after 0s [id=BU3jTP6RQ]]
random_string.conditional_for_each_resource["2"]: Creation complete after 0s [id=83RzgTf[t5]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

@apparentlymart
Copy link
Member

In addition to @bastiandg's suggestion, there's a more general form of this which allows more detailed conditions that conditionally exclude only a subset of the elements in input map or set:

resource "example" "example" {
  for_each = {
    for k, v in var.something : k => v
    if arbitrary_condition_here
  }
}

The arbitrary_condition_here expression can, but does not need to, refer to k and v to make decisions on a per-element basis.

In the simple case where you just want to disable something entirely based on a global value, you can write a condition that doesn't refer to the element key or element value, like this:

variable "enable_thing" {
  type = bool
}

resource "example" "example" {
  for_each = {
    for k, v in var.something : k => v
    if var.enable_thing
  }
}

In any for expression where the if clause refers to neither the key or the value the expression will either keep all of the elements or filter all of the elements out, which in the latter case creates the same effect as setting count = 0.

@jbardin
Copy link
Member

jbardin commented Sep 12, 2022

Hello,

Since there has been no further updates about original topic, I'm going to close the issue. If you have more questions, feel free to start a discussion in the community forum.

Thanks!

@jbardin jbardin closed this as completed Sep 12, 2022
@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement new new issue not yet triaged waiting-response An issue/pull request is waiting for a response from the community
Projects
None yet
Development

No branches or pull requests

4 participants