terraform: allow indexing into a computed list for multi-count resources

Fixes #8695

When a list count was computed in a multi-resource access
(foo.bar.*.list), we were returning the value as empty string. I don't
actually know the histocal reasoning for this but this can't be correct:
we must return unknown.

When changing this to unknown, the new tests passed and none of the old
tests failed. This leads me further to believe that the return empty
string is probably a holdover from long ago to just avoid crashes or
UUIDs in the plan output and not actually the correct behavior.
This commit is contained in:
Mitchell Hashimoto 2016-12-10 19:17:29 -05:00
parent c02b2471d6
commit cabcc4b5b8
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
5 changed files with 102 additions and 1 deletions

View File

@ -1319,6 +1319,31 @@ func TestContext2Plan_computedList(t *testing.T) {
}
}
// GH-8695. This tests that you can index into a computed list on a
// splatted resource.
func TestContext2Plan_computedMultiIndex(t *testing.T) {
m := testModule(t, "plan-computed-multi-index")
p := testProvider("aws")
p.DiffFn = testDiffFn
ctx := testContext2(t, &ContextOpts{
Module: m,
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
})
plan, err := ctx.Plan()
if err != nil {
t.Fatalf("err: %s", err)
}
actual := strings.TrimSpace(plan.String())
expected := strings.TrimSpace(testTerraformPlanComputedMultiIndexStr)
if actual != expected {
t.Fatalf("bad:\n%s", actual)
}
}
func TestContext2Plan_count(t *testing.T) {
m := testModule(t, "plan-count")
p := testProvider("aws")

View File

@ -587,7 +587,7 @@ func (i *Interpolater) computeResourceMultiVariable(
}
if multiAttr == unknownVariable {
return &ast.Variable{Type: ast.TypeString, Value: ""}, nil
return &unknownVariable, nil
}
values = append(values, multiAttr)

View File

@ -364,6 +364,55 @@ func TestInterpolater_resourceVariableMulti(t *testing.T) {
})
}
// When a splat reference is made to an attribute that is a computed list,
// the result should be unknown.
func TestInterpolater_resourceVariableMultiList(t *testing.T) {
lock := new(sync.RWMutex)
state := &State{
Modules: []*ModuleState{
&ModuleState{
Path: rootModulePath,
Resources: map[string]*ResourceState{
"aws_instance.web.0": &ResourceState{
Type: "aws_instance",
Primary: &InstanceState{
ID: "bar",
Attributes: map[string]string{
"ip.#": config.UnknownVariableValue,
},
},
},
"aws_instance.web.1": &ResourceState{
Type: "aws_instance",
Primary: &InstanceState{
ID: "bar",
Attributes: map[string]string{
"ip.#": "0",
},
},
},
},
},
},
}
i := &Interpolater{
Module: testModule(t, "interpolate-resource-variable"),
State: state,
StateLock: lock,
}
scope := &InterpolationScope{
Path: rootModulePath,
}
testInterpolate(t, i, scope, "aws_instance.web.*.ip", ast.Variable{
Value: config.UnknownVariableValue,
Type: ast.TypeUnknown,
})
}
func TestInterpolater_resourceVariableMulti_interpolated(t *testing.T) {
lock := new(sync.RWMutex)
state := &State{

View File

@ -943,6 +943,24 @@ STATE:
<no state>
`
const testTerraformPlanComputedMultiIndexStr = `
DIFF:
CREATE: aws_instance.bar
foo: "" => "<computed>"
type: "" => "aws_instance"
CREATE: aws_instance.foo.0
ip.#: "" => "<computed>"
type: "" => "aws_instance"
CREATE: aws_instance.foo.1
ip.#: "" => "<computed>"
type: "" => "aws_instance"
STATE:
<no state>
`
const testTerraformPlanCountStr = `
DIFF:

View File

@ -0,0 +1,9 @@
resource "aws_instance" "foo" {
count = 2
compute = "ip.#"
}
resource "aws_instance" "bar" {
count = 1
foo = "${aws_instance.foo.*.ip[count.index]}"
}