Error in using string list variable in Terraform Cloud

I have a simple project that creates DigitalOcean droplets. As part of the droplet creation, I need to inject a list of SSH key fingerprints to the authorized keys list.
When I add these as Terraform Variables in the UI

The resulting run fails with the following error.

Terraform v0.12.23
Configuring remote state backend...
Initializing Terraform configuration...
2020/03/09 15:09:44 [DEBUG] Using modified User-Agent: Terraform/0.12.23 TFC/896fd11ba6

Error: Invalid value for input variable

  on /terraform/terraform/terraform.tfvars line 4:
   4: ssh_fingerprints = "[\"fingerprint_1\", \"fingerprint_2\"]"

The given value is not valid for variable "ssh_fingerprints": list of string
required.

But, if I change the variable definition to be parsed as HCL, then it works.

Why would using ["fingerprint_1", "fingerprint_2"] as is not work?

1 Like

Hi @HanSooloo,

When the “HCL” checkbox is not checked, Terraform Cloud interprets the contents of the “Value” box as a static string value, not as an HCL expression. We can see in the error message there that indeed Terraform cloud has wrapped the exact string you entered in quotes and escaped the quotes inside, causing Terraform Core to interpret it as a string that happens to contain brackets and quote marks.

Marking it as HCL causes Terraform Cloud to pass the value to Terraform Core as a general expression, which means you can then produce values of types other than string.

3 Likes

I’m hitting a similar problem. I understand your reply and using terraform variables it does work if set to HCL. However, if you are trying to use the environment variable option there is no “hcl” toggle so you can only pass strings and those strings are escaped resulting in an error for list of strings.

Reading the documentation on environment variables it shows you can pass lists of strings by single quoting the content

export TF_VAR_availability_zone_names=‘[“us-west-1b”,“us-west-1d”]’

but in Cloud manually adding a value results in the single quotes being removed and then the whole string becoming escaped when passed to the terraform plan resulting in error and if you try to set the variable through the tfe_variable resource single quotes get flagged as not supported???

There seems to be a bit of inconsistency across implementation versions (local and cloud) and the documentation.

Another irritation is the recommendation to use TF_VAR_ environment variables in cloud to avoid the warning in plans for variables in global variable sets not being configured in a particular workspace yet for the problem above the solution is to use the terraform variables not the environment variables option.

It’s becoming a bit messy.

The best option would be to allow single quotes around the complex variable types in cloud environment variables - this would bring everything into alignment.

Cheers
Phill

Hi @philip.lewis,

Since the environment variables UI is for setting system environment variables in the OS where Terraform is running, rather than for directly passing values to Terraform, there isn’t any sense of an environment variable being in HCL syntax.

Mechanically what’s happening for the Terraform Variables you set is that Terraform Cloud is generating a terraform.tfvars file automatically before running Terraform CLI, and the “HCL” checkbox tells it to just insert the given expression directly rather than writing it in quotes to force treatment as a string.

There is no comparable file generated for environment variables, because Terraform Cloud in that case can just directly populate the environment variable table for the child process when it runs Terraform CLI. There is no escaping or quoting at all in that case because environment variables are always just plain string values from the OS perspective.

I think what you might be seeing is that Terraform CLI itself is the one parsing the TF_VAR_ environment variables and so the usual Terraform CLI rules are what matter in that case: Terraform CLI decides how to parse the environment variable for an input variable based on the type constraint for that input variable as declared in the configuration. If it’s a primitive type (string, bool, number) it will expect a raw string value and will then try to convert it to the target type using the a same rules as the functions like tonumber. But for any complex type like a list it will parse the environment variable string as an HCL expression. So in that case the decision for how to parse it belongs to the root module’s declarations rather than to Terraform Cloud workspace settings.

I’m not sure exactly what is happening in your case but I would suggest making sure your input variable is declared as being a list inside your root module, which should then cause Terraform CLI to parse it as HCL as you intended.

If that isn’t the problem then I’d recommend contacting HashiCorp support because they can (with your permission) look more closely at how you have things set up and so may spot a problem I’m not thinking to ask about.

Yep this is how it works if you have terraform locally installed and set, for example, a TF_VAR variable with a list of strings but in terraform cloud if you set an environment variable TF_VAR_= [“thing1”, “thing2”] Then instead of seeing this as a HCL expression it just escapes the string and errors out because the escaped string does not match the type <type = list(string)> in the variable declaration.

This is where I saw the mention of using TF_VARS as being the recommended approach for global/shared values.

(https://github.com/hashicorp/terraform/issues/22004#issuecomment-509356006)

Hi @philip.lewis,

I believe you that something strange is going on here but I cannot explain why it is behaving that way for you. What you tried here is supposed to work and so it seems that something odd is happening but it isn’t something I’ll be able to help to debug here because I imagine it’s something pretty specific to your current workspace configuration.

If you contact HashiCorp Support then they can hopefully work with you to narrow down the cause and, if it turns out to be a bug in Terraform Cloud, send that information to the Terraform Cloud engineering teams to investigate and fix.

Thanks for discussing this @apparentlymart I’ll ping the support people a request and see what they say.

Cheers