Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with terraform, why does the double quotes get ignored when trying to plan a particular resource

I am trying to run a terraform plan command targetting a particular module, created using for each . Here is the sample command to do terraform plan

terraform plan -target=module.virtualmachinescaleset.azurerm_linux_virtual_machine_scale_set.this["x"]

and i keep on getting the below error Index brackets must contain either a literal number or a literal string

like image 646
ch shaik Avatar asked Sep 12 '25 08:09

ch shaik


1 Answers

When you type a command at a shell prompt the command is first parsed by the shell itself in order to determine what arguments you passed (which might depend on evaluating environment variables, for example) and then the shell passes an array of arguments to the program you ran.

You didn't mention which shell you use, but the typical convention for Unix shells is that the quote character " marks the start and end of a range of characters where space characters do not represent the separation between two arguments. Without the quotes, spaces serve as markers for where the arguments are separated.

Even though there are no spaces inside your quotes, the shell still treats them as special and so it removes them as part of its processing, causing the array of arguments parsed to Terraform to be like this (one line per argument, all taken totally literally by Terraform):

terraform
plan
-target=module.virtualmachinescaleset.azurerm_linux_virtual_machine_scale_set.this[x]

Since the shell removed the quotes as part of its work, Terraform then finds that the characters after -target= are not a valid resource instance address, because in that position it expects either a decimal number (for resources with count) or a quoted string (for resources with for_each).

Given this, what we need to do is tell the shell that it should take the entire resource instance address literally, without any special interpretation such as replacing environment variables or removing quotes. The usual syntax for that in Unix shells is the single quote ', which is like a stronger version of the double quote " that also disables the interpretation of special characters, in addition to taking spaces literally:

terraform plan -target='module.virtualmachinescaleset.azurerm_linux_virtual_machine_scale_set.this["x"]'

When the shell scans across the characters in this command line, the first ' will cause the shell to switch into literal mode (and the shell discards the literal '), so it will take everything else literally until it finds the second ' which returns the shell to normal parsing mode again.

The result this time is therefore what Terraform is expecting:

terraform
plan
-target=module.virtualmachinescaleset.azurerm_linux_virtual_machine_scale_set.this["x"]

The one remaining caveat to note is what to do in the rarer situation where your instance key contains a literal ' character itself. Since that is the one character that the shell treats as special inside ' we would still need to escape that in a special way, which we can do by ending the literal sequence with ', then including a literal quote mark by using the \ escape character, and then re-opening a new literal sequence with another ' giving the rather messy sequence '\'' 😬, which is easier to see in a fuller example:

terraform plan -target='module.virtualmachinescaleset.azurerm_linux_virtual_machine_scale_set.this["it'\''s annoying to deal with single quotes"]'

Thankfully this doesn't arise often and so I'm mentioning it only for completeness. Most of the time, it's sufficient to just place the address in single quotes '.


(Note for future readers: the above is true for standard shells on Unix-style systems, like Linux and macOS, but it is it not true for Windows which has its own different rules for handling command line arguments. It takes a different strategy to escape quote marks when typing a command prompt on Windows.)

like image 117
Martin Atkins Avatar answered Sep 13 '25 22:09

Martin Atkins