Search code examples
jsonterraform

Trying to parse json input file through terraform


I am very new to terraform and trying to understand it. I am trying to parse a sample json file and trying to display the key and values. I have done the below so far, but it is not working. Any help is appreciated.

example.json:

{
    "Clients":[
        {
            "alias": "XXX-ED",
            "name": "XXX-ED | XXX Cloud | Dev/Test",
            "prefix": "xxxed",
            "id": 12345,
            "cluster": 3,
            "ZoneName": "East US 2",
            "EnvironmentName": "Dev/Test",
            "AzureSubscriptionID": "xxxxxx-xxxx-xxxxx-xxxx-xxxxxx",
            "AzureDirectory": "xxxxxx.onmicrosoft.com",
            "AzureTenantID": "xxxxxx-xxxx-xxxxx-xxxx-xxxxxx"
        },
        {
            "alias": "XXX-EM",
            "name": "XXX-EM | XXX Cloud | Management",
            "prefix": "xxxem",
            "id": null,
            "cluster": null,
            "ZoneName": "East US 2",
            "EnvironmentName": "Management",
            "AzureSubscriptionID": "xxxxxx-xxxx-xxxxx-xxxx-xxxxxx",
            "AzureDirectory": "xxxxxx.onmicrosoft.com",
            "AzureTenantID": "xxxxxx-xxxx-xxxxx-xxxx-xxxxxx"
        }
    ]
}

terraform code

data "local_file" "input"{
  filename = "${path.module}/example.json"
}

locals {
  raw_json_object = jsondecode(data.local_file.input.content)
  root_node       = flatten(local.raw_json_object["Clients"])
  
  expected_output = [
    for clients in local.root_node :[
      for key in clients:
        key.AzureDirectory
      ]
    ]
  }
}

output "raw_content" {
  value = local.expected_output
}

Getting below error

Planning failed. Terraform encountered an error while generating this plan. Error: Unsupported attribute on main.tf line 38, in locals: 38: key.AzureDirectory Can't access attributes on a primitive-typed value (string).


Solution

  • Testing this locally shows you can achieve what you want without having to reference the keys, so this should work:

    locals {
      raw_json_object = jsondecode(data.local_file.input.content)
      root_node       = flatten(local.raw_json_object["Clients"])
      expected_output = [for client in local.root_node : client.AzureDirectory]
    }
    
    output "raw_content" {
      value = local.expected_output
    }
    

    Which outputs:

    local.expected_output
    [
      "xxxxxx.onmicrosoft.com",
      "xxxxxx.onmicrosoft.com",
    ]
    

    The flattened root_node local variable is a list of maps, which means that you need to access each element of a list (i.e, client) and then each of those elements has a key called AzureDirectory. In other words, you need only to loop through the list once, and access the wanted key of each element in the list.

    As a side note, when using the local variables, you can test also using the terraform console command instead of outputs.