Sai Umesh

AWS CDK Custom Resources

3 min read

AWS has pretty solid support for CDK with its resources, but there are still a few cases where CDK doesn’t provide constructs. Since I’ve been working with CDK for over a couple of years now, I wanted to share some use cases where we had to roll up our sleeves and write an AwsCustomResource.

What is AwsCustomResource?

The AwsCustomResource is a custom resource that lets you make specific AWS API calls right from your CDK code. It does this using a singleton Lambda function. AwsCustomResource also comes with different lifecycle events like onCreate, onUpdate, and onDelete.

Invalidating CloudFront Cache When an S3 Bucket is Updated

Here’s a scenario we faced: we had our S3 bucket in one stack and our CloudFront distribution in another. Now, whenever we updated the S3 bucket with new objects, we needed to invalidate the CloudFront cache to ensure users got the latest content.

While CDK does support cache invalidation, it’s oddly tied directly to the S3 Bucket deployment, which is pretty strange, right? 🤷‍♂️

So, here’s the solution we came up with using AwsCustomResource:

export class CloudFrontInvalidation extends AwsCustomResource {
  constructor(scope: Construct, props: CloudFrontInvalidationProps) {
    super(scope, constructId, {
      onCreate: {
        service: 'CloudFront',
        action: 'createInvalidation',
        parameters: {
          DistributionId: distributionId,
          InvalidationBatch: {
            CallerReference: <random_id>,
            Paths: {
              Quantity: paths.length,
              Items: paths,
            },
          },
        },
        physicalResourceId: PhysicalResourceId.of(<random_id>),
      },
      onUpdate: {
        service: 'CloudFront',
        action: 'createInvalidation',
        parameters: {
          DistributionId: distributionId,
          InvalidationBatch: {
            CallerReference: <random_id>,
            Paths: {
              Quantity: paths.length,
              Items: paths,
            },
          },
        },
        physicalResourceId: PhysicalResourceId.of(generateRandomString(4)),
      },
      policy: AwsCustomResourcePolicy.fromStatements([
        new PolicyStatement({
          actions: ['cloudfront:CreateInvalidation'],
          resources: [cloudFrontArn],
        }),
      ]),
      installLatestAwsSdk: false,
      functionName: <custom-lambda-function-name>
    });
  }
}

In this snippet, we define a custom resource that triggers a CloudFront cache invalidation whenever the S3 bucket is updated. This way, users always get the latest version of your content without any hassle.


Sai Umesh

I’m Sai Umesh, a software engineer based in India. Working as a DevOps engineer.