Aws-cdk: Encrypted EBS volumes for EC2 instances

Created on 26 Feb 2020  Â·  10Comments  Â·  Source: aws/aws-cdk


Support encrypted EBS volumes for EC2 instances.

Use Case


We are using the CDK to generate EC2 fleets with EBS volumes that will contain customer sensitive information. We want customers to be able to use AMIs that we make available; the way to have a public AMI launch an encrypted instance is through this new EBS functionality.

Proposed Solution


I think that the option is via AWS::EC2::Instance → BlockDeviceMappings→ebs→ Encrypted/KmsKeyId, or
AWS::EC2::LaunchTempate→BlockDeviceMappings..., or
AWS::EC2::SpotFleet→ BlockDeviceMappings...

There does not appear to be a way to specify information that would feed into the BlockDeviceMapping in the L2 ec2.Instance construct

Other

Details: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIEncryption.html

  • [ ] :wave: I may be able to implement this feature request
  • [ ] :warning: This feature might incur a breaking change

This is a :rocket: Feature Request

@aws-cdaws-ec2 efforsmall feature-request in-progress p2

Most helpful comment

FWIW, you can use the AWS-Managed key by setting the corresponding property in EbsDeviceOptions:

blockDevices: [
        {
          deviceName: '/dev/xvda',
          mappingEnabled: true,
          volume: ec2.BlockDeviceVolume.ebs(30, {
            deleteOnTermination: true,
            volumeType: ec2.EbsDeviceVolumeType.GP2,
            encrypted: true
          })
        }
      ]

Thanks for quick reply but how can I use my own KMS key (CMK) for encryption? I do not seem to have any option here?

Building on top of what @shamelesscookie pointed out, as this creates a good foundation in the underlying CloudFormation template, in Java CDK (and probably other languages) you can utilize the concept of IAspect & CfnResource to override/extended provided implementation, and in this case encrypt the root device using CMK.

Conceptually what you basically have to do is the following:

  1. Make accessible the KmsKeyId you want to use from your Stack (if you are creating one as part of the Stack), or just pass the input if the key already exists.
  2. In the visit(IConstruct node) method of the aspect implementation class you can do something like:
if (node != null && node instanceof Instance) {
            CfnResource cfnResource = (CfnResource) node.getNode().findChild("Resource");
            cfnResource.addPropertyOverride("BlockDeviceMappings.0.Ebs.KmsKeyId", this.kmsKeyId);
}
  1. In the App class of your CDK, add this after your instantiating both your stack and encryption aspect Aspects.of(myStack).add(encryptionAspectClass);

This will encrypt your root device volume with the CMK, and every other volume you can provision using the Volume construct which does take custom encryption key. The concept of overriding properties in form of Escape Hatches is also explained here. You can check it out for more details. Hope it helps.

All 10 comments

Indeed, It'll be good to create EbsVolumes and be able to set a CMK (Alias/Key).
Actually I have to create a "ec2.CfnLaunchTemplate" to do that.

Any news about adding encryption & use of CMK in BlockDeviceVolume of an aws-autoscaling for example ?

https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-autoscaling.BlockDeviceVolume.html

Any news about adding encryption & use of CMK in BlockDeviceVolume of an aws-autoscaling for example ?

https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-autoscaling.BlockDeviceVolume.html

@Cloudrage The API in the docs you reference are eventually used to create a LaunchConfiguration for the AutoScalingGroup, unfortunately, LaunchConfiguration doesn't support this property:

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig-blockdev-template.html

It is however supported in LaunchTemplate: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html

but aws-autoscaling still doesn't support LaunchTemplates.

There is an outstanding PR to add LaunchTemplate support though, so once its merged I believe this functionality will be available as well.

That's the deal, I'm requesting/waiting for those 2 supports :

  • LaunchTemplates
  • Encryptionprop for BlockDeviceVolume

Keep waiting...

The ability to add CMK to BlockDeviceVolume is much needed. I can specify a CMK while creating EC2 via AWS Console. Just need the same ability in CDK.

Is there any progress on this?

FWIW, you can use the AWS-Managed key by setting the corresponding property in EbsDeviceOptions:

blockDevices: [
        {
          deviceName: '/dev/xvda',
          mappingEnabled: true,
          volume: ec2.BlockDeviceVolume.ebs(30, {
            deleteOnTermination: true,
            volumeType: ec2.EbsDeviceVolumeType.GP2,
            encrypted: true
          })
        }
      ]

FWIW, you can use the AWS-Managed key by setting the corresponding property in EbsDeviceOptions:

blockDevices: [
        {
          deviceName: '/dev/xvda',
          mappingEnabled: true,
          volume: ec2.BlockDeviceVolume.ebs(30, {
            deleteOnTermination: true,
            volumeType: ec2.EbsDeviceVolumeType.GP2,
            encrypted: true
          })
        }
      ]

Thanks for quick reply but how can I use my own KMS key (CMK) for encryption? I do not seem to have any option here?

FWIW, you can use the AWS-Managed key by setting the corresponding property in EbsDeviceOptions:

blockDevices: [
        {
          deviceName: '/dev/xvda',
          mappingEnabled: true,
          volume: ec2.BlockDeviceVolume.ebs(30, {
            deleteOnTermination: true,
            volumeType: ec2.EbsDeviceVolumeType.GP2,
            encrypted: true
          })
        }
      ]

Thanks for quick reply but how can I use my own KMS key (CMK) for encryption? I do not seem to have any option here?

Building on top of what @shamelesscookie pointed out, as this creates a good foundation in the underlying CloudFormation template, in Java CDK (and probably other languages) you can utilize the concept of IAspect & CfnResource to override/extended provided implementation, and in this case encrypt the root device using CMK.

Conceptually what you basically have to do is the following:

  1. Make accessible the KmsKeyId you want to use from your Stack (if you are creating one as part of the Stack), or just pass the input if the key already exists.
  2. In the visit(IConstruct node) method of the aspect implementation class you can do something like:
if (node != null && node instanceof Instance) {
            CfnResource cfnResource = (CfnResource) node.getNode().findChild("Resource");
            cfnResource.addPropertyOverride("BlockDeviceMappings.0.Ebs.KmsKeyId", this.kmsKeyId);
}
  1. In the App class of your CDK, add this after your instantiating both your stack and encryption aspect Aspects.of(myStack).add(encryptionAspectClass);

This will encrypt your root device volume with the CMK, and every other volume you can provision using the Volume construct which does take custom encryption key. The concept of overriding properties in form of Escape Hatches is also explained here. You can check it out for more details. Hope it helps.

I think the PR is up for grabs since it wasn't updated for a long time by the original contributor.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

abelmokadem picture abelmokadem  Â·  3Comments

NukaCody picture NukaCody  Â·  3Comments

pepastach picture pepastach  Â·  3Comments

Kent1 picture Kent1  Â·  3Comments

kawamoto picture kawamoto  Â·  3Comments