Merge pull request #33462 from hashicorp/jbardin/destroy-output-provider-refs

always evaluate module outputs during destroy
This commit is contained in:
James Bardin 2023-07-07 09:44:27 -04:00 committed by GitHub
commit c42d3b4e51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 35 deletions

View File

@ -11381,33 +11381,7 @@ locals {
// Ensure that we can destroy when a provider references a resource that will // Ensure that we can destroy when a provider references a resource that will
// also be destroyed // also be destroyed
func TestContext2Apply_destroyProviderReference(t *testing.T) { func TestContext2Apply_destroyProviderReference(t *testing.T) {
m := testModuleInline(t, map[string]string{ m, snap := testModuleWithSnapshot(t, "apply-destroy-provisider-refs")
"main.tf": `
provider "null" {
value = ""
}
module "mod" {
source = "./mod"
}
provider "test" {
value = module.mod.output
}
resource "test_instance" "bar" {
}
`,
"mod/main.tf": `
data "null_data_source" "foo" {
count = 1
}
output "output" {
value = data.null_data_source.foo[0].output
}
`})
schemaFn := func(name string) *ProviderSchema { schemaFn := func(name string) *ProviderSchema {
return &ProviderSchema{ return &ProviderSchema{
@ -11506,11 +11480,12 @@ output "output" {
t.Fatalf("apply errors: %s", diags.Err()) t.Fatalf("apply errors: %s", diags.Err())
} }
providers := map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testP),
addrs.NewDefaultProvider("null"): testProviderFuncFixed(nullP),
}
ctx = testContext2(t, &ContextOpts{ ctx = testContext2(t, &ContextOpts{
Providers: map[addrs.Provider]providers.Factory{ Providers: providers,
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testP),
addrs.NewDefaultProvider("null"): testProviderFuncFixed(nullP),
},
}) })
plan, diags = ctx.Plan(m, state, &PlanOpts{ plan, diags = ctx.Plan(m, state, &PlanOpts{
@ -11518,6 +11493,19 @@ output "output" {
}) })
assertNoErrors(t, diags) assertNoErrors(t, diags)
// We'll marshal and unmarshal the plan here, to ensure that we have
// a clean new context as would be created if we separately ran
// terraform plan -out=tfplan && terraform apply tfplan
ctxOpts, m, plan, err := contextOptsForPlanViaFile(t, snap, plan)
if err != nil {
t.Fatal(err)
}
ctxOpts.Providers = providers
ctx, diags = NewContext(ctxOpts)
if diags.HasErrors() {
t.Fatalf("failed to create context for plan: %s", diags.Err())
}
if _, diags := ctx.Apply(plan, m); diags.HasErrors() { if _, diags := ctx.Apply(plan, m); diags.HasErrors() {
t.Fatalf("destroy apply errors: %s", diags.Err()) t.Fatalf("destroy apply errors: %s", diags.Err())
} }

View File

@ -108,10 +108,6 @@ func (n *nodeExpandOutput) DynamicExpand(ctx EvalContext) (*Graph, error) {
Planning: n.Planning, Planning: n.Planning,
} }
case n.Destroying:
// nothing is done here for non-root outputs
continue
default: default:
node = &NodeApplyableOutput{ node = &NodeApplyableOutput{
Addr: absAddr, Addr: absAddr,

View File

@ -0,0 +1,15 @@
provider "null" {
value = ""
}
module "mod" {
source = "./mod"
}
provider "test" {
value = module.mod.output
}
resource "test_instance" "bar" {
}

View File

@ -0,0 +1,9 @@
data "null_data_source" "foo" {
count = 1
}
output "output" {
value = data.null_data_source.foo[0].output
}