How to process tuples from file (or remote state)

I have seen posts outlining how to create a map from a list of tuples, but it only seems to work if that is defined in a var or local. If I read that same structure from a file (or from remote state) then the plan errors out before even attempting to read the data.

If I set up locals like so:

locals {
   envs = ["dev", "qa"]
   svcmap = {
      "dev" : {
        "myservice" : {
          "acceptance_required" : false,
          "state" : "Available",
          "tags" : {
            "Environment" : "dev",
          },
        }
      },
      "qa" : {}
    }
    service_map = {
       for e in local.envs : e => local.svcmap[e]
    }
    services = merge([
      for env, map in local.service_map : {
         for svc, obj in map : "${env}-${svc}" => obj
       } if map != {}
    ]...)
}

the code works fine and I end up with the mapping I desire:

> local.services
{
  "dev-myservice" = {
    "acceptance_required" = false
    "state" = "Available"
    "tags" = {
      "Environment" = "dev"
    }
  }
}

however if I want to read that same structure from a file I get an error before it even reads the data:

> Error: Invalid expanding argument value

  on /home/user/test-terraform/test.tf line 20, in locals:
  20:   services = merge([
  21:     for env, map in local.service_map : {
  22:       for svc, obj in map : "${env}-${svc}" => obj
  23:     } if map != {}
  24:   ]...)
    |----------------
    | local.service_map is object with 2 attributes

The expanding argument (indicated by ...) must be of a tuple, list, or set
type.

I think it’s because it doesn’t know the structure of the data before reading it, but shouldn’t my merge([ ... { ... } ... ]) call tell it that it will be receiving a list?

When you say reading it from a file, how are you doing that? Using a .tfvars file?

Using a local_file data source (JSON):

locals {
  svcmap = jsondecode(data.local_file.svc-map.content)
}

The merge call is the same, just a different source.

data "local_file" "svc-map" {
  filename = "${path.module}/svc-map.json"
}