2015-02-05 18:47:06 -06:00
|
|
|
package terraform
|
|
|
|
|
|
|
|
import (
|
2015-04-14 19:42:23 -05:00
|
|
|
"fmt"
|
2015-02-05 18:47:06 -06:00
|
|
|
"os"
|
|
|
|
"reflect"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
"github.com/hashicorp/hil"
|
2016-01-31 01:43:41 -06:00
|
|
|
"github.com/hashicorp/hil/ast"
|
2015-02-05 18:47:06 -06:00
|
|
|
"github.com/hashicorp/terraform/config"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestInterpolater_countIndex(t *testing.T) {
|
|
|
|
i := &Interpolater{}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resource: &Resource{CountIndex: 42},
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolate(t, i, scope, "count.index", ast.Variable{
|
|
|
|
Value: 42,
|
|
|
|
Type: ast.TypeInt,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-04-14 19:42:23 -05:00
|
|
|
func TestInterpolater_countIndexInWrongContext(t *testing.T) {
|
|
|
|
i := &Interpolater{}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
n := "count.index"
|
|
|
|
|
|
|
|
v, err := config.NewInterpolatedVariable(n)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expectedErr := fmt.Errorf("foo: count.index is only valid within resources")
|
|
|
|
|
|
|
|
_, err = i.Values(scope, map[string]config.InterpolatedVariable{
|
|
|
|
"foo": v,
|
|
|
|
})
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(expectedErr, err) {
|
|
|
|
t.Fatalf("expected: %#v, got %#v", expectedErr, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-05 18:47:06 -06:00
|
|
|
func TestInterpolater_moduleVariable(t *testing.T) {
|
|
|
|
lock := new(sync.RWMutex)
|
|
|
|
state := &State{
|
|
|
|
Modules: []*ModuleState{
|
|
|
|
&ModuleState{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resources: map[string]*ResourceState{
|
|
|
|
"aws_instance.web": &ResourceState{
|
|
|
|
Type: "aws_instance",
|
|
|
|
Primary: &InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&ModuleState{
|
|
|
|
Path: []string{RootModuleName, "child"},
|
2016-05-11 19:05:02 -05:00
|
|
|
Outputs: map[string]*OutputState{
|
|
|
|
"foo": &OutputState{
|
|
|
|
Type: "string",
|
|
|
|
Value: "bar",
|
|
|
|
},
|
2015-02-05 18:47:06 -06:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
i := &Interpolater{
|
|
|
|
State: state,
|
|
|
|
StateLock: lock,
|
|
|
|
}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolate(t, i, scope, "module.child.foo", ast.Variable{
|
|
|
|
Value: "bar",
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterpolater_pathCwd(t *testing.T) {
|
|
|
|
i := &Interpolater{}
|
|
|
|
scope := &InterpolationScope{}
|
|
|
|
|
|
|
|
expected, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolate(t, i, scope, "path.cwd", ast.Variable{
|
|
|
|
Value: expected,
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterpolater_pathModule(t *testing.T) {
|
|
|
|
mod := testModule(t, "interpolate-path-module")
|
|
|
|
i := &Interpolater{
|
|
|
|
Module: mod,
|
|
|
|
}
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: []string{RootModuleName, "child"},
|
|
|
|
}
|
|
|
|
|
|
|
|
path := mod.Child([]string{"child"}).Config().Dir
|
|
|
|
testInterpolate(t, i, scope, "path.module", ast.Variable{
|
|
|
|
Value: path,
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterpolater_pathRoot(t *testing.T) {
|
|
|
|
mod := testModule(t, "interpolate-path-module")
|
|
|
|
i := &Interpolater{
|
|
|
|
Module: mod,
|
|
|
|
}
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: []string{RootModuleName, "child"},
|
|
|
|
}
|
|
|
|
|
|
|
|
path := mod.Config().Dir
|
|
|
|
testInterpolate(t, i, scope, "path.root", ast.Variable{
|
|
|
|
Value: path,
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-07-19 19:27:38 -05:00
|
|
|
func TestInterpolater_resourceVariable(t *testing.T) {
|
|
|
|
lock := new(sync.RWMutex)
|
|
|
|
state := &State{
|
|
|
|
Modules: []*ModuleState{
|
|
|
|
&ModuleState{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resources: map[string]*ResourceState{
|
|
|
|
"aws_instance.web": &ResourceState{
|
|
|
|
Type: "aws_instance",
|
|
|
|
Primary: &InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"foo": "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
i := &Interpolater{
|
|
|
|
Module: testModule(t, "interpolate-resource-variable"),
|
|
|
|
State: state,
|
|
|
|
StateLock: lock,
|
|
|
|
}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolate(t, i, scope, "aws_instance.web.foo", ast.Variable{
|
|
|
|
Value: "bar",
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-05-14 11:25:03 -05:00
|
|
|
func TestInterpolater_resourceVariableMissingDuringInput(t *testing.T) {
|
|
|
|
// During the input walk, computed resource attributes may be entirely
|
|
|
|
// absent since we've not yet produced diffs that tell us what computed
|
|
|
|
// attributes to expect. In that case, interpolator tolerates it and
|
|
|
|
// indicates the value is computed.
|
|
|
|
|
|
|
|
lock := new(sync.RWMutex)
|
|
|
|
state := &State{
|
|
|
|
Modules: []*ModuleState{
|
|
|
|
&ModuleState{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resources: map[string]*ResourceState{
|
|
|
|
// No resources at all yet, because we're still dealing
|
|
|
|
// with input and so the resources haven't been created.
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
i := &Interpolater{
|
|
|
|
Operation: walkInput,
|
|
|
|
Module: testModule(t, "interpolate-resource-variable"),
|
|
|
|
State: state,
|
|
|
|
StateLock: lock,
|
|
|
|
}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolate(t, i, scope, "aws_instance.web.foo", ast.Variable{
|
|
|
|
Value: config.UnknownVariableValue,
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// This doesn't apply during other walks, like plan
|
|
|
|
{
|
|
|
|
i := &Interpolater{
|
|
|
|
Operation: walkPlan,
|
|
|
|
Module: testModule(t, "interpolate-resource-variable"),
|
|
|
|
State: state,
|
|
|
|
StateLock: lock,
|
|
|
|
}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolateErr(t, i, scope, "aws_instance.web.foo")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-19 19:27:38 -05:00
|
|
|
func TestInterpolater_resourceVariableMulti(t *testing.T) {
|
|
|
|
lock := new(sync.RWMutex)
|
|
|
|
state := &State{
|
|
|
|
Modules: []*ModuleState{
|
|
|
|
&ModuleState{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resources: map[string]*ResourceState{
|
|
|
|
"aws_instance.web": &ResourceState{
|
|
|
|
Type: "aws_instance",
|
|
|
|
Primary: &InstanceState{
|
|
|
|
ID: "bar",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"foo": config.UnknownVariableValue,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
i := &Interpolater{
|
|
|
|
Module: testModule(t, "interpolate-resource-variable"),
|
|
|
|
State: state,
|
|
|
|
StateLock: lock,
|
|
|
|
}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolate(t, i, scope, "aws_instance.web.*.foo", ast.Variable{
|
|
|
|
Value: config.UnknownVariableValue,
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
func interfaceToVariableSwallowError(input interface{}) ast.Variable {
|
|
|
|
variable, _ := hil.InterfaceToVariable(input)
|
|
|
|
return variable
|
|
|
|
}
|
|
|
|
|
2015-07-05 09:26:01 -05:00
|
|
|
func TestInterpolator_resourceMultiAttributes(t *testing.T) {
|
|
|
|
lock := new(sync.RWMutex)
|
|
|
|
state := &State{
|
|
|
|
Modules: []*ModuleState{
|
|
|
|
&ModuleState{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resources: map[string]*ResourceState{
|
|
|
|
"aws_route53_zone.yada": &ResourceState{
|
|
|
|
Type: "aws_route53_zone",
|
|
|
|
Dependencies: []string{},
|
|
|
|
Primary: &InstanceState{
|
|
|
|
ID: "AAABBBCCCDDDEEE",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"name_servers.#": "4",
|
|
|
|
"name_servers.0": "ns-1334.awsdns-38.org",
|
|
|
|
"name_servers.1": "ns-1680.awsdns-18.co.uk",
|
|
|
|
"name_servers.2": "ns-498.awsdns-62.com",
|
|
|
|
"name_servers.3": "ns-601.awsdns-11.net",
|
|
|
|
"listeners.#": "1",
|
|
|
|
"listeners.0": "red",
|
|
|
|
"tags.#": "1",
|
|
|
|
"tags.Name": "reindeer",
|
|
|
|
"nothing.#": "0",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
i := &Interpolater{
|
|
|
|
Module: testModule(t, "interpolate-multi-vars"),
|
|
|
|
StateLock: lock,
|
|
|
|
State: state,
|
|
|
|
}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
name_servers := []interface{}{
|
2015-07-05 09:26:01 -05:00
|
|
|
"ns-1334.awsdns-38.org",
|
|
|
|
"ns-1680.awsdns-18.co.uk",
|
|
|
|
"ns-498.awsdns-62.com",
|
|
|
|
"ns-601.awsdns-11.net",
|
|
|
|
}
|
|
|
|
|
|
|
|
// More than 1 element
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.yada.name_servers",
|
|
|
|
interfaceToVariableSwallowError(name_servers))
|
2015-07-05 09:26:01 -05:00
|
|
|
|
|
|
|
// Exactly 1 element
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.yada.listeners",
|
|
|
|
interfaceToVariableSwallowError([]interface{}{"red"}))
|
2015-07-05 09:26:01 -05:00
|
|
|
|
|
|
|
// Zero elements
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.yada.nothing",
|
|
|
|
interfaceToVariableSwallowError([]interface{}{}))
|
2015-07-05 09:26:01 -05:00
|
|
|
|
|
|
|
// Maps still need to work
|
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.yada.tags.Name", ast.Variable{
|
|
|
|
Value: "reindeer",
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterpolator_resourceMultiAttributesWithResourceCount(t *testing.T) {
|
|
|
|
i := getInterpolaterFixture(t)
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
name_servers := []interface{}{
|
2015-07-05 09:26:01 -05:00
|
|
|
"ns-1334.awsdns-38.org",
|
|
|
|
"ns-1680.awsdns-18.co.uk",
|
|
|
|
"ns-498.awsdns-62.com",
|
|
|
|
"ns-601.awsdns-11.net",
|
|
|
|
"ns-000.awsdns-38.org",
|
|
|
|
"ns-444.awsdns-18.co.uk",
|
|
|
|
"ns-666.awsdns-11.net",
|
|
|
|
"ns-999.awsdns-62.com",
|
|
|
|
}
|
|
|
|
|
|
|
|
// More than 1 element
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.0.name_servers",
|
|
|
|
interfaceToVariableSwallowError(name_servers[0:4]))
|
|
|
|
|
2015-07-05 09:26:01 -05:00
|
|
|
// More than 1 element in both
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.*.name_servers",
|
|
|
|
interfaceToVariableSwallowError(name_servers))
|
2015-07-05 09:26:01 -05:00
|
|
|
|
|
|
|
// Exactly 1 element
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.0.listeners",
|
|
|
|
interfaceToVariableSwallowError([]interface{}{"red"}))
|
|
|
|
|
2015-07-05 09:26:01 -05:00
|
|
|
// Exactly 1 element in both
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.*.listeners",
|
|
|
|
interfaceToVariableSwallowError([]interface{}{"red", "blue"}))
|
2015-07-05 09:26:01 -05:00
|
|
|
|
|
|
|
// Zero elements
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.0.nothing",
|
|
|
|
interfaceToVariableSwallowError([]interface{}{}))
|
|
|
|
|
2015-07-05 09:26:01 -05:00
|
|
|
// Zero + 1 element
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.*.special",
|
|
|
|
interfaceToVariableSwallowError([]interface{}{"extra"}))
|
2015-07-05 09:26:01 -05:00
|
|
|
|
|
|
|
// Maps still need to work
|
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.0.tags.Name", ast.Variable{
|
|
|
|
Value: "reindeer",
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
|
2015-07-05 09:26:01 -05:00
|
|
|
// Maps still need to work in both
|
core: support native list variables in config
This commit adds support for native list variables and outputs, building
up on the previous change to state. Interpolation functions now return
native lists in preference to StringList.
List variables are defined like this:
variable "test" {
# This can also be inferred
type = "list"
default = ["Hello", "World"]
}
output "test_out" {
value = "${var.a_list}"
}
This results in the following state:
```
...
"outputs": {
"test_out": [
"hello",
"world"
]
},
...
```
And the result of terraform output is as follows:
```
$ terraform output
test_out = [
hello
world
]
```
Using the output name, an xargs-friendly representation is output:
```
$ terraform output test_out
hello
world
```
The output command also supports indexing into the list (with
appropriate range checking and no wrapping):
```
$ terraform output test_out 1
world
```
Along with maps, list outputs from one module may be passed as variables
into another, removing the need for the `join(",", var.list_as_string)`
and `split(",", var.list_as_string)` which was previously necessary in
Terraform configuration.
This commit also updates the tests and implementations of built-in
interpolation functions to take and return native lists where
appropriate.
A backwards compatibility note: previously the concat interpolation
function was capable of concatenating either strings or lists. The
strings use case was deprectated a long time ago but still remained.
Because we cannot return `ast.TypeAny` from an interpolation function,
this use case is no longer supported for strings - `concat` is only
capable of concatenating lists. This should not be a huge issue - the
type checker picks up incorrect parameters, and the native HIL string
concatenation - or the `join` function - can be used to replicate the
missing behaviour.
2016-04-21 19:03:24 -05:00
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.terra.*.tags.Name",
|
|
|
|
interfaceToVariableSwallowError([]interface{}{"reindeer", "white-hart"}))
|
2015-07-05 09:26:01 -05:00
|
|
|
}
|
|
|
|
|
2016-01-26 13:18:00 -06:00
|
|
|
func TestInterpolator_resourceMultiAttributesComputed(t *testing.T) {
|
|
|
|
lock := new(sync.RWMutex)
|
|
|
|
// The state would never be written with an UnknownVariableValue in it, but
|
|
|
|
// it can/does exist that way in memory during the plan phase.
|
|
|
|
state := &State{
|
|
|
|
Modules: []*ModuleState{
|
|
|
|
&ModuleState{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resources: map[string]*ResourceState{
|
|
|
|
"aws_route53_zone.yada": &ResourceState{
|
|
|
|
Type: "aws_route53_zone",
|
|
|
|
Primary: &InstanceState{
|
|
|
|
ID: "z-abc123",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"name_servers.#": config.UnknownVariableValue,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
i := &Interpolater{
|
|
|
|
Module: testModule(t, "interpolate-multi-vars"),
|
|
|
|
StateLock: lock,
|
|
|
|
State: state,
|
|
|
|
}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
testInterpolate(t, i, scope, "aws_route53_zone.yada.name_servers", ast.Variable{
|
|
|
|
Value: config.UnknownVariableValue,
|
|
|
|
Type: ast.TypeString,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-02-23 11:42:55 -06:00
|
|
|
func TestInterpolater_selfVarWithoutResource(t *testing.T) {
|
|
|
|
i := &Interpolater{}
|
|
|
|
|
|
|
|
scope := &InterpolationScope{
|
|
|
|
Path: rootModulePath,
|
|
|
|
}
|
|
|
|
|
|
|
|
v, err := config.NewInterpolatedVariable("self.name")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = i.Values(scope, map[string]config.InterpolatedVariable{"foo": v})
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected err, got none")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-05 09:26:01 -05:00
|
|
|
func getInterpolaterFixture(t *testing.T) *Interpolater {
|
|
|
|
lock := new(sync.RWMutex)
|
|
|
|
state := &State{
|
|
|
|
Modules: []*ModuleState{
|
|
|
|
&ModuleState{
|
|
|
|
Path: rootModulePath,
|
|
|
|
Resources: map[string]*ResourceState{
|
|
|
|
"aws_route53_zone.terra.0": &ResourceState{
|
|
|
|
Type: "aws_route53_zone",
|
|
|
|
Dependencies: []string{},
|
|
|
|
Primary: &InstanceState{
|
|
|
|
ID: "AAABBBCCCDDDEEE",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"name_servers.#": "4",
|
|
|
|
"name_servers.0": "ns-1334.awsdns-38.org",
|
|
|
|
"name_servers.1": "ns-1680.awsdns-18.co.uk",
|
|
|
|
"name_servers.2": "ns-498.awsdns-62.com",
|
|
|
|
"name_servers.3": "ns-601.awsdns-11.net",
|
|
|
|
"listeners.#": "1",
|
|
|
|
"listeners.0": "red",
|
|
|
|
"tags.#": "1",
|
|
|
|
"tags.Name": "reindeer",
|
|
|
|
"nothing.#": "0",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"aws_route53_zone.terra.1": &ResourceState{
|
|
|
|
Type: "aws_route53_zone",
|
|
|
|
Dependencies: []string{},
|
|
|
|
Primary: &InstanceState{
|
|
|
|
ID: "EEEFFFGGGHHHIII",
|
|
|
|
Attributes: map[string]string{
|
|
|
|
"name_servers.#": "4",
|
|
|
|
"name_servers.0": "ns-000.awsdns-38.org",
|
|
|
|
"name_servers.1": "ns-444.awsdns-18.co.uk",
|
|
|
|
"name_servers.2": "ns-999.awsdns-62.com",
|
|
|
|
"name_servers.3": "ns-666.awsdns-11.net",
|
|
|
|
"listeners.#": "1",
|
|
|
|
"listeners.0": "blue",
|
|
|
|
"special.#": "1",
|
|
|
|
"special.0": "extra",
|
|
|
|
"tags.#": "1",
|
|
|
|
"tags.Name": "white-hart",
|
|
|
|
"nothing.#": "0",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Interpolater{
|
|
|
|
Module: testModule(t, "interpolate-multi-vars"),
|
|
|
|
StateLock: lock,
|
|
|
|
State: state,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-05 18:47:06 -06:00
|
|
|
func testInterpolate(
|
|
|
|
t *testing.T, i *Interpolater,
|
|
|
|
scope *InterpolationScope,
|
|
|
|
n string, expectedVar ast.Variable) {
|
|
|
|
v, err := config.NewInterpolatedVariable(n)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
actual, err := i.Values(scope, map[string]config.InterpolatedVariable{
|
|
|
|
"foo": v,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := map[string]ast.Variable{
|
|
|
|
"foo": expectedVar,
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(actual, expected) {
|
2015-07-05 09:26:01 -05:00
|
|
|
t.Fatalf("%q: actual: %#v\nexpected: %#v", n, actual, expected)
|
2015-02-05 18:47:06 -06:00
|
|
|
}
|
|
|
|
}
|
2016-05-14 11:25:03 -05:00
|
|
|
|
|
|
|
func testInterpolateErr(
|
|
|
|
t *testing.T, i *Interpolater,
|
|
|
|
scope *InterpolationScope,
|
|
|
|
n string) {
|
|
|
|
v, err := config.NewInterpolatedVariable(n)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = i.Values(scope, map[string]config.InterpolatedVariable{
|
|
|
|
"foo": v,
|
|
|
|
})
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("%q: succeeded, but wanted error", n)
|
|
|
|
}
|
|
|
|
}
|