diff --git a/README.rst b/README.rst index 4579982..4506264 100644 --- a/README.rst +++ b/README.rst @@ -162,6 +162,10 @@ The ``ec2`` key configures the EC2 instances created by auto-scaling groups (ASG The path of the linux device to attach the instance to ``VolumeSize`` Size in gigabytes of the EBS volume + ``VolumeType (optional)`` + The type of the volume to create. One of standard (default), gp2 or io1 (see `AWS API reference `_) + ``Iops (Required for io1 type)`` + The Iops value to assign to the io1 volume type. Example:: @@ -172,7 +176,12 @@ The ``ec2`` key configures the EC2 instances created by auto-scaling groups (ASG - DeviceName: /dev/sda1 VolumeSize: 10 - DeviceName: /dev/sdf + VolumeType: gp2 VolumeSize: 100 + - DeviceName: /dev/sdh + VolumeType: io1 + VolumeSize: 80 + Iops: 1200 :``security_groups``: Dictionary of security groups to create and add the EC2 instances to. The key is the name of the security group and the value is a list of ingress rules following the `Cloudformation reference `_ diff --git a/bootstrap_cfn/config.py b/bootstrap_cfn/config.py index c48d5b7..932e2c5 100644 --- a/bootstrap_cfn/config.py +++ b/bootstrap_cfn/config.py @@ -865,10 +865,29 @@ def ec2(self): devices = [] try: for i in data['block_devices']: + device_name = i['DeviceName'] + volume_size = i.get('VolumeSize', 20) + volume_type = i.get('VolumeType', 'standard') + iops = i.get('Iops', None) + # Check we have a permitted volume type + if volume_type not in ['standard', 'gp2', 'io1']: + raise errors.CfnConfigError("config: Volume type '%s' but must be one of standard', 'gp2' or 'io1" + % (volume_type)) + # We need to specifiy iops if we have a volume type of io1 + if volume_type == 'io1' and not iops: + raise errors.CfnConfigError("config: Volume type io1 must have Iops defined") + + # We dont set a default for iops and troposphere doesnt handle this well + if not iops: + ebs = EBSBlockDevice(VolumeType=volume_type, VolumeSize=volume_size) + else: + ebs = EBSBlockDevice(VolumeType=volume_type, VolumeSize=volume_size, Iops=iops) + devices.append(BlockDeviceMapping( - DeviceName=i['DeviceName'], - Ebs=EBSBlockDevice(VolumeSize=i['VolumeSize']), + DeviceName=device_name, + Ebs=ebs )) + except KeyError: devices.append(BlockDeviceMapping( DeviceName="/dev/sda1", diff --git a/tests/sample-project.yaml b/tests/sample-project.yaml index f6d287b..a865bc8 100644 --- a/tests/sample-project.yaml +++ b/tests/sample-project.yaml @@ -15,7 +15,12 @@ dev: - DeviceName: /dev/sda1 VolumeSize: 10 - DeviceName: /dev/sdf + VolumeType: gp2 VolumeSize: 10 + - DeviceName: /dev/sdg + VolumeType: io1 + VolumeSize: 20 + Iops: 100 security_groups: AnotherSG: - IpProtocol: tcp diff --git a/tests/test.py b/tests/test.py index 13ece13..c00486d 100644 --- a/tests/test.py +++ b/tests/test.py @@ -29,7 +29,12 @@ def setUp(self): 'block_devices': [{'DeviceName': '/dev/sda1', 'VolumeSize': 10}, {'DeviceName': '/dev/sdf', - 'VolumeSize': 10}], + 'VolumeType': 'gp2', + 'VolumeSize': 10}, + {'DeviceName': '/dev/sdg', + 'VolumeType': 'io1', + 'VolumeSize': 20, + 'Iops': 100}], 'parameters': {'InstanceType': 't2.micro', 'KeyName': 'default'}, 'security_groups': [{'CidrIp': '0.0.0.0/0', diff --git a/tests/tests.py b/tests/tests.py index 5814b6f..8ba25d5 100755 --- a/tests/tests.py +++ b/tests/tests.py @@ -1295,11 +1295,15 @@ def test_ec2(self): BlockDeviceMappings=[ { "DeviceName": "/dev/sda1", - "Ebs": {"VolumeSize": 10} + "Ebs": {"VolumeSize": 10, "VolumeType": "standard"} }, { "DeviceName": "/dev/sdf", - "Ebs": {"VolumeSize": 10} + "Ebs": {"VolumeSize": 10, "VolumeType": "gp2"} + }, + { + "DeviceName": "/dev/sdg", + "Ebs": {"VolumeSize": 20, "VolumeType": "io1", "Iops": 100} } ], KeyName="default", @@ -1345,11 +1349,15 @@ def test_launchconfig_userdata(self): BlockDeviceMappings=[ { "DeviceName": "/dev/sda1", - "Ebs": {"VolumeSize": 10} + "Ebs": {"VolumeSize": 10, "VolumeType": "standard"} }, { "DeviceName": "/dev/sdf", - "Ebs": {"VolumeSize": 10} + "Ebs": {"VolumeSize": 10, "VolumeType": "gp2"} + }, + { + "DeviceName": "/dev/sdg", + "Ebs": {"VolumeSize": 20, "VolumeType": "io1", "Iops": 100} } ], KeyName="default",