@@ -14,9 +14,11 @@ import (
14
14
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
15
15
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
16
16
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
17
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
17
18
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
18
19
"github.com/hashicorp/terraform-provider-aws/internal/conns"
19
20
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
21
+ tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
20
22
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
21
23
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
22
24
"github.com/hashicorp/terraform-provider-aws/internal/verify"
@@ -25,12 +27,13 @@ import (
25
27
26
28
// @SDKResource("aws_fsx_backup", name="Backup")
27
29
// @Tags(identifierAttribute="arn")
28
- func ResourceBackup () * schema.Resource {
30
+ func resourceBackup () * schema.Resource {
29
31
return & schema.Resource {
30
32
CreateWithoutTimeout : resourceBackupCreate ,
31
33
ReadWithoutTimeout : resourceBackupRead ,
32
34
UpdateWithoutTimeout : resourceBackupUpdate ,
33
35
DeleteWithoutTimeout : resourceBackupDelete ,
36
+
34
37
Importer : & schema.ResourceImporter {
35
38
StateContext : schema .ImportStatePassthroughContext ,
36
39
},
@@ -102,34 +105,27 @@ func resourceBackupCreate(ctx context.Context, d *schema.ResourceData, meta inte
102
105
return sdkdiag .AppendErrorf (diags , "creating FSx Backup: %s" , "can only specify either file_system_id or volume_id" )
103
106
}
104
107
105
- result , err := conn .CreateBackupWithContext (ctx , input )
108
+ output , err := conn .CreateBackupWithContext (ctx , input )
109
+
106
110
if err != nil {
107
111
return sdkdiag .AppendErrorf (diags , "creating FSx Backup: %s" , err )
108
112
}
109
113
110
- d .SetId (aws .StringValue (result .Backup .BackupId ))
114
+ d .SetId (aws .StringValue (output .Backup .BackupId ))
111
115
112
- log .Println ("[DEBUG] Waiting for FSx backup to become available" )
113
116
if _ , err := waitBackupAvailable (ctx , conn , d .Id ()); err != nil {
114
- return sdkdiag .AppendErrorf (diags , "waiting for FSx Backup (%s) to be available : %s" , d .Id (), err )
117
+ return sdkdiag .AppendErrorf (diags , "waiting for FSx Backup (%s) create : %s" , d .Id (), err )
115
118
}
116
119
117
120
return append (diags , resourceBackupRead (ctx , d , meta )... )
118
121
}
119
122
120
- func resourceBackupUpdate (ctx context.Context , d * schema.ResourceData , meta interface {}) diag.Diagnostics {
121
- var diags diag.Diagnostics
122
-
123
- // Tags only.
124
-
125
- return append (diags , resourceBackupRead (ctx , d , meta )... )
126
- }
127
-
128
123
func resourceBackupRead (ctx context.Context , d * schema.ResourceData , meta interface {}) diag.Diagnostics {
129
124
var diags diag.Diagnostics
130
125
conn := meta .(* conns.AWSClient ).FSxConn (ctx )
131
126
132
- backup , err := FindBackupByID (ctx , conn , d .Id ())
127
+ backup , err := findBackupByID (ctx , conn , d .Id ())
128
+
133
129
if ! d .IsNewResource () && tfresource .NotFound (err ) {
134
130
log .Printf ("[WARN] FSx Backup (%s) not found, removing from state" , d .Id ())
135
131
d .SetId ("" )
@@ -141,17 +137,12 @@ func resourceBackupRead(ctx context.Context, d *schema.ResourceData, meta interf
141
137
}
142
138
143
139
d .Set ("arn" , backup .ResourceARN )
144
- d .Set ("type" , backup .Type )
145
-
146
140
if backup .FileSystem != nil {
147
- fs := backup .FileSystem
148
- d .Set ("file_system_id" , fs .FileSystemId )
141
+ d .Set ("file_system_id" , backup .FileSystem .FileSystemId )
149
142
}
150
-
151
143
d .Set ("kms_key_id" , backup .KmsKeyId )
152
-
153
144
d .Set ("owner_id" , backup .OwnerId )
154
-
145
+ d . Set ( "type" , backup . Type )
155
146
if backup .Volume != nil {
156
147
d .Set ("volume_id" , backup .Volume .VolumeId )
157
148
}
@@ -161,28 +152,139 @@ func resourceBackupRead(ctx context.Context, d *schema.ResourceData, meta interf
161
152
return diags
162
153
}
163
154
155
+ func resourceBackupUpdate (ctx context.Context , d * schema.ResourceData , meta interface {}) diag.Diagnostics {
156
+ var diags diag.Diagnostics
157
+
158
+ // Tags only.
159
+
160
+ return append (diags , resourceBackupRead (ctx , d , meta )... )
161
+ }
162
+
164
163
func resourceBackupDelete (ctx context.Context , d * schema.ResourceData , meta interface {}) diag.Diagnostics {
165
164
var diags diag.Diagnostics
166
165
conn := meta .(* conns.AWSClient ).FSxConn (ctx )
167
166
168
- request := & fsx.DeleteBackupInput {
167
+ log .Printf ("[INFO] Deleting FSx Backup: %s" , d .Id ())
168
+ _ , err := conn .DeleteBackupWithContext (ctx , & fsx.DeleteBackupInput {
169
169
BackupId : aws .String (d .Id ()),
170
- }
170
+ })
171
171
172
- log .Printf ("[INFO] Deleting FSx Backup: %s" , d .Id ())
173
- _ , err := conn .DeleteBackupWithContext (ctx , request )
172
+ if tfawserr .ErrCodeEquals (err , fsx .ErrCodeBackupNotFound ) {
173
+ return diags
174
+ }
174
175
175
176
if err != nil {
176
- if tfawserr .ErrCodeEquals (err , fsx .ErrCodeBackupNotFound ) {
177
- return diags
178
- }
179
177
return sdkdiag .AppendErrorf (diags , "deleting FSx Backup (%s): %s" , d .Id (), err )
180
178
}
181
179
182
- log .Println ("[DEBUG] Waiting for backup to delete" )
183
180
if _ , err := waitBackupDeleted (ctx , conn , d .Id ()); err != nil {
184
- return sdkdiag .AppendErrorf (diags , "waiting for FSx Backup (%s) to deleted : %s" , d .Id (), err )
181
+ return sdkdiag .AppendErrorf (diags , "waiting for FSx Backup (%s) delete : %s" , d .Id (), err )
185
182
}
186
183
187
184
return diags
188
185
}
186
+
187
+ func findBackupByID (ctx context.Context , conn * fsx.FSx , id string ) (* fsx.Backup , error ) {
188
+ input := & fsx.DescribeBackupsInput {
189
+ BackupIds : aws .StringSlice ([]string {id }),
190
+ }
191
+
192
+ return findBackup (ctx , conn , input , tfslices .PredicateTrue [* fsx.Backup ]())
193
+ }
194
+
195
+ func findBackup (ctx context.Context , conn * fsx.FSx , input * fsx.DescribeBackupsInput , filter tfslices.Predicate [* fsx.Backup ]) (* fsx.Backup , error ) {
196
+ output , err := findBackups (ctx , conn , input , filter )
197
+
198
+ if err != nil {
199
+ return nil , err
200
+ }
201
+
202
+ return tfresource .AssertSinglePtrResult (output )
203
+ }
204
+
205
+ func findBackups (ctx context.Context , conn * fsx.FSx , input * fsx.DescribeBackupsInput , filter tfslices.Predicate [* fsx.Backup ]) ([]* fsx.Backup , error ) {
206
+ var output []* fsx.Backup
207
+
208
+ err := conn .DescribeBackupsPagesWithContext (ctx , input , func (page * fsx.DescribeBackupsOutput , lastPage bool ) bool {
209
+ if page == nil {
210
+ return ! lastPage
211
+ }
212
+
213
+ for _ , v := range page .Backups {
214
+ if v != nil && filter (v ) {
215
+ output = append (output , v )
216
+ }
217
+ }
218
+
219
+ return ! lastPage
220
+ })
221
+
222
+ if tfawserr .ErrCodeEquals (err , fsx .ErrCodeFileSystemNotFound ) || tfawserr .ErrCodeEquals (err , fsx .ErrCodeBackupNotFound ) {
223
+ return nil , & retry.NotFoundError {
224
+ LastError : err ,
225
+ LastRequest : input ,
226
+ }
227
+ }
228
+
229
+ if err != nil {
230
+ return nil , err
231
+ }
232
+
233
+ return output , nil
234
+ }
235
+
236
+ func statusBackup (ctx context.Context , conn * fsx.FSx , id string ) retry.StateRefreshFunc {
237
+ return func () (interface {}, string , error ) {
238
+ output , err := findBackupByID (ctx , conn , id )
239
+
240
+ if tfresource .NotFound (err ) {
241
+ return nil , "" , nil
242
+ }
243
+
244
+ if err != nil {
245
+ return nil , "" , err
246
+ }
247
+
248
+ return output , aws .StringValue (output .Lifecycle ), nil
249
+ }
250
+ }
251
+
252
+ func waitBackupAvailable (ctx context.Context , conn * fsx.FSx , id string ) (* fsx.Backup , error ) {
253
+ const (
254
+ timeout = 10 * time .Minute
255
+ )
256
+ stateConf := & retry.StateChangeConf {
257
+ Pending : []string {fsx .BackupLifecycleCreating , fsx .BackupLifecyclePending , fsx .BackupLifecycleTransferring },
258
+ Target : []string {fsx .BackupLifecycleAvailable },
259
+ Refresh : statusBackup (ctx , conn , id ),
260
+ Timeout : timeout ,
261
+ }
262
+
263
+ outputRaw , err := stateConf .WaitForStateContext (ctx )
264
+
265
+ if output , ok := outputRaw .(* fsx.Backup ); ok {
266
+ return output , err
267
+ }
268
+
269
+ return nil , err
270
+ }
271
+
272
+ func waitBackupDeleted (ctx context.Context , conn * fsx.FSx , id string ) (* fsx.Backup , error ) {
273
+ const (
274
+ timeout = 10 * time .Minute
275
+ )
276
+ stateConf := & retry.StateChangeConf {
277
+ Pending : []string {fsx .FileSystemLifecycleDeleting },
278
+ Target : []string {},
279
+ Refresh : statusBackup (ctx , conn , id ),
280
+ Timeout : timeout ,
281
+ }
282
+
283
+ outputRaw , err := stateConf .WaitForStateContext (ctx )
284
+
285
+ if output , ok := outputRaw .(* fsx.Backup ); ok {
286
+ return output , err
287
+ }
288
+
289
+ return nil , err
290
+ }
0 commit comments