Cannot pass in variable for list type

I am using terraform 1.0.0.
simple terraform file
provider “azurerm” {

features {}

}

variable “image_id_list” {

type = list(string)

default = [“blah”]

}

output “tenantid” {

value = var.image_id_list[0]

}

I run terraform plan (or apply), I get in my output, ‘blah’.
try to override on commandline
terraform apply -var=‘image_id_list=[“ami-abc123”]’


│ Error: Variables not allowed

│ on line 1:
│ (source code not available)

│ Variables may not be used here.

was really trying to pass in an azure tenant id, but it failed, so I simplified.
same error. I cannot override the default value.
I even renamed the variable to that which is in terraform documentation, and copied in the command (thinking, am I messing it up?). nope. error.

oh, this is all in powershell. I noticed if I flip to bash, it works.
/mnt/c/terraform/terraform.exe plan -var=‘image_id_list=[“ami-abc123”,“ami-def456”]’

Changes to Outputs:

  • tenantid = “ami-abc123”

You can apply this plan to save these new output values to the Terraform state, without changing any real
infrastructure.
Problem is, I don’t want to flip to bash. it should work for both.

Hi @marc-gmail-towersap,

Unfortunately running tools like Terraform with PowerShell is a bit miserable because PowerShell’s behavior is to first parse the command line itself, then to notice that what you’ve specified is an external program rather than a PowerShell cmdlet, and then to try to reassemble the command line again based on its own parse tree, often removing or escaping or otherwise changing the quotes and other metacharacters in your original command line along the way. By the time the command reaches Terraform it no longer matches what you originally typed, and so Terraform ends up returning a parse error that makes no sense, as you saw here.

This is a design problem in PowerShell and not something Terraform is equipped to solve, because PowerShell corrupts the arguments string before Terraform is even running. :confounded: In order to make it work with PowerShell you’ll need to figure out what sort of escaping to use to force PowerShell to pass the same punctuation you typed, which is the subject of various lengthy blog posts and other answers, including one on the MSDN “DrScripto” blog.

Another trick I learned from someone else trying to use PowerShell to run Terraform was the special sequence --% which I believe (if I recall correctly) tells PowerShell to pass the rest of the command line literally to the external program. That might mean that for your situation you could get away with something like this, but I don’t have PowerShell to test with:

terraform --% plan -var=image_id_list=["ami-abc123","ami-def456"]

(I’m not sure how the --% mechanism deals with quotes in the arguments that follow; it might still need some further escaping, but I’d need to refer you to the PowerShell documentation for information on that, unfortunately.)

thank you for this description!

I wish though, that the documentation would mention this to help others who stumble into this issue and waste their time in a futile effort. AFAIK, it’s the list type. I did not try the map type, maybe it also has issues, dunno!

FYI, I haven’t yet been able to get powershell to work.
Tried the --% to stop parsing, but it didn’t work with var=‘name=[“value”]’, it complains about missing a variable named 'name
tried removing the single quotes, nope! tried various permutations of using backtic’s to escape the [, ", and ', but nope! Fortunately, if you installed the unix extension to windows, you can just flip to bash, it still creates the resource, remembering your azure tenant and subscription set in powershell. Not sure how i’m going to do this in an azure devops release pipeline though. but flipping to bash works straight on my commandline.

haha, saw someone didn’t use the --%, but instead, used three doublequotes instead of one.
-var ‘aad_allowed_tenants=[""“my azure tenant id”""]’
those are single quotes on the outside, and three doublequotes instead of one surrounding the text you want to pass into your list.

It should also work to run Terraform from the Windows Command Prompt (cmd.exe), which avoids PowerShell’s problems because its own syntax doesn’t typically conflict with the syntax of the command you are trying to run… it uses rarer characters that are less likely to conflict, and uses ^ as its escape character, and only reserves a few special characters like |, >, and < for I/O redirection.

I’m glad you found better success with Bash, though on Windows I expect there will be some situations where Bash is also problematic. The fundamental problem here is that on Unix the convention is that the shell parses the command line, whereas on Windows the convention is that the target program parses the command line. Therefore if you use any shell that does its own parsing (the Unix way) on Windows then it will inevitably need to somehow try to rebuild the command line back to the original string you typed, which will always have edge-cases.

The Windows Command Prompt would be my recommendation for low-friction use of various command line programs on Windows, because it’s built to be compatible with the Windows API assumption that applications parse their own command line arguments, rather than trying to pretend it’s running on Unix.