diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index f53bae1d9d92..184ee540b72a 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -9541,3 +9541,62 @@ func TestContext2Apply_plannedInterpolatedCount(t *testing.T) { 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) + } +} diff --git a/terraform/interpolate.go b/terraform/interpolate.go index 1509a65fe0c0..f3d9adefe1dd 100644 --- a/terraform/interpolate.go +++ b/terraform/interpolate.go @@ -820,7 +820,13 @@ func (i *Interpolater) resourceCountMax( // 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. 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 index := "" if k == id { diff --git a/terraform/test-fixtures/apply-resource-scale-in/main.tf b/terraform/test-fixtures/apply-resource-scale-in/main.tf new file mode 100644 index 000000000000..da5ac8e4d0e3 --- /dev/null +++ b/terraform/test-fixtures/apply-resource-scale-in/main.tf @@ -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}" +}