Search code examples
terraformterraform-provider-awshcl

terraform json map regex lookup and using loops properly


So I have a json file below I can definitely restructure it as needed, but its what I started with. It needs to be an external format of terraform of any type. I chose json based on seemingly easy compatability.

I would like to be able to loop through all the regex patterns in the json file below (I truncated this list) and if the regex pattern is a match to testcomputer, then return the ou value to another local variable. One caveat, that I am not sure if I am having an issue with, is that the json requires escaping the \ . In an imperative programming language I just handled this with a switch/case stanza or method that performs evaluations. Not sure how to best do this with HCL.

ou.json:

{
  "ProdInf": {
    "regex": "/^(?i)nyinf-p(\\d+)/",
    "ou": "OU=Inf,OU=Prod,OU=Servers,DC=example,DC=local"
  },
  "ProdHyperV": {
    "regex": "/^(?i)nyhyp-p(\\d+)/",
    "ou": "OU=HyperV,OU=Prod,OU=Servers,DC=example,DC=local"
  },
  "ProdRDS": {
    "regex": "/^(?i)nyrds-p(\\d+)/",
    "ou": "OU=RDS,OU=Prod,OU=Servers,DC=example,DC=local"
  }
}

I have some initial terraform code (contrived and based on my real issue) but it I can't figure out how to proceed from here.:

locals {
  testcomputer = "nyhyp-p29"
  map1 = jsondecode(file("./ou.json"))
  # started to play with loops here, but not really sure how to do what I am want.
  oulist = [for ou in local.map1 : ou].*.ou
  regexlist = [for regex in local.map1 : regex].*.regex
  test_computer_ou = # this is the desired value I am trying to get
}

Solution

  • You would want to modify your json file to look something like this:

    {
        "ProdInf": {
            "regex": "^(?i)nyinf-p(\\d+)$",
            "ou": "OU=Inf,OU=Prod,OU=Servers,DC=example,DC=local"
        },
        "ProdHyperV": {
            "regex": "^(?i)nyhyp-p(\\d+)$",
            "ou": "OU=HyperV,OU=Prod,OU=Servers,DC=example,DC=local"
        },
        "ProdRDS": {
            "regex": "^(?i)nyrds-p(\\d+)$",
            "ou": "OU=RDS,OU=Prod,OU=Servers,DC=example,DC=local"
        }
    }
    

    From your question I understood that you are looking for a full match, so I've added regex anchors.

    The local variables are the following:

    locals {
      testcomputer = "nyhyp-p29"
      map1 = jsondecode(file("./ou.json"))
      oulist = [for ou in local.map1 : ou].*.ou
      regexlist = [for regex in local.map1 : regex].*.regex
      test_computer_ou = [for key, value in local.map1: value.ou if length(regexall(value.regex, local.testcomputer)) == 1]
    }
    

    The value for test_computer_ou will be:

    output "test_computer_ou" {
      value = local.test_computer_ou
    }
    

    Output value:

    test_computer_ou = [
      "OU=HyperV,OU=Prod,OU=Servers,DC=example,DC=local",
    ]