summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Coca <bcoca@ansible.com>2016-01-18 08:20:26 -0500
committerBrian Coca <bcoca@ansible.com>2016-01-18 08:20:26 -0500
commitce8da3836444a3709a0d60e4806f2655a11dccc8 (patch)
tree7768a936e4f76401b7c3136b9fe1f366e645e5e8
parent7a0b4882449f1c9730425f0055f9a1e664e7d13b (diff)
parent56fa475dcbbd23f4d08141ec15ee4016e47b2826 (diff)
downloadansible-modules-core-ce8da3836444a3709a0d60e4806f2655a11dccc8.tar.gz
Merge pull request #2324 from Constantin07/update_ec2_vol
ec2_vol.py - Added 'delete_on_termination" option for volume attachment action
-rw-r--r--cloud/amazon/ec2_vol.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/cloud/amazon/ec2_vol.py b/cloud/amazon/ec2_vol.py
index 4f1dbf33..b34d60f6 100644
--- a/cloud/amazon/ec2_vol.py
+++ b/cloud/amazon/ec2_vol.py
@@ -67,6 +67,12 @@ options:
- device id to override device mapping. Assumes /dev/sdf for Linux/UNIX and /dev/xvdf for Windows.
required: false
default: null
+ delete_on_termination:
+ description:
+ - When set to "yes", the volume will be deleted upon instance termination.
+ required: false
+ default: "no"
+ choices: ["yes", "no"]
zone:
description:
- zone in which to create the volume, if unset uses the zone the instance is in (if set)
@@ -173,6 +179,56 @@ EXAMPLES = '''
volume_size: 50
volume_type: gp2
device_name: /dev/xvdf
+
+# Attach an existing volume to instance. The volume will be deleted upon instance termination.
+- ec2_vol:
+ instance: XXXXXX
+ id: XXXXXX
+ device_name: /dev/sdf
+ delete_on_termination: yes
+'''
+
+RETURN = '''
+device:
+ description: device name of attached volume
+ returned: when success
+ type: string
+ sample: "/def/sdf"
+volume_id:
+ description: the id of volume
+ returned: when success
+ type: string
+ sample: "vol-35b333d9"
+volume_type:
+ description: the volume type
+ returned: when success
+ type: string
+ sample: "standard"
+volume:
+ description: a dictionary containing detailed attributes of the volume
+ returned: when success
+ type: string
+ sample: {
+ "attachment_set": {
+ "attach_time": "2015-10-23T00:22:29.000Z",
+ "deleteOnTermination": "false",
+ "device": "/dev/sdf",
+ "instance_id": "i-8356263c",
+ "status": "attached"
+ },
+ "create_time": "2015-10-21T14:36:08.870Z",
+ "encrypted": false,
+ "id": "vol-35b333d9",
+ "iops": null,
+ "size": 1,
+ "snapshot_id": "",
+ "status": "in-use",
+ "tags": {
+ "env": "dev"
+ },
+ "type": "standard",
+ "zone": "us-east-1b"
+ }
'''
import time
@@ -182,6 +238,7 @@ from distutils.version import LooseVersion
try:
import boto.ec2
from boto.exception import BotoServerError
+ from boto.ec2.blockdevicemapping import BlockDeviceType, BlockDeviceMapping
HAS_BOTO = True
except ImportError:
HAS_BOTO = False
@@ -222,6 +279,7 @@ def get_volume(module, ec2):
module.fail_json(msg="Found more than one volume in zone (if specified) with name: %s" % name)
return vols[0]
+
def get_volumes(module, ec2):
instance = module.params.get('instance')
@@ -235,6 +293,7 @@ def get_volumes(module, ec2):
module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
return vols
+
def delete_volume(module, ec2):
volume_id = module.params['id']
try:
@@ -245,6 +304,7 @@ def delete_volume(module, ec2):
module.exit_json(changed=False)
module.fail_json(msg=ec2_error.message)
+
def boto_supports_volume_encryption():
"""
Check if Boto library supports encryption of EBS volumes (added in 2.29.0)
@@ -292,6 +352,7 @@ def create_volume(module, ec2, zone):
def attach_volume(module, ec2, volume, instance):
device_name = module.params.get('device_name')
+ delete_on_termination = module.params.get('delete_on_termination')
changed = False
# If device_name isn't set, make a choice based on best practices here:
@@ -315,6 +376,9 @@ def attach_volume(module, ec2, volume, instance):
if adata.instance_id != instance.id:
module.fail_json(msg = "Volume %s is already attached to another instance: %s"
% (volume.id, adata.instance_id))
+ else:
+ # Volume is already attached to right instance
+ changed = modify_dot_attribute(module, ec2, instance, device_name)
else:
try:
volume.attach(instance.id, device_name)
@@ -325,8 +389,41 @@ def attach_volume(module, ec2, volume, instance):
except boto.exception.BotoServerError, e:
module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
+ modify_dot_attribute(module, ec2, instance, device_name)
+
return volume, changed
+
+def modify_dot_attribute(module, ec2, instance, device_name):
+ """ Modify delete_on_termination attribute """
+
+ delete_on_termination = module.params.get('delete_on_termination')
+ changed = False
+
+ try:
+ instance.update()
+ dot = instance.block_device_mapping[device_name].delete_on_termination
+ except boto.exception.BotoServerError, e:
+ module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
+
+ if delete_on_termination != dot:
+ try:
+ bdt = BlockDeviceType(delete_on_termination=delete_on_termination)
+ bdm = BlockDeviceMapping()
+ bdm[device_name] = bdt
+
+ ec2.modify_instance_attribute(instance_id=instance.id, attribute='blockDeviceMapping', value=bdm)
+
+ while instance.block_device_mapping[device_name].delete_on_termination != delete_on_termination:
+ time.sleep(3)
+ instance.update()
+ changed = True
+ except boto.exception.BotoServerError, e:
+ module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
+
+ return changed
+
+
def detach_volume(module, ec2, volume):
changed = False
@@ -341,6 +438,7 @@ def detach_volume(module, ec2, volume):
return volume, changed
+
def get_volume_info(volume, state):
# If we're just listing volumes then do nothing, else get the latest update for the volume
@@ -352,6 +450,7 @@ def get_volume_info(volume, state):
volume_info = {
'create_time': volume.create_time,
+ 'encrypted': volume.encrypted,
'id': volume.id,
'iops': volume.iops,
'size': volume.size,
@@ -367,9 +466,12 @@ def get_volume_info(volume, state):
},
'tags': volume.tags
}
+ if hasattr(attachment, 'deleteOnTermination'):
+ volume_info['attachment_set']['deleteOnTermination'] = attachment.deleteOnTermination
return volume_info
+
def main():
argument_spec = ec2_argument_spec()
argument_spec.update(dict(
@@ -381,6 +483,7 @@ def main():
iops = dict(),
encrypted = dict(type='bool', default=False),
device_name = dict(),
+ delete_on_termination = dict(type='bool', default=False),
zone = dict(aliases=['availability_zone', 'aws_zone', 'ec2_zone']),
snapshot = dict(),
state = dict(choices=['absent', 'present', 'list'], default='present')