KMS Key Example in AWS CDK - Complete Guide

avatar
Borislav Hadzhiev

Last updated: Jan 26, 2024
3 min

banner

# Creating a KMS Key in AWS CDK

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

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-lib/aws-kms'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cdk from 'aws-cdk-lib'; 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 sample:

  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 aws-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 permission 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 aws-cdk destroy

# Further Reading

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.