Terraform: Create variable data based on conditions

I am relatively new to Terraform and I do understand that TF is not a programming language to assist in conditional looping. However, I have below requirement currently and would like to seek some assistance on the same

User will declare a list in below format for creation in their child module.

  serverlist = [
    {"name" : "PhysicalVM",  "value" : "Server1"},
    {"name" : "CloudVM", "value" : "CServer1"},
    {"name" : "PhysicalVM", "value" : "Server2"},
    {"name" : "PhysicalVM", "value" : "Server3"},
  ]

In my parent module, for creating resource, I need to store value based on above list like below

server_build = a1 && a2 || a3 || a4

If we get CloudVM, && should be used and if we see PhysicalVM, || symbol to be used.

How can we achieve this in Terraform?

Thanks

Hi @parthibansg20,

I’m afraid I don’t understand your goal. I’d like to learn more about it to try to answer your question.

I think what you’ve shown here is a value for a variable declared like this:

variable "serverlist" {
  type = list(object({
    name  = string
    value = string
  }))
}

I also think that you want to make a dynamic decision based on the value of the name attribute of each element of this list.

However, I don’t yet understand what result you intend to produce. In particular, I don’t understand what “a1”, “a2”, “a3”, and “a4” represent in your example.


As a partial answer to your question, I can share a pattern for selecting a value based on a string. You can achieve that by declaring a local value that is a mapping to be used as a lookup table:

locals {
  server_name_something = {
    "PhysicalVM" = "result-1"
    "CloudVM"    = "result-2"
  }

  servers_with_something = tolist([
    for s in var.serverlist : {
      name      = s.name
      value     = s.value
      something = local.server_name_something[s.name]
    }
  ])
}

The server_name_something local value gives a different result for each possible name value. servers_with_something then builds a new list based on the given list which adds the additional attribute something which has the result of consulting the lookup table.

With the input value you showed in your question, local.servers_with_something would have the following value:

[
  {"name": "PhysicalVM", "value": "Server1", "something": "result-1"},
  {"name": "CloudVM", "value": "CServer1", "something": "result-2"},
  {"name": "PhysicalVM", "value": "Server2", "something": "result-1"},
  {"name": "PhysicalVM", "value": "Server3", "something": "result-1"},
]

Hopefully this example gives you some ideas for what to try next. If this isn’t a sufficient answer then please tell me more about your goal and I will try again.

Thanks!

Thanks for the hint and I would like to add detail to the question I posted… Below is the resource creation

https://registry.terraform.io/providers/aquasecurity/aquasec/latest/docs/resources/application_scope

In above, expression value for each loop is dynamic based on the user input hence if user supplies value of “PhysicalVM”, expression will include "&&" or if it is “CloudVM” then expression will include " || "

I hope this clears the understanding right now on the expression usage

Thank you for that extra context. The part I didn’t understand before is that these boolean expressions are really just strings from Terraform’s perspective, and so they’ll be finally evaluated in the remote system rather than in Terraform. The coincidental similarity with Terraform’s own logical operators made this confusing.

I think the pattern I described in my previous reply should be suitable for this situation then: the lookup table would have "&&" instead of "result-1" and "||" instead of "result-2", and then you can rename the local values and attributes to have a more useful name then just “something” which I was using as a placeholder. I suppose “operator” could be a reasonable word to describe what this lookup table is selecting.

@apparentlymart Thanks for the suggestion however the lookup table is now correctly populated but I still miss the iteration of the values

[
{“name”: “PhysicalVM”, “value”: “Server1”, “something”: “||”},
{“name”: “CloudVM”, “value”: “CServer1”, “something”: “&&”},
{“name”: “PhysicalVM”, “value”: “Server2”, “something”: “||”},
{“name”: “PhysicalVM”, “value”: “Server3”, “something”: “||”},
]

How will I concat the something now with the iterated list to get my expression as “a1 && a2 || a3 || a4” ?

Thanks

I figured it out with joins and formatlist to do the trick… It is working fine… Thanks for giving your inputs @apparentlymart … It was really helpful