make ephemeral resource work during destroy

Ephemeral resource behavior is a strange mix of temporary values and
existing resource types, and their operation during destroy is going to
be more difficult to manage than normal resources.

The pruneUnusedNodesTransformer is probably no longer equipped to handle
the situation, and will probably need to be build in a different manner,
but this minor change allows us to move forward for  now.
pull/35853/head
James Bardin 2 years ago
parent c00c235f37
commit 179c502ffb

@ -24,6 +24,7 @@ func NewProvider() providers.Interface {
// GetSchema returns the complete schema for the provider.
func (p *Provider) GetProviderSchema() providers.GetProviderSchemaResponse {
resp := providers.GetProviderSchemaResponse{
Provider: providers.Schema{},
ServerCapabilities: providers.ServerCapabilities{
MoveResourceState: true,
},

@ -378,6 +378,7 @@ func (c *Context) checkApplyGraph(plan *plans.Plan, config *configs.Config, opts
return nil
}
log.Println("[DEBUG] building apply graph to check for errors")
_, _, diags := c.applyGraph(plan, config, opts.ApplyOpts(), true)
return diags
}

@ -137,7 +137,7 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
&ConfigTransformer{
Concrete: b.ConcreteResource,
Config: b.Config,
skip: b.Operation == walkDestroy || b.Operation == walkPlanDestroy,
destroy: b.Operation == walkDestroy || b.Operation == walkPlanDestroy,
importTargets: b.ImportTargets,

@ -35,7 +35,8 @@ type ConfigTransformer struct {
ModeFilter bool
Mode addrs.ResourceMode
skip bool
// some actions are skipped during the destroy process
destroy bool
// importTargets specifies a slice of addresses that will have state
// imported for them.
@ -52,11 +53,6 @@ type ConfigTransformer struct {
}
func (t *ConfigTransformer) Transform(g *Graph) error {
// no import ops happen during destroy
if t.skip {
return nil
}
// If no configuration is available, we don't do anything
if t.Config == nil {
return nil
@ -97,12 +93,17 @@ func (t *ConfigTransformer) transformSingle(g *Graph, config *configs.Config) er
log.Printf("[TRACE] ConfigTransformer: Starting for path: %v", path)
var allResources []*configs.Resource
for _, r := range module.ManagedResources {
allResources = append(allResources, r)
}
for _, r := range module.DataResources {
allResources = append(allResources, r)
if !t.destroy {
for _, r := range module.ManagedResources {
allResources = append(allResources, r)
}
for _, r := range module.DataResources {
allResources = append(allResources, r)
}
}
// ephemeral resources act like temporary values and must be added to the
// graph even during destroy operations.
for _, r := range module.EphemeralResources {
allResources = append(allResources, r)
}
@ -204,6 +205,9 @@ func (t *ConfigTransformer) transformSingle(g *Graph, config *configs.Config) er
// validateImportTargets ensures that the import target module exists in the
// configuration. Individual resources will be check by the validation node.
func (t *ConfigTransformer) validateImportTargets() error {
if t.destroy {
return nil
}
var diags tfdiags.Diagnostics
for _, i := range t.importTargets {

@ -346,6 +346,16 @@ func (t *pruneUnusedNodesTransformer) Transform(g *Graph) error {
}
case graphNodeExpandsInstances:
// FIXME: Ephemeral resources have kind of broken this
// transformer. They work like temporary values in that they
// should not exist when there are no dependencies, but also
// share expansion nodes with all other resource modes. We
// can't use graphNodeTemporaryValue because then all
// resources will be caught by the previous case here.
if n, ok := n.(GraphNodeConfigResource); ok && n.ResourceAddr().Resource.Mode == addrs.EphemeralResourceMode {
return
}
// Any nodes that expand instances are kept when their
// instances may need to be evaluated.
for _, v := range g.UpEdges(n) {

Loading…
Cancel
Save