terraform --var-file "vars.json" will only read first submap in a nested map.

Created on 5 Oct 2016  ยท  6Comments  ยท  Source: hashicorp/terraform

Terraform Version

0.7.4

Affected Resource(s)

maps and var files.

Terraform Configuration Files

main.tf:

variable "map" {
  type = "map"

  default = {
    regiona = {
      amia = "main.tf"
      amib = "main.tf"
    }

    regionb = {
      amia = "main.tf"
      amib = "main.tf"
    }
  }
}

output "map" {
  value = "${var.map}"
}

vars.json:

{
    "map": {
        "regiona": {
            "amia": "vars.json",
            "amib": "vars.json"
        },
        "regionb": {
            "amia": "vars.json"
        },
        "regionc": {
            "amia": "vars.json",
            "amib": "vars.json"
        }
    }
}

Expected Behavior

Terraform should have merged the map from main.tf with the map and all of it's submaps declared in vars.json.

map = {
  regiona = [map[amia:vars.json amib:vars.json]]
  regionb = [map[amia:vars.json amib:maint.tf]]
  regionc = [map[amia:vars.json amib:vars.json]]
}

Actual Behavior

Terraform merges only the first submap from vars.json (map.regiona) and ignores any other maps (map.regionb, map.regionc). The first submap depends on the order they are declared in vars.json.

map = {
  regiona = [map[amia:vars.json amib:vars.json]]
  regionb = [map[amia:main.tf amib:maint.tf]]
}

Note that regiona was successfully overwritten, the change to regionb was not made, and regionc is completely missing.

Steps to Reproduce

terraform apply -var-file vars.json outputs the following:

Important Factoids

Nested maps work fine if declared in hcl, ie if regionc is moved from vars.json to main.tf this would work and is our current workaround.

bug config

Most helpful comment

@jbardin can you provide a working example for 2 or more variables declared in a json -var-file=?

I can get terraform to accept one json var value in a -var-file.

It's when I ask terraform to accept 2 (or more) variable declarations in a -var-file (v0.8.4),
it fails with the same message, but I'm not passing a map, just two simple variable = "string" values.

invalid value "vars.json" for flag -var-file: multiple map declarations not supported for variables

I'm wondering if it's my json formatting or?

All 6 comments

Just an update, but this will now print an error in this case:

invalid value "vars.json" for flag -var-file: multiple map declarations not supported for variables

Because of the internal structure of HCL, the "correct" format for the JSON is actually:

{
    "map": [
        {
            "regiona": [
                {
                    "amia": "vars.a.a",
                    "amib": "vars.b.b"
                }
            ],
            "regionb": [
                {
                    "amia": "vars.b.a"
                }
            ]
        }
    ]
}

Not this isn't very intuitive, and we usually do try to accept the more condensed JSON as input, so I'll keep this open to try and fix that issue (as well as the less than helpful error message we now get).

@jbardin

list of objects won't work, either. I assume it's the same issue.
May I ask for a workaround for this? I tried with the structure above but no luck.

variable "map" {
  type = "list"

  default = [
    {
      amia = "main.tf"
      amib = "main.tf"
    },
    {
      amia = "main.tf"
      amib = "main.tf"
    }
  ]
}

output "map" {
  value = "${var.map}"
}

json file

{
    "map": [
        {
            "amia": "vars.json",
            "amib": "vars.json"
        },   
        {
            "amia": "vars.json"
        }
    ]
}

expected

map = [
    {
        amia = main.tf,
        amib = main.tf
    },
    {
        amia = main.tf,
        amib = main.tf
    }
]

Actual

multiple map declarations not supported for variables

@beelit94,

Sorry, I missed that you had a list type rather than a map.

I think this is another edge case without a workaround at the moment. Fixing JSON input is something we're going to be working on soon.

@jbardin can you provide a working example for 2 or more variables declared in a json -var-file=?

I can get terraform to accept one json var value in a -var-file.

It's when I ask terraform to accept 2 (or more) variable declarations in a -var-file (v0.8.4),
it fails with the same message, but I'm not passing a map, just two simple variable = "string" values.

invalid value "vars.json" for flag -var-file: multiple map declarations not supported for variables

I'm wondering if it's my json formatting or?

Hi all,

I just verified this in v0.12.0-alpha2 using the same files as given (with the minor adjustment of specifying a more precise type (`map(map(string))`` for the variable to work around #19141):

$ terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

map = {
  "regiona" = {
    "amia" = "main.tf"
    "amib" = "main.tf"
  }
  "regionb" = {
    "amia" = "main.tf"
    "amib" = "main.tf"
  }
}
$ terraform apply -var-file vars.tfvars.json

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

map = {
  "regiona" = {
    "amia" = "vars.json"
    "amib" = "vars.json"
  }
  "regionb" = {
    "amia" = "vars.json"
  }
  "regionc" = {
    "amia" = "vars.json"
    "amib" = "vars.json"
  }
}

The fix here comes from the switch to the new JSON parser implementation that is also now used for .tf files. This fix is already in master and ready to be included in the forthcoming v0.12.0 final release, and so I'm going to close this issue.

Sorry for the weird behavior, and for the long delay in getting it fixed.

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings