Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ec2): EBS volume configuration for BastionHostLinux #7585

Merged
merged 9 commits into from
May 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-ec2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 17 additions & 0 deletions packages/@aws-cdk/aws-ec2/lib/bastion-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -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[];
}

/**
Expand Down Expand Up @@ -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,
Expand All @@ -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: [
Expand Down
40 changes: 39 additions & 1 deletion packages/@aws-cdk/aws-ec2/test/test.bastion-host.ts
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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();
},
};