detect scaled in resources when evaluating *s

If an existing resources is scaled back to 0, locals and outputs will
still have a multi-variable reference to evaluate, which should return
an empty list. Due to how the resource is removed, the resource will
still exist in the state but with no primary instance, which needs to be
ignored in the instance count.
This commit is contained in:
James Bardin 2018-04-03 10:00:45 -04:00
parent d4eb6049b3
commit 79b948c9cc
3 changed files with 79 additions and 1 deletions

View File

@ -9541,3 +9541,62 @@ func TestContext2Apply_plannedInterpolatedCount(t *testing.T) {
t.Fatalf("apply failed: %s", err) t.Fatalf("apply failed: %s", err)
} }
} }
func TestContext2Apply_scaleInMultivarRef(t *testing.T) {
m := testModule(t, "apply-resource-scale-in")
p := testProvider("aws")
p.ApplyFn = testApplyFn
p.DiffFn = testDiffFn
providerResolver := ResourceProviderResolverFixed(
map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
)
s := &State{
Modules: []*ModuleState{
&ModuleState{
Path: rootModulePath,
Resources: map[string]*ResourceState{
"aws_instance.one": {
Type: "aws_instance",
Primary: &InstanceState{
ID: "foo",
},
Provider: "provider.aws",
},
"aws_instance.two": {
Type: "aws_instance",
Primary: &InstanceState{
ID: "foo",
Attributes: map[string]string{
"val": "foo",
},
},
Provider: "provider.aws",
},
},
},
},
}
ctx := testContext2(t, &ContextOpts{
Module: m,
ProviderResolver: providerResolver,
State: s,
Variables: map[string]interface{}{"count": "0"},
})
_, err := ctx.Plan()
if err != nil {
t.Fatalf("plan failed: %s", err)
}
// Applying the plan should now succeed
_, err = ctx.Apply()
if err != nil {
t.Fatalf("apply failed: %s", err)
}
}

View File

@ -820,7 +820,13 @@ func (i *Interpolater) resourceCountMax(
// use "cr.Count()" but that doesn't work if the count is interpolated // use "cr.Count()" but that doesn't work if the count is interpolated
// and we can't guarantee that so we instead depend on the state. // and we can't guarantee that so we instead depend on the state.
max := -1 max := -1
for k, _ := range ms.Resources { for k, s := range ms.Resources {
// This resource may have been just removed, in which case the Primary
// may be nil, or just empty.
if s == nil || s.Primary == nil || len(s.Primary.Attributes) == 0 {
continue
}
// Get the index number for this resource // Get the index number for this resource
index := "" index := ""
if k == id { if k == id {

View File

@ -0,0 +1,13 @@
variable "count" {}
resource "aws_instance" "one" {
count = "${var.count}"
}
locals {
"one_id" = "${element(concat(aws_instance.one.*.id, list("")), 0)}"
}
resource "aws_instance" "two" {
val = "${local.one_id}"
}