Merge pull request #4534 from willthames/ec2_mount_volumes
Added the ability to add EBS volumes to EC2 instances at creation time
This commit is contained in:
commit
8ff1b06879
1 changed files with 79 additions and 0 deletions
|
@ -191,6 +191,13 @@ options:
|
|||
required: false
|
||||
default: 'present'
|
||||
aliases: []
|
||||
volumes:
|
||||
version_added: "1.5"
|
||||
description:
|
||||
- a list of volume dicts, each containing device name and optionally ephemeral id or snapshot id. Size and type (and number of iops for io device type) must be specified for a new volume or a root volume, and may be passed for a snapshot volume. For any volume, a volume size less than 1 will be interpreted as a request not to create the volume.
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
|
||||
requirements: [ "boto" ]
|
||||
author: Seth Vidal, Tim Gerla, Lester Wade
|
||||
|
@ -223,6 +230,23 @@ EXAMPLES = '''
|
|||
instance_tags: '{"db":"postgres"}'
|
||||
monitoring=yes
|
||||
|
||||
# Single instance with additional IOPS volume from snapshot
|
||||
local_action:
|
||||
module: ec2
|
||||
keypair: mykey
|
||||
group: webserver
|
||||
instance_type: m1.large
|
||||
image: ami-6e649707
|
||||
wait: yes
|
||||
wait_timeout: 500
|
||||
volumes:
|
||||
- device_name: /dev/sdb
|
||||
snapshot: snap-abcdef12
|
||||
device_type: io1
|
||||
iops: 1000
|
||||
volume_size: 100
|
||||
monitoring=yes
|
||||
|
||||
# Multiple groups example
|
||||
local_action:
|
||||
module: ec2
|
||||
|
@ -236,6 +260,22 @@ local_action:
|
|||
instance_tags: '{"db":"postgres"}'
|
||||
monitoring=yes
|
||||
|
||||
# Multiple instances with additional volume from snapshot
|
||||
local_action:
|
||||
module: ec2
|
||||
keypair: mykey
|
||||
group: webserver
|
||||
instance_type: m1.large
|
||||
image: ami-6e649707
|
||||
wait: yes
|
||||
wait_timeout: 500
|
||||
count: 5
|
||||
volumes:
|
||||
- device_name: /dev/sdb
|
||||
snapshot: snap-abcdef12
|
||||
volume_size: 10
|
||||
monitoring=yes
|
||||
|
||||
# VPC example
|
||||
- local_action:
|
||||
module: ec2
|
||||
|
@ -296,6 +336,7 @@ import time
|
|||
|
||||
try:
|
||||
import boto.ec2
|
||||
from boto.ec2.blockdevicemapping import BlockDeviceType, BlockDeviceMapping
|
||||
from boto.exception import EC2ResponseError
|
||||
except ImportError:
|
||||
print "failed=True msg='boto required for this module'"
|
||||
|
@ -364,6 +405,30 @@ def boto_supports_profile_name_arg(ec2):
|
|||
run_instances_method = getattr(ec2, 'run_instances')
|
||||
return 'instance_profile_name' in run_instances_method.func_code.co_varnames
|
||||
|
||||
def create_block_device(module, ec2, volume):
|
||||
# Not aware of a way to determine this programatically
|
||||
# http://aws.amazon.com/about-aws/whats-new/2013/10/09/ebs-provisioned-iops-maximum-iops-gb-ratio-increased-to-30-1/
|
||||
MAX_IOPS_TO_SIZE_RATIO = 30
|
||||
if 'snapshot' not in volume and 'ephemeral' not in volume:
|
||||
if 'volume_size' not in volume:
|
||||
module.fail_json(msg = 'Size must be specified when creating a new volume or modifying the root volume')
|
||||
if 'snapshot' in volume:
|
||||
if 'device_type' in volume and volume.get('device_type') == 'io1' and 'iops' not in volume:
|
||||
module.fail_json(msg = 'io1 volumes must have an iops value set')
|
||||
if 'iops' in volume:
|
||||
snapshot = ec2.get_all_snapshots(snapshot_ids=[volume['snapshot']])[0]
|
||||
size = volume.get('volume_size', snapshot.volume_size)
|
||||
if int(volume['iops']) > MAX_IOPS_TO_SIZE_RATIO * size:
|
||||
module.fail_json(msg = 'IOPS must be at most %d times greater than size' % MAX_IOPS_TO_SIZE_RATIO)
|
||||
if 'ephemeral' in volume:
|
||||
if 'snapshot' in volume:
|
||||
module.fail_json(msg = 'Cannot set both ephemeral and snapshot')
|
||||
return BlockDeviceType(snapshot_id=volume.get('snapshot'),
|
||||
ephemeral_name=volume.get('ephemeral'),
|
||||
size=volume.get('volume_size'),
|
||||
volume_type=volume.get('device_type'),
|
||||
delete_on_termination=volume.get('delete_on_termination', False),
|
||||
iops=volume.get('iops'))
|
||||
|
||||
def create_instances(module, ec2):
|
||||
"""
|
||||
|
@ -397,6 +462,7 @@ def create_instances(module, ec2):
|
|||
assign_public_ip = module.boolean(module.params.get('assign_public_ip'))
|
||||
private_ip = module.params.get('private_ip')
|
||||
instance_profile_name = module.params.get('instance_profile_name')
|
||||
volumes = module.params.get('volumes')
|
||||
|
||||
# group_id and group_name are exclusive of each other
|
||||
if group_id and group_name:
|
||||
|
@ -489,6 +555,18 @@ def create_instances(module, ec2):
|
|||
else:
|
||||
params['security_groups'] = group_name
|
||||
|
||||
if volumes:
|
||||
bdm = BlockDeviceMapping()
|
||||
for volume in volumes:
|
||||
if 'device_name' not in volume:
|
||||
module.fail_json(msg = 'Device name must be set for volume')
|
||||
# Minimum volume size is 1GB. We'll use volume size explicitly set to 0
|
||||
# to be a signal not to create this volume
|
||||
if 'volume_size' not in volume or int(volume['volume_size']) > 0:
|
||||
bdm[volume['device_name']] = create_block_device(module, ec2, volume)
|
||||
|
||||
params['block_device_map'] = bdm
|
||||
|
||||
res = ec2.run_instances(**params)
|
||||
except boto.exception.BotoServerError, e:
|
||||
module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
|
||||
|
@ -641,6 +719,7 @@ def main():
|
|||
instance_profile_name = dict(),
|
||||
instance_ids = dict(type='list'),
|
||||
state = dict(default='present'),
|
||||
volumes = dict(type='list'),
|
||||
)
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue