Skip to content

Commit

Permalink
feat(ec2): Volume construct (#8219)
Browse files Browse the repository at this point in the history
This adds an L2 construct for AWS::EC2:Volume that supports encryption with a customer-owned KMS key, or service-owned key. It provides methods for importing an existing Volume to the stack, and for granting `AttachVolume` and `DetachVolume` to a role.

----

Resolves #8218

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
ddneilson authored Jun 26, 2020
1 parent 10bd8e4 commit 7490dee
Show file tree
Hide file tree
Showing 4 changed files with 2,043 additions and 4 deletions.
69 changes: 68 additions & 1 deletion packages/@aws-cdk/aws-ec2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,6 @@ EBS volume for the bastion host can be encrypted like:
});
```


## Block Devices

To add EBS block device mappings, specify the `blockDeviceMappings` property. The follow example sets the EBS-backed
Expand All @@ -608,6 +607,74 @@ new ec2.Instance(this, 'Instance', {

```

## Volumes

Whereas a `BlockDeviceVolume` is an EBS volume that is created and destroyed as part of the creation and destruction of a specific instance. A `Volume` is for when you want an EBS volume separate from any particular instance. A `Volume` is an EBS block device that can be attached to, or detached from, any instance at any time. Some types of `Volume`s can also be attached to multiple instances at the same time to allow you to have shared storage between those instances.

A notable restriction is that a Volume can only be attached to instances in the same availability zone as the Volume itself.

The following demonstrates how to create a 500 GiB encrypted Volume in the `us-west-2a` availability zone, and give a role the ability to attach that Volume to a specific instance:

```ts
const instance = new ec2.Instance(this, 'Instance', {
// ...
});
const role = new iam.Role(stack, 'SomeRole', {
assumedBy: new iam.AccountRootPrincipal(),
});
const volume = new ec2.Volume(this, 'Volume', {
availabilityZone: 'us-west-2a',
size: cdk.Size.gibibytes(500),
encrypted: true,
});

volume.grantAttachVolume(role, [instance]);
```

### Instances Attaching Volumes to Themselves

If you need to grant an instance the ability to attach/detach an EBS volume to/from itself, then using `grantAttachVolume` and `grantDetachVolume` as outlined above
will lead to an unresolvable circular reference between the instance role and the instance. In this case, use `grantAttachVolumeByResourceTag` and `grantDetachVolumeByResourceTag` as follows:

```ts
const instance = new ec2.Instance(this, 'Instance', {
// ...
});
const volume = new ec2.Volume(this, 'Volume', {
// ...
});

const attachGrant = volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]);
const detachGrant = volume.grantDetachVolumeByResourceTag(instance.grantPrincipal, [instance]);
```

### Attaching Volumes

The Amazon EC2 documentation for
[Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html) and
[Windows Instances](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ebs-volumes.html) contains information on how
to attach and detach your Volumes to/from instances, and how to format them for use.

The following is a sample skeleton of EC2 UserData that can be used to attach a Volume to the Linux instance that it is running on:

```ts
const volume = new ec2.Volume(this, 'Volume', {
// ...
});
const instance = new ec2.Instance(this, 'Instance', {
// ...
});
volume.grantAttachVolumeByResourceTag(instance.grantPrincipal, [instance]);
const targetDevice = '/dev/xvdz';
instance.userData.addCommands(
// Attach the volume to /dev/xvdz
`aws --region ${Stack.of(this).region} ec2 attach-volume --volume-id ${volume.volumeId} --instance-id ${instance.instanceId} --device ${targetDevice}`,
// Wait until the volume has attached
`while ! test -e ${targetDevice}; do sleep 1; done`
// The volume will now be mounted. You may have to add additional code to format the volume if it has not been prepared.
);
```

## VPC Flow Logs
VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. Flow log data can be published to Amazon CloudWatch Logs and Amazon S3. After you've created a flow log, you can retrieve and view its data in the chosen destination. (https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html).

Expand Down
Loading

0 comments on commit 7490dee

Please sign in to comment.