Merge pull request #5302 from hashicorp/b-5254
terraform: don't prune resource if count has interpolations
This commit is contained in:
commit
242f088309
|
@ -1,6 +1,7 @@
|
|||
package terraform
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
|
@ -3929,3 +3930,87 @@ func TestContext2Apply_singleDestroy(t *testing.T) {
|
|||
t.Fatalf("bad: %d", invokeCount)
|
||||
}
|
||||
}
|
||||
|
||||
// GH-5254
|
||||
func TestContext2Apply_issue5254(t *testing.T) {
|
||||
// Create a provider. We use "template" here just to match the repro
|
||||
// we got from the issue itself.
|
||||
p := testProvider("template")
|
||||
p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
|
||||
Name: "template_file",
|
||||
})
|
||||
|
||||
p.ApplyFn = testApplyFn
|
||||
p.DiffFn = testDiffFn
|
||||
|
||||
// Apply cleanly step 0
|
||||
t.Log("Applying Step 0")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Module: testModule(t, "issue-5254/step-0"),
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"template": testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
plan, err := ctx.Plan()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
t.Logf("Plan for Step 0: %s", plan)
|
||||
|
||||
state, err := ctx.Apply()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Application success. Now make the modification and store a plan
|
||||
println("Planning Step 1")
|
||||
t.Log("Planning Step 1")
|
||||
ctx = testContext2(t, &ContextOpts{
|
||||
Module: testModule(t, "issue-5254/step-1"),
|
||||
State: state,
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"template": testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
plan, err = ctx.Plan()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Write / Read plan to simulate running it through a Plan file
|
||||
var buf bytes.Buffer
|
||||
if err := WritePlan(plan, &buf); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
planFromFile, err := ReadPlan(&buf)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
t.Logf("Plan for Step 1: %s", planFromFile)
|
||||
|
||||
// Apply the plan
|
||||
println("Applying Step 1 (from Plan)")
|
||||
t.Log("Applying Step 1 (from plan)")
|
||||
ctx = planFromFile.Context(&ContextOpts{
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"template": testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
state, err = ctx.Apply()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
/*
|
||||
actual := strings.TrimSpace(state.String())
|
||||
expected := strings.TrimSpace(testTerraformApplyProviderAliasStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad: \n%s", actual)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -52,6 +52,11 @@ func testDiffFn(
|
|||
continue
|
||||
}
|
||||
|
||||
// Ignore __-prefixed keys since they're used for magic
|
||||
if k[0] == '_' && k[1] == '_' {
|
||||
continue
|
||||
}
|
||||
|
||||
if k == "nil" {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -100,6 +105,9 @@ func testDiffFn(
|
|||
if k == "require_new" {
|
||||
attrDiff.RequiresNew = true
|
||||
}
|
||||
if _, ok := c.Raw["__"+k+"_requires_new"]; ok {
|
||||
attrDiff.RequiresNew = true
|
||||
}
|
||||
diff.Attributes[k] = attrDiff
|
||||
}
|
||||
|
||||
|
|
|
@ -283,6 +283,13 @@ func (n *GraphNodeConfigResource) Noop(opts *NoopOpts) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// If the count has any interpolations, we can't prune this node since
|
||||
// we need to be sure to evaluate the count so that splat variables work
|
||||
// later (which need to know the full count).
|
||||
if len(n.Resource.RawCount.Interpolations) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// If we have no module diff, we're certainly a noop. This is because
|
||||
// it means there is a diff, and that the module we're in just isn't
|
||||
// in it, meaning we're not doing anything.
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
variable "c" { default = 1 }
|
||||
|
||||
resource "template_file" "parent" {
|
||||
count = "${var.c}"
|
||||
template = "Hi"
|
||||
}
|
||||
|
||||
resource "template_file" "child" {
|
||||
template = "${join(",", template_file.parent.*.template)} ok"
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
variable "c" { default = 1 }
|
||||
|
||||
resource "template_file" "parent" {
|
||||
count = "${var.c}"
|
||||
template = "Hi"
|
||||
}
|
||||
|
||||
resource "template_file" "child" {
|
||||
template = "${join(",", template_file.parent.*.template)}"
|
||||
__template_requires_new = 1
|
||||
}
|
Loading…
Reference in New Issue