core: Move CountBoundaryTransformer to the plan graph builder

This fixes interpolation issues on grandchild data sources that have
multiple instances (ie: counts). For example, baz depends on bar, which
depends on foo.

In this instance, after an initial TF run is done and state is saved,
the next refresh/plan is not properly transformed, and instead of the
graph/state coming through as data.x.bar.0, it comes through as
data.x.bar.  This breaks interpolations that rely on splat operators -
ie: data.x.bar.*.out.
This commit is contained in:
Chris Marchesi 2017-04-19 16:56:54 -07:00
parent f5cda342f7
commit 2802d319d2
3 changed files with 59 additions and 3 deletions

View File

@ -99,3 +99,59 @@ resource "test_resource" "foo" {
},
})
}
// Test that a grandchild data source that is based off of count works, ie:
// dependency chain foo -> bar -> baz. This was failing because
// CountBoundaryTransformer is being run during apply instead of plan, which
// meant that it wasn't firing after data sources were potentially changing
// state and causing diff/interpolation issues.
//
// This happens after the initial apply, after state is saved.
func TestDataSource_dataSourceCountGrandChild(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
CheckDestroy: func(s *terraform.State) error {
return nil
},
Steps: []resource.TestStep{
{
Config: dataSourceCountGrandChildConfig,
},
{
Config: dataSourceCountGrandChildConfig,
Check: func(s *terraform.State) error {
for _, v := range []string{"foo", "bar", "baz"} {
count := 0
for k := range s.RootModule().Resources {
if strings.HasPrefix(k, fmt.Sprintf("data.test_data_source.%s.", v)) {
count++
}
}
if count != 2 {
return fmt.Errorf("bad count for data.test_data_source.%s: %d", v, count)
}
}
return nil
},
},
},
})
}
const dataSourceCountGrandChildConfig = `
data "test_data_source" "foo" {
count = 2
input = "one"
}
data "test_data_source" "bar" {
count = "${length(data.test_data_source.foo.*.id)}"
input = "${data.test_data_source.foo.*.output[count.index]}"
}
data "test_data_source" "baz" {
count = "${length(data.test_data_source.bar.*.id)}"
input = "${data.test_data_source.bar.*.output[count.index]}"
}
`

View File

@ -117,9 +117,6 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
// Connect references so ordering is correct
&ReferenceTransformer{},
// Add the node to fix the state count boundaries
&CountBoundaryTransformer{},
// Target
&TargetsTransformer{Targets: b.Targets},

View File

@ -120,6 +120,9 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
&CloseProviderTransformer{},
&CloseProvisionerTransformer{},
// Add the node to fix the state count boundaries
&CountBoundaryTransformer{},
// Single root
&RootTransformer{},
}