|
|
|
@ -74,6 +74,12 @@ options:
|
|
|
|
|
- snapshot id to remove
|
|
|
|
|
required: false
|
|
|
|
|
version_added: "1.9"
|
|
|
|
|
snapshot_max_age:
|
|
|
|
|
description:
|
|
|
|
|
- If the volume's most recent snapshot has started less than `snapshot_max_age' minutes ago, a new snapshot will not be created.
|
|
|
|
|
required: false
|
|
|
|
|
default: 0
|
|
|
|
|
version_added: "1.9"
|
|
|
|
|
|
|
|
|
|
author: "Will Thames (@willthames)"
|
|
|
|
|
extends_documentation_fragment: aws
|
|
|
|
@ -104,6 +110,12 @@ EXAMPLES = '''
|
|
|
|
|
module: ec2_snapshot
|
|
|
|
|
snapshot_id: snap-abcd1234
|
|
|
|
|
state: absent
|
|
|
|
|
|
|
|
|
|
# Create a snapshot only if the most recent one is older than 1 hour
|
|
|
|
|
- local_action:
|
|
|
|
|
module: ec2_snapshot
|
|
|
|
|
volume_id: vol-abcdef12
|
|
|
|
|
snapshot_max_age: 60
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
import time
|
|
|
|
@ -124,8 +136,9 @@ def main():
|
|
|
|
|
instance_id = dict(),
|
|
|
|
|
snapshot_id = dict(),
|
|
|
|
|
device_name = dict(),
|
|
|
|
|
wait = dict(type='bool', default='true'),
|
|
|
|
|
wait_timeout = dict(default=0),
|
|
|
|
|
wait = dict(type='bool', default='false'),
|
|
|
|
|
wait_timeout = dict(type='int', default=0),
|
|
|
|
|
snapshot_max_age = dict(type='int', default=0),
|
|
|
|
|
snapshot_tags = dict(type='dict', default=dict()),
|
|
|
|
|
state = dict(choices=['absent','present'], default='present'),
|
|
|
|
|
)
|
|
|
|
@ -142,9 +155,13 @@ def main():
|
|
|
|
|
device_name = module.params.get('device_name')
|
|
|
|
|
wait = module.params.get('wait')
|
|
|
|
|
wait_timeout = module.params.get('wait_timeout')
|
|
|
|
|
snapshot_max_age = module.params.get('snapshot_max_age')
|
|
|
|
|
snapshot_tags = module.params.get('snapshot_tags')
|
|
|
|
|
state = module.params.get('state')
|
|
|
|
|
|
|
|
|
|
snapshot = None
|
|
|
|
|
changed = False
|
|
|
|
|
|
|
|
|
|
if not volume_id and not instance_id and not snapshot_id or volume_id and instance_id and snapshot_id:
|
|
|
|
|
module.fail_json(msg='One and only one of volume_id or instance_id or snapshot_id must be specified')
|
|
|
|
|
if instance_id and not device_name or device_name and not instance_id:
|
|
|
|
@ -175,10 +192,37 @@ def main():
|
|
|
|
|
else:
|
|
|
|
|
module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
|
|
|
|
|
|
|
|
|
|
if snapshot_max_age > 0:
|
|
|
|
|
try:
|
|
|
|
|
snapshot_max_age = snapshot_max_age * 60 # Convert to seconds
|
|
|
|
|
current_snapshots = ec2.get_all_snapshots(filters={'volume_id': volume_id})
|
|
|
|
|
# Find the most recent snapshot
|
|
|
|
|
recent = dict(start_time=0, snapshot=None)
|
|
|
|
|
for s in current_snapshots:
|
|
|
|
|
start_time = time.mktime(time.strptime(s.start_time, '%Y-%m-%dT%H:%M:%S.000Z'))
|
|
|
|
|
if start_time > recent['start_time']:
|
|
|
|
|
recent['start_time'] = start_time
|
|
|
|
|
recent['snapshot'] = s
|
|
|
|
|
|
|
|
|
|
# Adjust snapshot start time to local timezone
|
|
|
|
|
tz_adjustment = time.daylight and time.altzone or time.timezone
|
|
|
|
|
recent['start_time'] -= tz_adjustment
|
|
|
|
|
|
|
|
|
|
# See if the snapshot is younger that the given max age
|
|
|
|
|
current_time = time.mktime(time.localtime())
|
|
|
|
|
snapshot_age = current_time - recent['start_time']
|
|
|
|
|
if snapshot_age < snapshot_max_age:
|
|
|
|
|
snapshot = recent['snapshot']
|
|
|
|
|
except boto.exception.BotoServerError, e:
|
|
|
|
|
module.fail_json(msg="%s: %s" % (e.error_code, e.error_message))
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
snapshot = ec2.create_snapshot(volume_id, description=description)
|
|
|
|
|
time_waited = 0
|
|
|
|
|
# Create a new snapshot if we didn't find an existing one to use
|
|
|
|
|
if snapshot is None:
|
|
|
|
|
snapshot = ec2.create_snapshot(volume_id, description=description)
|
|
|
|
|
changed = True
|
|
|
|
|
if wait:
|
|
|
|
|
time_waited = 0
|
|
|
|
|
snapshot.update()
|
|
|
|
|
while snapshot.status != 'completed':
|
|
|
|
|
time.sleep(3)
|
|
|
|
@ -189,9 +233,9 @@ def main():
|
|
|
|
|
for k, v in snapshot_tags.items():
|
|
|
|
|
snapshot.add_tag(k, v)
|
|
|
|
|
except boto.exception.BotoServerError, e:
|
|
|
|
|
module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
|
|
|
|
|
module.fail_json(msg="%s: %s" % (e.error_code, e.error_message))
|
|
|
|
|
|
|
|
|
|
module.exit_json(changed=True, snapshot_id=snapshot.id, volume_id=snapshot.volume_id,
|
|
|
|
|
module.exit_json(changed=changed, snapshot_id=snapshot.id, volume_id=snapshot.volume_id,
|
|
|
|
|
volume_size=snapshot.volume_size, tags=snapshot.tags.copy())
|
|
|
|
|
|
|
|
|
|
# import module snippets
|
|
|
|
|