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

Function to convert boolean to 1 or 0 #33150

Open
tmccombs opened this issue May 4, 2023 · 8 comments
Open

Function to convert boolean to 1 or 0 #33150

tmccombs opened this issue May 4, 2023 · 8 comments
Labels
enhancement functions new new issue not yet triaged

Comments

@tmccombs
Copy link
Contributor

tmccombs commented May 4, 2023

Terraform Version

Terraform v1.4.3
on linux_amd64

Use Cases

The main use case I have for such a function is to use as the value to the count meta argument, to simplify conditionally creating resources.

Attempted Solutions

The standard way to do this would be to use a ternary operator with something like:

resource "null_resource" "example" {
  count = var.should_create ? 1 : 0
}

And this works, but it is kind of awkward, and IMO not very readable.

Proposal

Add a new function that takes a boolean, and returns 1 if the boolean is true, or 0 if it is false. It would effectively be something like:

f(x) = x ? 1 : 0

This could potentially just be extending the tonumber function to accept a boolean value or it could be new function. If the latter, I'm not sure what the best name for it would be. Perhaps "condcount", or "boolocount", or possibly something like "enabled" to indicate the specific use case it is useful for.

References

This has a similar goal to #21953, but is a smaller change, and doesn't require any fundamental changes to the language or design of terraform, so could be landed in a more reasonable amount of time.

@tmccombs tmccombs added enhancement new new issue not yet triaged labels May 4, 2023
@tmccombs
Copy link
Contributor Author

tmccombs commented May 4, 2023

I would be happy to help with the implementation if adding this function is something the maintainers are willing to accept, and we decide on a name for it.

@tmccombs tmccombs changed the title Function to conver boolean to 1 or 0 Function to convert boolean to 1 or 0 May 4, 2023
@crw crw added the functions label May 5, 2023
@crw
Copy link
Collaborator

crw commented May 5, 2023

Thanks for this request, I'll bring it to triage to discuss your proposal.

@timothyclarke
Copy link

I'd normally do the the following in a local

locals {
  my_var_true = var.should_create ? 1 : 0
}

resource "thing" "this" {
  count = local.my_var_true

@tmccombs
Copy link
Contributor Author

tmccombs commented May 18, 2023

Another function that has a somewhat related usecase is a function that is the inverse of one. meanting that it takes a scalar possibly null value , and if it is null creates an empty list, if it is non-null creates a singleton list containing just that item, so it woudl be equivalen to:

singleton(x) = x != null ? [x] : []

this would be useful for dynamic blocks, since you could do something like:

dynamic "block" {
  for_each = singleton(var.my_var)

  content {
     some_attr = block.x
  }
}

@crw
Copy link
Collaborator

crw commented May 19, 2023

@tmccombs I brought up the original use case in triage and the response was that we do not usually introduce new ways to solve a problem (as a built-in function, for example) if there is already a (relative concise) way to accomplish the same thing. In this case the ternary operator was deemed to be sufficiently uncomplicated for the use case. The subjective part here is "what is more or less readable code," but that is the reasoning of the maintainers in this case.

The second looks like it would follow similar logic, but is unique enough that I can re-raise the issue.

@tmccombs
Copy link
Contributor Author

IMO, something like:

count = if(var.enabled)

or even

count = tonumber(var.enabled)

is a lot more readable than

count = var.enabled ? 1 : 0 

and even more so, if instead of just a variable reference we have something like var.something != null since you now have a lot of symbols , and either need to worry about order of operations, or add parenthesis, which adds even more symbols.

For my singleton function, it also has the benefit, that you no longer have to repeat the expression multiple times. That is more of an issue if the expression is more complicated than just a variable lookup. Sometimes you can use a local to factor that out, but not always, for example, if the dynamic block is part of a resource that itself uses for_each or count, and you need to reference the iteration variable.

@crw
Copy link
Collaborator

crw commented Mar 6, 2024

Thank you for your continued interest in this issue.

Terraform version 1.8 launches with support of provider-defined functions. It is now possible to implement your own functions! We would love to see this implemented as a provider-defined function.

Please see the provider-defined functions documentation to learn how to implement functions in your providers. If you are new to provider development, learn how to create a new provider with the Terraform Plugin Framework. If you have any questions, please visit the Terraform Plugin Development category in our official forum.

We hope this feature unblocks future function development and provides more flexibility for the Terraform community. Thank you for your continued support of Terraform!

@pierreact
Copy link

pierreact commented Mar 20, 2024

https://developer.hashicorp.com/terraform/language/functions/tonumber should simply accept booleans as arguments.
You already can uglily to do: tonumber(tostring(true))

I have another use case for the request also.

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

No branches or pull requests

4 participants