Skip to content

Commit

Permalink
Merge pull request #9751 from hashicorp/b-true-true
Browse files Browse the repository at this point in the history
terraform: consistent variable values for booleans
  • Loading branch information
mitchellh authored Oct 31, 2016
2 parents 6831b6b + 50d4931 commit e8f5e4b
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 8 deletions.
10 changes: 10 additions & 0 deletions terraform/test-fixtures/vars-basic-bool/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// At the time of writing Terraform doesn't formally support a boolean
// type, but historically this has magically worked. Lots of TF code
// relies on this so we test it now.
variable "a" {
default = true
}

variable "b" {
default = false
}
18 changes: 17 additions & 1 deletion terraform/variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module"
"github.com/hashicorp/terraform/helper/hilmapstructure"
)

// Variables returns the fully loaded set of variables to use with
Expand Down Expand Up @@ -104,10 +105,25 @@ func Variables(
}

switch schema.Type() {
case config.VariableTypeList:
result[k] = v
case config.VariableTypeMap:
varSetMap(result, k, v)
case config.VariableTypeString:
// Convert to a string and set. We don't catch any errors
// here because the validation step later should catch
// any type errors.
var strVal string
if err := hilmapstructure.WeakDecode(v, &strVal); err == nil {
result[k] = strVal
} else {
result[k] = v
}
default:
result[k] = v
panic(fmt.Sprintf(
"Unhandled var type: %T\n\n"+
"THIS IS A BUG. Please report it.",
schema.Type()))
}
}
}
Expand Down
63 changes: 56 additions & 7 deletions terraform/variables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,64 @@ func TestVariables(t *testing.T) {
},
},
},

"bools: config only": {
"vars-basic-bool",
nil,
nil,
false,
map[string]interface{}{
"a": "1",
"b": "0",
},
},

"bools: override with string": {
"vars-basic-bool",
nil,
map[string]interface{}{
"a": "foo",
"b": "bar",
},
false,
map[string]interface{}{
"a": "foo",
"b": "bar",
},
},

"bools: override with env": {
"vars-basic-bool",
map[string]string{
"TF_VAR_a": "false",
"TF_VAR_b": "true",
},
nil,
false,
map[string]interface{}{
"a": "false",
"b": "true",
},
},

"bools: override with bool": {
"vars-basic-bool",
nil,
map[string]interface{}{
"a": false,
"b": true,
},
false,
map[string]interface{}{
"a": "0",
"b": "1",
},
},
}

for name, tc := range cases {
if name != "override partial map" {
continue
}

// Wrapped in a func so we can get defers to work
func() {
t.Run(name, func(t *testing.T) {
// Set the env vars
for k, v := range tc.Env {
defer tempEnv(t, k, v)()
Expand All @@ -107,8 +156,8 @@ func TestVariables(t *testing.T) {
}

if !reflect.DeepEqual(actual, tc.Expected) {
t.Fatalf("%s: expected: %#v\n\ngot: %#v", name, tc.Expected, actual)
t.Fatalf("%s\n\nexpected: %#v\n\ngot: %#v", name, tc.Expected, actual)
}
}()
})
}
}
47 changes: 47 additions & 0 deletions website/source/docs/configuration/variables.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,53 @@ VALUE
}
```

### Booleans

Although it appears Terraform supports boolean types, they are instead
silently converted to string types. The implications of this are subtle and
should be completely understood if you plan on using boolean values.

It is instead recommended you avoid using boolean values for now and use
explicit strings. A future version of Terraform will properly support
booleans and using the current behavior could result in backwards-incompatibilities
in the future.

For a configuration such as the following:

```
variable "active" {
default = false
}
```

The false is converted to a string `"0"` when running Terraform.

Then, depending on where you specify overrides, the behavior can differ:

* Variables with boolean values in a `tfvars` file will likewise be
converted to "0" and "1" values.

* Variables specified via the `-var` command line flag will be literal
strings "true" and "false", so care should be taken to explicitly use
"0" or "1".

* Variables specified with the `TF_VAR_` environment variables will
be literal string values, just like `-var`.

A future version of Terraform will fully support first-class boolean
types which will make the behavior of booleans consistent as you would
expect. This may break some of the above behavior.

When passing boolean-like variables as parameters to resource configurations
that expect boolean values, they are converted consistently:

* "1", "true", "t" all become `true`
* "0", "false", "f" all become `false`

The behavior of conversion above will likely not change in future
Terraform versions. Therefore, simply using string values rather than
booleans for variables is recommended.

## Environment Variables

Environment variables can be used to set the value of a variable.
Expand Down

0 comments on commit e8f5e4b

Please sign in to comment.