hashicorp-community / tf-helper

Commands for performing operations on Terraform states, configurations, TFE using the API, and more. Please target all PRs to the master branch, not the release branch.
Mozilla Public License 2.0
101 stars 32 forks source link

whitespace in variable names and contents #11

Closed jeremygaither closed 4 years ago

jeremygaither commented 4 years ago

When using var-file-like syntax on the command line, such as tfh pushvars -var 'foo = bar' -overwrite foo, tf-helper correctly splits the var argument at the equal symbol, but does not strip white space on either side. This results in no matches found when comparing for existing variables, and the following error:

[DEBUG] Processing REDACTED  type:terraform hcl:false sensitive:false value: REDACTED
[DEBUG] REDACTED  not in variable listing
Creating REDACTED  type:terraform hcl:false sensitive:false value: REDACTED
...
[DEBUG] API request http code: 422. Response:
{"errors":[{"status":"422","title":"Invalid Attribute","detail":"Key has already been taken","source":{"pointer":"/data/attributes/key"}}]}
[ERROR] API request failed.
HTTP status code: 422
JSON-API details:
  detail: Key has already been taken
  source:
    pointer: /data/attributes/key
  status: 422
  title: Invalid Attribute

The command syntax tfh pushvars -var foo='bar' -overwrite foo works as expected for the same variables and values.

Seen in tfh 0.2.7

fprimex commented 4 years ago

'lo. Getting back to work on tfh after medical leave.

I've fixed this up so that it's a bit more friendly, but please note that foo = bar won't work for terraform -var either:

# main.tf
variable "foo" {}
output "o" { value = var.foo }
$ terraform apply -var 'foo=bar'

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

Outputs:

o = bar

$ terraform apply -var 'foo = bar'
var.foo
  Enter a value: 
^C

Other invocations are similar - foo =bar, foo= bar, etc.

In the documentation it states:

Variable values are interpreted as HCL

But this isn't actually true, because foo = bar isn't valid HCL2 for a Terraform string assignment, either in .tf or .tfvars files. So there is a concession at the shell quote handling level; an assumption that things coming in are strings unless they're something else. This can be seen by passing a number in for a variable that doesn't specify a type:

variable "foo" { }
output "o" { value = list(var.foo) }
$ terraform apply -var 'foo=10'

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

Outputs:

o = [
  "10",
]

There is no way to pass a number that I can figure out other than to specify the type of the variable:

variable "foo" { type = number }
output "o" { value = list(var.foo) }
$ terraform apply -var 'foo=10'

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

Outputs:

o = [
  10,
]

What I have done is just strip spaces, tabs, and newlines (POXIS IFS) around the =; foo = bar works to assign bar to foo. It doesn't match terraform behavior, but it does make it actually closer to the documentation. Because of automatic type conversion, if 10 gets stored as "10", it won't actually matter when it gets used for a computation or assignment.

I've had to be extremely careful with the sequence that strips, because you have to be careful not to trigger the interpretation of escape codes that might be in the value (\n, etc), so no echo "$val" | something_that_trims.

$ tfh pushvars -delete foo
Deleting foo type:terraform hcl:false sensitive:false value:bar

$ tfh pullvars

$ tfh pushvars -var ' foo  =   bar   ' -overwrite foo
Creating foo type:terraform hcl:false sensitive:false value:bar

$ tfh pullvars
foo = "bar"

$ tfh pushvars -var ' foo  =   baz   ' -overwrite foo
Updating foo type:terraform hcl:false sensitive:false value:baz

$ tfh pullvars
foo = "baz"

Note that with this change it is not possible to assign a variable using pushvars that has spaces either at the start or end. They will always be trimmed.

This is in master now. Feel free to test!