Merge pull request #25500 from hashicorp/jbardin/destroy-output-expand

Do not evaluate output when doing a full destroy
This commit is contained in:
James Bardin 2020-07-08 10:07:20 -04:00 committed by GitHub
commit 8e79611e59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 19 deletions

View File

@ -6275,13 +6275,24 @@ func TestContext2Apply_destroyWithModuleVariableAndCountNested(t *testing.T) {
func TestContext2Apply_destroyOutputs(t *testing.T) {
m := testModule(t, "apply-destroy-outputs")
p := testProvider("aws")
p := testProvider("test")
p.ApplyFn = testApplyFn
p.DiffFn = testDiffFn
p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) providers.ReadDataSourceResponse {
// add the required id
m := req.Config.AsValueMap()
m["id"] = cty.StringVal("foo")
return providers.ReadDataSourceResponse{
State: cty.ObjectVal(m),
}
}
ctx := testContext2(t, &ContextOpts{
Config: m,
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})
@ -6302,7 +6313,7 @@ func TestContext2Apply_destroyOutputs(t *testing.T) {
State: state,
Config: m,
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})
@ -6326,7 +6337,7 @@ func TestContext2Apply_destroyOutputs(t *testing.T) {
State: state,
Config: m,
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})
if _, diags := ctx.Plan(); diags.HasErrors() {

View File

@ -165,7 +165,7 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
// directly. A destroy is identical to a normal apply, except for the
// fact that we also have configuration to evaluate. While the rest of
// the unused nodes can be programmatically pruned (via
// pruneUnusedNodesTransformer), root module outputs only have an
// pruneUnusedNodesTransformer), root module outputs always have an
// implied dependency on remote state. This means that if they exist in
// the configuration, the only signal to remove them is via the destroy
// command itself.

View File

@ -1,12 +1,26 @@
resource "aws_instance" "foo" {
num = "2"
data "test_data_source" "foo" {
foo = "ok"
}
resource "aws_instance" "bar" {
foo = "{aws_instance.foo.num}"
dep = "foo"
locals {
l = [
{
name = data.test_data_source.foo.id
val = "null"
},
]
m = { for v in local.l :
v.name => v
}
}
output "foo" {
value = "${aws_instance.foo.id}"
resource "test_instance" "bar" {
for_each = local.m
foo = format("%s", each.value.name)
dep = each.value.val
}
output "out" {
value = test_instance.bar
}

View File

@ -207,10 +207,10 @@ func (t *pruneUnusedNodesTransformer) Transform(g *Graph) error {
modules = append(modules, mod)
}
// Sort them by path length, longest first, so that start with the deepest
// modules. The order of modules at the same tree level doesn't matter, we
// just need to ensure that child modules are processed before parent
// modules.
// Sort them by path length, longest first, so that we start with the
// deepest modules. The order of modules at the same tree level doesn't
// matter, we just need to ensure that child modules are processed before
// parent modules.
sort.Slice(modules, func(i, j int) bool {
return len(modules[i].addr) > len(modules[j].addr)
})

View File

@ -88,13 +88,14 @@ func (t *destroyRootOutputTransformer) Transform(g *Graph) error {
deps := g.UpEdges(v)
// the destroy node must depend on the eval node
deps.Add(v)
for _, d := range deps {
log.Printf("[TRACE] %s depends on %s", node.Name(), dag.VertexName(d))
g.Connect(dag.BasicEdge(node, d))
}
// We no longer need the expand node, since we intend to remove this
// output from the state.
g.Remove(v)
}
return nil
}