Terraform: variable type inference error

Created on 24 Jul 2017  ยท  7Comments  ยท  Source: hashicorp/terraform

Variable values passed to plan/apply via the -var flag are interpreted as empty strings when they match a specific pattern. the values appear to be treated as hex, despite the fact that the variable is defined as type = "string".

Examples of inputs that result in an empty value:

  • -var version=16e8195
  • -var version=2a68195

Examples of inputs that render correctly:

  • -var version=0x16e8195
  • -var version=168e195
  • -var version=16g8195
  • -var version=168195

Specifically, it seems that when an alpha character a-f appears as the 2nd or 3rd character in a string containing only numeric characters, the value fails to render. When these same values are passed via a -var-file, all values are rendered correctly.

Terraform Version

v0.9.11

OS

  • macOS 10.12.5
  • Ubuntu - trusty

Example

Failure case:

resource "aws_security_group" "default" {
  name        = "fakename"
  description = "${var.version}"
}

terraform plan -var version='16e8195'

+ aws_security_group.default
    egress.#:  "<computed>"
    ingress.#: "<computed>"
    name:      "fakename"
    owner_id:  "<computed>"
    vpc_id:    "<computed>"
  • description is a missing because the value was blank or invalid

Successful case:

resource "aws_security_group" "default" {
  name        = "fakename"
  description = "${var.version}"
}

terraform plan -var version='16z8195'

+ aws_security_group.default
    description: "16z8195"
    egress.#:    "<computed>"
    ingress.#:   "<computed>"
    name:        "fakename"
    owner_id:    "<computed>"
    vpc_id:      "<computed>"
  • description is present with the expected value
bug cli config

Most helpful comment

Hi again @davemeyer!

I'm pleased to report that as expected this strange bug seems to be gone in v0.12.0-alpha1. The variable processing code was rewritten along with the rest of the language interpreter in this release, so whatever codepath was causing the strange type inference is no longer being used.

I tweaked your example slightly because in v0.12.0-alpha1 the variable name "version" is reserved due to its conflict with a meta-argument in module blocks:

variable "desc" {
}

resource "aws_security_group" "default" {
  name        = "fakename"
  description = var.desc
}

Now I can terraform plan with the value that was previously coming through as empty:

$ terraform plan -var desc='16e8195'
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.default will be created
  + resource "aws_security_group" "default" {
      + arn                    = (known after apply)
      + description            = "16e8195"
      + id                     = (known after apply)
      + name                   = "fakename"
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + vpc_id                 = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

The new plan rendering layout makes this quite different than what you originally shared, but most important is the value "16e8195" showing up for the description argument.

Since this fix is already in master, I'm going to close this out. The fix will also be included in the final v0.12.0 release. Thanks for reporting this, and for your patience while we worked through all the groundwork to fix it.

All 7 comments

Hi @davemeyer! Sorry this is acting strange.

In your "failure case" your plan output seems to be for some other resource, rather than for aws_security_group.default. Could you please update the issue text to show what the default security group's plan looks like in that case? Thanks!

sorry about that.. updated now

fyi, i added the failure case to the kv unit test, and it seems to pass.

$ go test github.com/hashicorp/terraform/command            
ok      github.com/hashicorp/terraform/command  11.014s

$  gd                           
diff --git a/command/flag_kv_test.go b/command/flag_kv_test.go
index 0f39211..2400fe9 100644
--- a/command/flag_kv_test.go
+++ b/command/flag_kv_test.go
@@ -23,6 +23,12 @@ func TestFlagStringKV(t *testing.T) {
                },

                {
+                       "key=16e8195",
+                       map[string]string{"key": "16e8195"},
+                       false,
+               },
+
+               {
                        "key=",
                        map[string]string{"key": ""},
                        false,

so doesn't seem to be a problem in the kv flag implementation...

still seeing this as of Terraform v0.11.7.

here is some additional clarification on the usecase:
i am using a Git short-rev as a "version", which i want to use in a templatized dockerrun.aws.json file. something like

"environment": [
  { "name": "VERSION", "value": "myApp:${VERSION}" }
],
...

in rare cases, like those described above, the resulting file is rendered as:

"environment": [
  { "name": "VERSION", "value": "myApp:" }
],
...

with an empty string for the VERSION variable. i can prevent this by prepending a string (something like rev) to my Git rev. but i would like to have an explanation/solution for the actual problem.

Thanks for the extra context, @davemeyer!

This is a pretty weird bug, indeed. Since the relevant portions of the code that deal with variables provided as arguments have changed significantly in the development branch for v0.12, I had been planning to hold on it until that branch is in a stable state where we could give this a try there, but given how weird this is hopefully we'll have some time soon to try to repro on 0.11.7 to see if there's a more straightforward fix here in the mean time.

The team is unfortunately kinda heads-down on the v0.12 development tasks as I write this, but we'll see if one of us can take a break to look at this in the not-too-distant future.

Hi again @davemeyer!

I'm pleased to report that as expected this strange bug seems to be gone in v0.12.0-alpha1. The variable processing code was rewritten along with the rest of the language interpreter in this release, so whatever codepath was causing the strange type inference is no longer being used.

I tweaked your example slightly because in v0.12.0-alpha1 the variable name "version" is reserved due to its conflict with a meta-argument in module blocks:

variable "desc" {
}

resource "aws_security_group" "default" {
  name        = "fakename"
  description = var.desc
}

Now I can terraform plan with the value that was previously coming through as empty:

$ terraform plan -var desc='16e8195'
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.default will be created
  + resource "aws_security_group" "default" {
      + arn                    = (known after apply)
      + description            = "16e8195"
      + id                     = (known after apply)
      + name                   = "fakename"
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + vpc_id                 = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

The new plan rendering layout makes this quite different than what you originally shared, but most important is the value "16e8195" showing up for the description argument.

Since this fix is already in master, I'm going to close this out. The fix will also be included in the final v0.12.0 release. Thanks for reporting this, and for your patience while we worked through all the groundwork to fix it.

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.

Was this page helpful?
0 / 5 - 0 ratings