Add support for encrypted AMIs that can be used to launch instances

with encrypted boot volume.
This commit is contained in:
Veli-Matti Lintu 2018-03-15 17:46:33 +02:00
parent 2c02e6875a
commit 8e24c5e795
5 changed files with 54 additions and 7 deletions

View file

@ -146,6 +146,30 @@ Example:
name: ec2
amzn-driver-version: 1.5.0
Encrypted volumes
~~~~~~~~~~~~~~~~~
Encrypted AMIs that can be used to launch instances with encrypted boot volume
are supported. Defining encryption key is optional and EC2 uses default
encryption key if one is not set. Encryption works only with EBS volumes.
- ``encrypted:``: Default: False
Valid values: ``True``, ``False``
``optional``
- ``kms_key_id:``: Default: EC2 default EBS encryption key
Valid values: arn of the KMS key
``optional``
Example:
.. code-block:: yaml
---
provider:
name: ec2
encrypted: True
kms_key_id: arn:aws:kms:us-east-1:1234567890:key/00000000-0000-0000-0000-000000000000
Image
~~~~~

View file

@ -25,6 +25,8 @@ def validate_manifest(data, validator, error):
bootloader = data['system']['bootloader']
virtualization = data['provider']['virtualization']
encrypted = data['provider'].get('encrypted', False)
kms_key_id = data['provider'].get('kms_key_id')
backing = data['volume']['backing']
partition_type = data['volume']['partitions']['type']
enhanced_networking = data['provider']['enhanced_networking'] if 'enhanced_networking' in data['provider'] else None
@ -38,6 +40,12 @@ def validate_manifest(data, validator, error):
if backing == 's3' and partition_type != 'none':
error('S3 backed AMIs currently only work with unpartitioned volumes', ['system', 'bootloader'])
if backing != 'ebs' and encrypted:
error('Encryption is supported only on EBS volumes')
if encrypted is False and kms_key_id is not None:
error('KMS Key Id can be set only when encryption is enabled')
if enhanced_networking == 'simple' and virtualization != 'hvm':
error('Enhanced networking only works with HVM virtualization', ['provider', 'virtualization'])

View file

@ -4,18 +4,26 @@ from bootstrapvz.base.fs.exceptions import VolumeError
class EBSVolume(Volume):
def create(self, conn, zone, tags=[]):
self.fsm.create(connection=conn, zone=zone, tags=tags)
def create(self, conn, zone, tags=[], encrypted=False, kms_key_id=None):
self.fsm.create(connection=conn, zone=zone, tags=tags, encrypted=encrypted, kms_key_id=kms_key_id)
def _before_create(self, e):
self.conn = e.connection
zone = e.zone
tags = e.tags
size = self.size.bytes.get_qty_in('GiB')
self.volume = self.conn.create_volume(Size=size,
AvailabilityZone=zone,
VolumeType='gp2',
TagSpecifications=[{'ResourceType': 'volume', 'Tags': tags}])
params = dict(Size=size,
AvailabilityZone=zone,
VolumeType='gp2',
TagSpecifications=[{'ResourceType': 'volume', 'Tags': tags}],
Encrypted=e.encrypted)
if e.encrypted and e.kms_key_id:
params['KmsKeyId'] = e.kms_key_id
self.volume = self.conn.create_volume(**params)
self.vol_id = self.volume['VolumeId']
waiter = self.conn.get_waiter('volume_available')
waiter.wait(VolumeIds=[self.vol_id],

View file

@ -27,6 +27,8 @@ properties:
amzn-driver-version:
type: string
pattern: "^([0-9]+\\.?){3}$"
encrypted: { type: boolean }
kms_key_id: { type: string }
required: [description, virtualization]
system:
type: object

View file

@ -16,7 +16,12 @@ class Create(Task):
formatted_tags = {k: v.format(**info.manifest_vars) for k, v in raw_tags.items()}
tags = [{'Key': k, 'Value': v} for k, v in formatted_tags.items()]
info.volume.create(info._ec2['connection'], info._ec2['host']['availabilityZone'], tags)
# EBS volumes support encryption. KMS key id is optional and default key
# is used when it is not defined.
encrypted = info.manifest.data['provider'].get('encrypted', False)
kms_key_id = info.manifest.data['provider'].get('kms_key_id')
info.volume.create(info._ec2['connection'], info._ec2['host']['availabilityZone'], tags=tags, encrypted=encrypted, kms_key_id=kms_key_id)
class Attach(Task):