KMS Key Example in AWS CDK - Complete Guide

avatar

Borislav Hadzhiev

Mon May 10 20213 min read

banner

Photo by Mesh

A complete example of creating, configuring and deploying a KMS key with AWS CDK.

Creating a KMS Key in AWS CDK #

AWS KMS is a service, that enables us to control access to our data, by encrypting it using AWS managed keys.

In this article we are going to create and configure a KMS key in CDK and use it to encrypt an S3 bucket.

The code for this article is available on GitHub

I'll post the complete code snippet and then we'll go over the code.

lib/cdk-starter-stack.ts
import * as kms from '@aws-cdk/aws-kms';
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';

export class CdkStarterStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const key = new kms.Key(this, 'my-kms-key', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      pendingWindow: cdk.Duration.days(7),
      alias: 'alias/mykey',
      description: 'KMS key for encrypting the objects in an S3 bucket',
      enableKeyRotation: false,
    });

    const s3Bucket = new s3.Bucket(this, 'my-bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      encryption: s3.BucketEncryption.KMS,
      // ๐Ÿ‘‡ encrypt with our KMS key
      encryptionKey: key,
    });

    new cdk.CfnOutput(this, 'key-arn', {
      value: key.keyArn,
    });

    new cdk.CfnOutput(this, 'bucket-name', {
      value: s3Bucket.bucketName,
    });
  }
}

Let's go over what we did in the code snippet.

  1. we created a KMS key by instantiating the Key class. We passed the following props to the constructor:
NameDescription
removalPolicyspecify what should happen to the key when the stack is deleted. By default, the key is retained in an orphaned state
pendingWindowthe number of days (7 - 30) before the KMS key gets deleted. By default the waiting period is 30 days
aliasan alias to add to the KMS key. The alias can then be used for different operations, i.e. to import the KMS key in a different stack
descriptiona short description of how the KMS key is intended to be used
enableKeyRotationwhether AWS should rotate the KMS key for us
  1. we created an S3 bucket, for which we configured server-side encryption via the KMS key

  2. we created some Outputs that will help us identify the resources after we deploy the stack

I'll deploy the resources from the stack and redirect the outputs to a file on the local file system:

shell
npx cdk deploy \
  --output-file ./cdk-outputs.json

We've successfully created a symmetric KMS CMK (customer master key). A single symmetric KMS key is used to both encrypt and decrypt data.

kms symmetric key

These keys are managed by AWS, so we don't have access to the un-encrypted key.

We can also see that CDK created a default key policy for us, because we didn't specify one:

kms default key policy

The default KMS Key Policy gives complete access to the root user, to perform any KMS actions with the key.

Before we explicitly set a KMS Key policy, we should be aware, that if the policy gives permissions to a user or role that gets deleted, we run the risk of no one having permissions to manage the key.

If we now take a look at the S3 bucket's encryption configuration, we can see that the objects in the bucket will get encrypted by the KMS key we created:

kms encryption s3 bucket

Clean up #

To delete the provisioned resources, execute the destroy command:

shell
npx cdk destroy

Further Reading #

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee