Skip to content

Commit

Permalink
Merge pull request #532 from gruntwork-io/yori-test-nil-conversion
Browse files Browse the repository at this point in the history
Handle nil in input vars
  • Loading branch information
yorinasub17 authored Jun 5, 2020
2 parents 98e5516 + 8de6386 commit 2246114
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 3 deletions.
4 changes: 4 additions & 0 deletions modules/terraform/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ func mapToHclString(m map[string]interface{}) string {
// Convert a primitive, such as a bool, int, or string, to an HCL string. If this isn't a primitive, force its value
// using Sprintf. See ToHclString for details.
func primitiveToHclString(value interface{}, isNested bool) string {
if value == nil {
return "null"
}

switch v := value.(type) {

case bool:
Expand Down
2 changes: 2 additions & 0 deletions modules/terraform/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestFormatTerraformVarsAsArgs(t *testing.T) {
{map[string]interface{}{"foo": "bar"}, []string{"-var", "foo=bar"}},
{map[string]interface{}{"foo": 123}, []string{"-var", "foo=123"}},
{map[string]interface{}{"foo": true}, []string{"-var", "foo=true"}},
{map[string]interface{}{"foo": nil}, []string{"-var", "foo=null"}},
{map[string]interface{}{"foo": []int{1, 2, 3}}, []string{"-var", "foo=[1, 2, 3]"}},
{map[string]interface{}{"foo": map[string]string{"baz": "blah"}}, []string{"-var", "foo={\"baz\" = \"blah\"}"}},
{
Expand Down Expand Up @@ -45,6 +46,7 @@ func TestPrimitiveToHclString(t *testing.T) {
{"true", "true"},
{true, "true"},
{3, "3"},
{nil, "null"},
{[]int{1, 2, 3}, "[1 2 3]"}, // Anything that isn't a primitive is forced into a string
}

Expand Down
15 changes: 12 additions & 3 deletions modules/terraform/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ import (

// Options for running Terraform commands
type Options struct {
TerraformBinary string // Name of the binary that will be used
TerraformDir string // The path to the folder where the Terraform code is defined.
Vars map[string]interface{} // The vars to pass to Terraform commands using the -var option.
TerraformBinary string // Name of the binary that will be used
TerraformDir string // The path to the folder where the Terraform code is defined.

// The vars to pass to Terraform commands using the -var option. Note that terraform does not support passing `null`
// as a variable value through the command line. That is, if you use `map[string]interface{}{"foo": nil}` as `Vars`,
// this will translate to the string literal `"null"` being assigned to the variable `foo`. However, nulls in
// lists and maps/objects are supported. E.g., the following var will be set as expected (`{ bar = null }`:
// map[string]interface{}{
// "foo": map[string]interface{}{"bar": nil},
// }
Vars map[string]interface{}

VarFiles []string // The var file paths to pass to Terraform commands using -var-file option.
Targets []string // The target resources to pass to the terraform command with -target
Lock bool // The lock option to pass to the terraform command with -lock
Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/terraform-null/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
variable "foo" {
type = object({
nullable_string = string
nonnullable_string = string
})
}

output "foo" {
value = var.foo
}

output "bar" {
value = var.foo.nullable_string == null ? "I AM NULL" : null
}
28 changes: 28 additions & 0 deletions test/terraform_unit_null_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package test

import (
"testing"

"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/magiconair/properties/assert"
)

func TestUnitNullInput(t *testing.T) {
t.Parallel()

foo := map[string]interface{}{
"nullable_string": nil,
"nonnullable_string": "foo",
}
options := &terraform.Options{
TerraformDir: "./fixtures/terraform-null",
Vars: map[string]interface{}{"foo": foo},
}
terraform.InitAndApply(t, options)

fooOut := terraform.OutputMap(t, options, "foo")
assert.Equal(t, fooOut, map[string]string{"nonnullable_string": "foo", "nullable_string": "<nil>"})

barOut := terraform.Output(t, options, "bar")
assert.Equal(t, barOut, "I AM NULL")
}

0 comments on commit 2246114

Please sign in to comment.