1
votes

I'm struggling with this interpolation, I have variables below like.

primary = ["foo.dev","all.bar.com"]
secondary = ["module.foo.dev","*.foo.dev","all.bar.com"]

I want my output to be

{
     "foo.dev" = ["module.foo.dev","*foo.dev"]
     "all.bar.com" = ["all.bar.com"]
}

Using Terraform 0.12.20

I tried in terraform console , I'm not able to achieve my desired output. Is there any easy solution?

[for i in ["foo.dev","all.bar.com"]: map(i,[for j in ["module.foo.dev","*foo.dev","all.bar.com"]: replace(j,i,"")!=j == true ? j : 0])]
[
  {
    "foo.dev" = [
      "module.foo.dev",
      "*foo.dev",
      "0",
    ]
  },
  {
    "all.bar.com" = [
      "0",
      "0",
      "all.bar.com",
    ]
  },
]
1
Can you explain the logic for that association ... and why not provide the correct map from the beginning ?Helder Sepulveda

1 Answers

1
votes

You can do this with the following expression:

{ for i in ["foo.dev", "all.bar.com"] : i => [for j in ["module.foo.dev", "*foo.dev", "all.bar.com"] : j if can(regex(i, j))] }

This results in the following value:

{
  "all.bar.com" = [
    "all.bar.com",
  ]
  "foo.dev" = [
    "module.foo.dev",
    "*foo.dev",
  ]
}

which is exactly what you requested.

The iterative explanation follows:

First, specify the type is a map:

{}

Now, we should iterate over the elements in the first list:

{ for i in ["foo.dev", "all.bar.com"] : }

Next, we assign the i value to the key of the map, and initialize a list for the value:

{ for i in ["foo.dev", "all.bar.com"] : i => [] }

However, we need to assign the values from the elements in the second list to the list for the key of the resulting map (the below example is sub-optimal because we do not need a for expression, but it is illustrative for the next step):

{ for i in ["foo.dev", "all.bar.com"] : i => [for j in ["module.foo.dev", "*foo.dev", "all.bar.com"] : j] }

Finally, we want to filter the elements in the list value based on the key. We can use the can function outside the regex function to return a boolean based on whether there is a match. We use this for the conditional on whether the element of the second list should be added to the list in the value:

{ for i in ["foo.dev", "all.bar.com"] : i => [for j in ["module.foo.dev", "*foo.dev", "all.bar.com"] : j if can(regex(i, j))] }

and we have arrived at the solution.