@@ -4,6 +4,10 @@ package resource
44import (
55 "fmt"
66
7+ "github.com/hashicorp/terraform/configs/configschema"
8+
9+ "github.com/zclconf/go-cty/cty"
10+
711 "github.com/apex/log"
812 "github.com/jckuester/terradozer/internal"
913 "github.com/jckuester/terradozer/pkg/provider"
@@ -51,40 +55,56 @@ func (r Resource) ID() string {
5155
5256// Destroy destroys a Terraform resource.
5357func (r Resource ) Destroy (dryRun bool ) error {
54- importedResources , err := r .provider .ImportResource (r .terraformType , r .id )
58+ resourceSchema , ok := r .provider .GetSchema ().ResourceTypes [r .Type ()]
59+ if ! ok {
60+ return fmt .Errorf ("failed to get schema for resource" )
61+ }
62+
63+ currentResourceState , err := r .provider .ReadResource (r .Type (), emptyValueWitId (r .ID (), resourceSchema .Block ))
5564 if err != nil {
56- return fmt .Errorf ("failed to import resource: %s" , err )
65+ return fmt .Errorf ("failed to read current state of resource: %s" , err )
5766 }
5867
59- for _ , rImported := range importedResources {
60- currentResourceState , err := r .provider .ReadResource (rImported )
61- if err != nil {
62- return fmt .Errorf ("failed to read current state of resource: %s" , err )
63- }
68+ resourceNotFound := currentResourceState .IsNull ()
69+ if resourceNotFound {
70+ return fmt .Errorf ("resource found in state doesn't exist anymore" )
71+ }
6472
65- resourceNotFound := currentResourceState .IsNull ()
66- if resourceNotFound {
67- return fmt .Errorf ("resource found in state doesn't exist anymore" )
68- }
73+ if dryRun {
74+ log .WithField ("id" , r .id ).Warn (internal .Pad (r .terraformType ))
6975
70- if dryRun {
71- log . WithField ( "id" , r . id ). Warn ( internal . Pad ( r . terraformType ))
76+ return nil
77+ }
7278
73- return nil
74- }
79+ err = r .provider .DestroyResource (r .terraformType , currentResourceState )
80+ if err != nil {
81+ log .WithError (err ).WithFields (log.Fields {
82+ "id" : r .id , "type" : r .terraformType }).Debug (internal .Pad ("failed to delete resource" ))
7583
76- err = r .provider .DestroyResource (r .terraformType , currentResourceState )
77- if err != nil {
78- log .WithError (err ).WithFields (log.Fields {
79- "id" : r .id , "type" : r .terraformType }).Debug (internal .Pad ("failed to delete resource" ))
84+ return NewRetryDestroyError (err , r )
85+ }
8086
81- return NewRetryDestroyError (err , r )
82- }
87+ log .WithField ("id" , r .id ).Error (internal .Pad (r .terraformType ))
88+
89+ return nil
90+ }
8391
84- log .WithField ("id" , r .id ).Error (internal .Pad (r .terraformType ))
92+ // emptyValueWitId returns a non-null object for the configuration block
93+ // where all of the attribute values are set to empty values except the ID attribute.
94+ //
95+ // see also github.com/hashicorp/terraform/configs/configschema/empty_value.go
96+ func emptyValueWitId (id string , block * configschema.Block ) cty.Value {
97+ vals := make (map [string ]cty.Value )
98+ for name , attrS := range block .Attributes {
99+ vals [name ] = attrS .EmptyValue ()
100+ }
101+ for name , blockS := range block .BlockTypes {
102+ vals [name ] = blockS .EmptyValue ()
85103 }
86104
87- return nil
105+ vals ["id" ] = cty .StringVal (id )
106+
107+ return cty .ObjectVal (vals )
88108}
89109
90110// DestroyResources destroys a given list of resources, which may depend on each other.
0 commit comments