From 207a8ecf233511ad478827620b9caf0ff5fbb815 Mon Sep 17 00:00:00 2001 From: Shreyas Damle Date: Wed, 6 May 2020 07:02:15 -0700 Subject: [PATCH] feat(ec2): EBS volume configuration for BastionHostLinux Added `blockDevices?` property to `BastionHostLinuxProps` to allow full EBS device configuration so that customers can use it for use-cases like to encrypt an EBS volume for BastionHostLinux Fixes #6945 --- packages/@aws-cdk/aws-ec2/README.md | 13 ++++++ packages/@aws-cdk/aws-ec2/lib/bastion-host.ts | 17 ++++++++ .../aws-ec2/test/test.bastion-host.ts | 40 ++++++++++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index eb0d83949f3b..aa8b4aaaf321 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -558,6 +558,19 @@ host.allowSshAccessFrom(ec2.Peer.ipv4('1.2.3.4/32')); As there are no SSH public keys deployed on this machine, you need to use [EC2 Instance Connect](https://aws.amazon.com/de/blogs/compute/new-using-amazon-ec2-instance-connect-for-ssh-access-to-your-ec2-instances/) with the command `aws ec2-instance-connect send-ssh-public-key` to provide your SSH public key. +EBS volume for the bastion host can be encrypted like: +```ts + const host = new ec2.BastionHostLinux(stack, 'BastionHost', { + vpc, + blockDevices: [{ + deviceName: 'EBSBastionHost', + volume: BlockDeviceVolume.ebs(10, { + encrypted: true, + }), + }], + }); +``` + ## Block Devices diff --git a/packages/@aws-cdk/aws-ec2/lib/bastion-host.ts b/packages/@aws-cdk/aws-ec2/lib/bastion-host.ts index 91c34ad17bec..00b6cd396ddf 100644 --- a/packages/@aws-cdk/aws-ec2/lib/bastion-host.ts +++ b/packages/@aws-cdk/aws-ec2/lib/bastion-host.ts @@ -7,6 +7,7 @@ import { IMachineImage, MachineImage } from './machine-image'; import { IPeer } from './peer'; import { Port } from './port'; import { ISecurityGroup } from './security-group'; +import { BlockDevice } from './volume'; import { IVpc, SubnetSelection } from './vpc'; /** @@ -64,6 +65,20 @@ export interface BastionHostLinuxProps { * may be replaced on every deployment). */ readonly machineImage?: IMachineImage; + + /** + * Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes. + * + * Each instance that is launched has an associated root device volume, + * either an Amazon EBS volume or an instance store volume. + * You can use block device mappings to specify additional EBS volumes or + * instance store volumes to attach to an instance when it is launched. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html + * + * @default - Uses the block device mapping of the AMI + */ + readonly blockDevices?: BlockDevice[]; } /** @@ -129,6 +144,7 @@ export class BastionHostLinux extends Construct implements IInstance { constructor(scope: Construct, id: string, props: BastionHostLinuxProps) { super(scope, id); this.stack = Stack.of(scope); + this.instance = new Instance(this, 'Resource', { vpc: props.vpc, availabilityZone: props.availabilityZone, @@ -137,6 +153,7 @@ export class BastionHostLinux extends Construct implements IInstance { instanceType: props.instanceType ?? InstanceType.of(InstanceClass.T3, InstanceSize.NANO), machineImage: props.machineImage ?? MachineImage.latestAmazonLinux({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2 }), vpcSubnets: props.subnetSelection ?? {}, + blockDevices: props.blockDevices ?? undefined, }); this.instance.addToRolePolicy(new PolicyStatement({ actions: [ diff --git a/packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts b/packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts index 5711f31826b5..434571895236 100644 --- a/packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts +++ b/packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts @@ -1,7 +1,7 @@ import { expect, haveResource } from '@aws-cdk/assert'; import { Stack } from '@aws-cdk/core'; import { Test } from 'nodeunit'; -import { BastionHostLinux, SubnetType, Vpc } from '../lib'; +import { BastionHostLinux, BlockDeviceVolume, SubnetType, Vpc } from '../lib'; export = { 'default instance is created in basic'(test: Test) { @@ -45,6 +45,44 @@ export = { SubnetId: {Ref: 'VPCIsolatedSubnet1SubnetEBD00FC6'}, })); + test.done(); + }, + 'ebs volume is encrypted'(test: Test) { + // GIVEN + const stack = new Stack(); + const vpc = new Vpc(stack, 'VPC', { + subnetConfiguration: [ + { + subnetType: SubnetType.ISOLATED, + name: 'Isolated', + }, + ], + }); + + // WHEN + new BastionHostLinux(stack, 'Bastion', { + vpc, + blockDevices: [{ + deviceName: 'EBSBastionHost', + volume: BlockDeviceVolume.ebs(10, { + encrypted: true, + }), + }], + }); + + // THEN + expect(stack).to(haveResource('AWS::EC2::Instance', { + BlockDeviceMappings: [ + { + DeviceName: 'EBSBastionHost', + Ebs: { + Encrypted: true, + VolumeSize: 10, + }, + }, + ], + })); + test.done(); }, };