-
Notifications
You must be signed in to change notification settings - Fork 343
/
Copy pathmain.yml
397 lines (341 loc) · 12.3 KB
/
main.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
---
# Tests for EC2 Snapshot
#
# Tests amazon.aws.ec2_snapshot:
# - Snapshot creation
# - Create with last_snapshot_min_age
# - Snapshot deletion
#
# Tests amazon.aws.ec2_snapshot_info:
# - Listing snapshots for filter: tag
#
- name: Integration testing for ec2_snapshot
module_defaults:
group/aws:
access_key: "{{ aws_access_key }}"
secret_key: "{{ aws_secret_key }}"
session_token: "{{ security_token | default(omit) }}"
region: "{{ aws_region }}"
block:
- name: Gather availability zones
amazon.aws.aws_az_info:
register: azs
- name: Run tasks for testing snapshot createVolumePermissions modifications
ansible.builtin.import_tasks: test_modify_create_volume_permissions.yml
- name: Create a detached volume without tags
amazon.aws.ec2_vol:
volume_size: 1
zone: "{{ azs.availability_zones[0].zone_name }}"
register: volume_detached
# Capture snapshot of this detached volume and assert the results
- name: Create a snapshot of detached volume without tags and store results
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_detached.volume_id }}"
register: untagged_snapshot
- ansible.builtin.assert:
that:
- untagged_snapshot is changed
- untagged_snapshot.snapshots| length == 1
- untagged_snapshot.snapshots[0].volume_id == volume_detached.volume_id
- name: Setup an instance for testing, make sure volumes are attached before next task
amazon.aws.ec2_instance:
name: "{{ resource_prefix }}"
instance_type: t2.nano
image_id: "{{ ec2_ami_id }}"
volumes:
- device_name: /dev/xvda
ebs:
volume_size: 8
delete_on_termination: true
state: running
wait: true
register: instance
- ansible.builtin.set_fact:
volume_id: "{{ instance.instances[0].block_device_mappings[0].ebs.volume_id }}"
instance_id: "{{ instance.instances[0].instance_id }}"
device_name: "{{ instance.instances[0].block_device_mappings[0].device_name }}"
- name: Take snapshot (check mode)
amazon.aws.ec2_snapshot:
instance_id: "{{ instance_id }}"
device_name: "{{ device_name }}"
snapshot_tags:
Test: "{{ resource_prefix }}"
check_mode: true
register: result
- ansible.builtin.assert:
that:
- result is changed
- name: Take snapshot of volume
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
register: result
# The Name tag is created automatically as the instance_name; ie the resource_prefix
- name: Get info about snapshots
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: info_result
- ansible.builtin.assert:
that:
- result is changed
- info_result is not changed
- info_result.snapshots| length == 1
- info_result.snapshots[0].snapshot_id == result.snapshot_id
- info_result.snapshots[0].volume_id == result.volume_id
- info_result.snapshots[0].volume_size == result.volume_size
- info_result.snapshots[0].tags == result.tags
- name: Get info about snapshots (check_mode)
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: info_check
check_mode: true
- ansible.builtin.assert:
that:
- info_check is not changed
- info_check.snapshots| length == 1
- info_check.snapshots[0].snapshot_id == result.snapshot_id
- info_check.snapshots[0].volume_id == result.volume_id
- info_check.snapshots[0].volume_size == result.volume_size
- info_check.snapshots[0].tags == result.tags
- name: Take snapshot if most recent >1hr (False) (check mode)
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
snapshot_tags:
Name: "{{ resource_prefix }}"
last_snapshot_min_age: 60
check_mode: true
register: result
- ansible.builtin.assert:
that:
- result is not changed
- name: Take snapshot if most recent >1hr (False)
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
last_snapshot_min_age: 60
register: result
- name: Get info about snapshots
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: info_result
- ansible.builtin.assert:
that:
- result is not changed
- info_result.snapshots| length == 1
- name: Pause so we can do a last_snapshot_min_age test
ansible.builtin.pause:
minutes: 1
- name: Take snapshot if most recent >1min (True) (check mode)
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
snapshot_tags:
Name: "{{ resource_prefix }}"
last_snapshot_min_age: 1
check_mode: true
register: result
- ansible.builtin.assert:
that:
- result is changed
- name: Take snapshot if most recent >1min (True)
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
last_snapshot_min_age: 1
register: result
- name: Get info about snapshots
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: info_result
- ansible.builtin.assert:
that:
- result is changed
- info_result.snapshots| length == 2
- result.snapshot_id in ( info_result.snapshots | map(attribute='snapshot_id') | list )
- name: Take snapshot with a tag (check mode)
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
snapshot_tags:
MyTag: "{{ resource_prefix }}"
check_mode: true
register: result
- ansible.builtin.assert:
that:
- result is changed
- name: Take snapshot and tag it
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
snapshot_tags:
MyTag: "{{ resource_prefix }}"
register: tagged_result
- name: Get info about snapshots by tag
amazon.aws.ec2_snapshot_info:
filters:
tag:MyTag: "{{ resource_prefix }}"
register: tag_info_result
- ansible.builtin.set_fact:
tagged_snapshot_id: "{{ tag_info_result.snapshots[0].snapshot_id }}"
- ansible.builtin.assert:
that:
- tagged_result is changed
- tagged_result.tags| length == 2
- tag_info_result.snapshots| length == 1
- tagged_result.tags.MyTag == resource_prefix
- tagged_result.snapshot_id == tagged_snapshot_id
- name: Get info about all snapshots for this test
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: info_result
- ansible.builtin.assert:
that:
- info_result.snapshots | length == 3
- name: Generate extra snapshots
amazon.aws.ec2_snapshot:
volume_id: "{{ volume_id }}"
snapshot_tags:
ResourcePrefix: "{{ resource_prefix }}"
loop: "{{ range(1, 6, 1) | list }}"
loop_control:
# Anything under 15 will trigger SnapshotCreationPerVolumeRateExceeded,
# this should now be automatically handled, but pause a little anyway to
# avoid being aggressive
pause: 15
label: Generate extra snapshots - {{ item }}
# Retrieve snapshots in paginated mode
- name: Get snapshots in paginated mode using max_results option
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
max_results: 5
register: info_result
- ansible.builtin.assert:
that:
- info_result.next_token_id is defined
# Pagination : 2nd request
- name: Get snapshots for a second paginated request
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
next_token_id: "{{ info_result.next_token_id }}"
max_results: 5
register: info_result_2
# note: *MAX* 5 results, sometimes they'll throw us fewer...
# 8 is the absolute max it should find
- ansible.builtin.assert:
that:
- (length_1 | int ) + (length_2 | int) <= 8
vars:
length_1: "{{ info_result.snapshots | length }}"
length_2: "{{ info_result_2.snapshots | length }}"
# delete the tagged snapshot - check mode
- name: Delete the tagged snapshot (check mode)
amazon.aws.ec2_snapshot:
state: absent
snapshot_id: "{{ tagged_snapshot_id }}"
register: delete_result_check_mode
check_mode: true
- ansible.builtin.assert:
that:
- delete_result_check_mode is changed
# check that snapshot_ids and max_results are mutually exclusive
- name: Check that max_results and snapshot_ids are mutually exclusive
amazon.aws.ec2_snapshot_info:
snapshot_ids:
- "{{ tagged_snapshot_id }}"
max_results: 5
ignore_errors: true
register: info_result
- name: Assert that operation failed
ansible.builtin.assert:
that:
- info_result is failed
# check that snapshot_ids and next_token_id are mutually exclusive
- name: Check that snapshot_ids and next_token_id are mutually exclusive
amazon.aws.ec2_snapshot_info:
snapshot_ids:
- "{{ tagged_snapshot_id }}"
next_token_id: random_value_token
ignore_errors: true
register: info_result
- name: Assert that operation failed
ansible.builtin.assert:
that:
- info_result is failed
# delete the tagged snapshot
- name: Delete the tagged snapshot
amazon.aws.ec2_snapshot:
state: absent
snapshot_id: "{{ tagged_snapshot_id }}"
# delete the tagged snapshot again (results in InvalidSnapshot.NotFound)
- name: Delete already removed snapshot (check mode)
amazon.aws.ec2_snapshot:
state: absent
snapshot_id: "{{ tagged_snapshot_id }}"
register: delete_result_second_check_mode
check_mode: true
- ansible.builtin.assert:
that:
- delete_result_second_check_mode is not changed
- name: Delete already removed snapshot (idempotent)
amazon.aws.ec2_snapshot:
state: absent
snapshot_id: "{{ tagged_snapshot_id }}"
register: delete_result_second_idempotent
- ansible.builtin.assert:
that:
- delete_result_second_idempotent is not changed
- name: Get info about all snapshots for this test
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: info_result
- ansible.builtin.assert:
that:
- info_result.snapshots| length == 7
- tagged_snapshot_id not in ( info_result.snapshots | map(attribute='snapshot_id') | list )
- name: Delete snapshots
amazon.aws.ec2_snapshot:
state: absent
snapshot_id: "{{ item.snapshot_id }}"
with_items: "{{ info_result.snapshots }}"
- name: Get info about all snapshots for this test
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: info_result
- ansible.builtin.assert:
that:
- info_result.snapshots| length == 0
always:
- name: Snapshots to delete
amazon.aws.ec2_snapshot_info:
filters:
tag:Name: "{{ resource_prefix }}"
register: tagged_snapshots
- name: Delete tagged snapshots
amazon.aws.ec2_snapshot:
state: absent
snapshot_id: "{{ item.snapshot_id }}"
with_items: "{{ tagged_snapshots.snapshots }}"
ignore_errors: true
- name: Delete instance
amazon.aws.ec2_instance:
instance_ids: "{{ instance_id }}"
state: absent
ignore_errors: true
- name: Delete volume
amazon.aws.ec2_vol:
id: "{{ volume_id }}"
state: absent
ignore_errors: true
- name: Delete detached and untagged volume
amazon.aws.ec2_vol:
id: "{{ volume_detached.volume_id }}"
state: absent
ignore_errors: true
- name: Delete untagged snapshot
amazon.aws.ec2_snapshot:
state: absent
snapshot_id: "{{ untagged_snapshot.snapshot_id }}"
ignore_errors: true