Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config a list variable in the input file,but got a error: network:should be a list #18723

Closed
SecurityNeo opened this issue Aug 22, 2018 · 2 comments

Comments

@SecurityNeo
Copy link

Terraform Version

Terraform v0.11.7

Terraform Configuration Files

input.tf.json:

{
  "variable" : {
    "network" : {
      "description" : "balabala",
      "default": [{"name":"net1","fixed_ip_v4":"10.10.10.2"},{"name":"net2","fixed_ip_v4":"10.10.20.2"}]
    }
  }
}

main.tf.json:

...
"resource" : {
  "openstack_compute_instance_v2" : {
    "testserver" : {
       ...
       "network" : "${var.network}"
       ...
      }
  }
}
...

In the debug output,I got an error like this:
root: eval: *terraform.EvalValidateResource, err: Varnings: [].Errors: [network: should be a list]

@apparentlymart
Copy link
Contributor

Hi @SecurityNeo! Sorry this didn't work as expected.

It looks like what you encountered here is a JSON-syntax variant of the same limitation discussed in #7034: network is a fixed child block of openstack_compute_instance_v2, rather than an attribute, and so arbitrary expressions cannot be assigned to it. Instead, Terraform expects this block to be specified statically in configuration.

As discussed in #7034, there is a planned solution for this coming in the forthcoming 0.12 release, which is the primary focus of the Terraform Core team at this time.

As usual, the formatting of this in JSON is a little more awkward than in Terraform's own native syntax, but here is how a JSON transliteration of the forthcoming dynamic block type would look:

"resource": {
  "openstack_compute_instance_v2": {
    "testserver": {
       ...
       "dynamic": {
          "network" : {
             "for_each": "${var.network}",
             "content": {
                "name": "${network.name}",
                "fixed_ip_v4": "${network.fixed_ip_v4}"
             }
          }
       },
       ...
      }
  }
}

Although the JSON syntax obscures this distinction by representing everything as JSON objects, Terraform distinguishes attributes values from child blocks because that allows Terraform to properly validate the structure statically (before evaluating anything) and thus avoid surprising misbehavior at apply time. In that way, the attribute names and nested blocks are more like a struct in a statically-typed programming language than a list/map data structure.

Since this new capability is already covered by #7034, I'm going to close this one just to consolidate the discussion over there. Thanks!

@ghost
Copy link

ghost commented Apr 2, 2020

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.

@ghost ghost locked and limited conversation to collaborators Apr 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants