From 9b8cb548c32b222072bbe71ab4d48d92a857e1dc Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 10 May 2024 17:06:21 -0700 Subject: [PATCH] terraform: Ephemeral resource close comes after provider close When a provider configuration is using an ephemeral resource, we need the closure of the resource instances to depend on the closure of the provider instance because otherwise we'll leave the ephemeral resource instance live only long enough to configure the provider, and that's useless for taking any other actions with the provider after it's been configured. --- .../transform_ephemeral_resource_close.go | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/internal/terraform/transform_ephemeral_resource_close.go b/internal/terraform/transform_ephemeral_resource_close.go index 25aea67ed3d1..03a60e66240b 100644 --- a/internal/terraform/transform_ephemeral_resource_close.go +++ b/internal/terraform/transform_ephemeral_resource_close.go @@ -92,6 +92,23 @@ func (t *ephemeralResourceCloseTransformer) Transform(g *Graph) error { if !ok { continue } + // If "v" is representing a provider configuration then we also need + // our close node to depend on its close node, so that an ephemeral + // resource instance that a provider instance is depending on will + // remain alive for the provider instance's entire lifetime, rather + // than just while it's configuring itself. + var vClose dag.Vertex + if vP, ok := v.(GraphNodeProvider); ok { + providerAddr := vP.ProviderAddr() + for _, maybeVClose := range verts { + if maybeVClose, ok := maybeVClose.(GraphNodeCloseProvider); ok { + if maybeVClose.CloseProviderAddr().Equal(providerAddr) { + vClose = maybeVClose + break + } + } + } + } for _, consumedAddr := range requiredEphemeralResourcesForReferencer(v) { if consumedAddr.Resource.Mode != addrs.EphemeralResourceMode { // Should not happen: correct implementations of @@ -113,7 +130,12 @@ func (t *ephemeralResourceCloseTransformer) Transform(g *Graph) error { // The close node depends on anything that consumes instances of // the ephemeral resource, because we mustn't close it while // other components are still using it. + log.Printf("[TRACE] ephemeralResourceCloseTransformer: %s must wait for %s", dag.VertexName(closeNode), v) g.Connect(dag.BasicEdge(closeNode, v)) + if vClose != nil { + log.Printf("[TRACE] ephemeralResourceCloseTransformer: %s must wait for %s", dag.VertexName(closeNode), vClose) + g.Connect(dag.BasicEdge(closeNode, vClose)) + } } }