Improving CDK deployment speed for serverless stacks with esbuild
1. Previous experience
Throughout my career in development I have met various solutions to deploy stacks to AWS. I have been fortunate to use CloudFormation, SAM, CDK and Serverless Framework.
Most of the time I work with serverless technologies. I use TypeScript and Node.js, but Lambda functions only accept JavaScript code.
Code conversion, bundling, and deployment could take quite a few minutes, which sometimes seems an eternity. I find it frustrating when I make small changes in the stack, and then I must wait long minutes for the updated stack in the cloud.
esbuild
is an amazingly fast JavaScript bundler that works well with CDK.
2. Sample stack
To demonstrate that, create a sample stack in a folder called test-project
:
npx cdk init --language=typescript
This command will create the folder structure for a CDK version 2 stack called TestProject
. I update all packages after they are ready because the package creator sometimes lags behind the latest versions.
Let’s create a Lambda function in the lib
folder:
import { Duration, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { NodejsFunction, LogLevel, NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
const lambdaFnProps: Partial<NodejsFunctionProps> = {
bundling: {
target: 'es2020',
keepNames: true,
logLevel: LogLevel.INFO,
sourceMap: true,
minify: true,
},
runtime: Runtime.NODEJS_16_X,
timeout: Duration.seconds(6),
memorySize: 256,
logRetention: RetentionDays.ONE_DAY,
environment: {
NODE_OPTIONS: '--enable-source-maps',
},
};
export class TestProjectStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
new NodejsFunction(this, 'test', {
...lambdaFnProps,
functionName: 'TestFn',
});
}
}
If we want to deploy the stack, we can run npm run cdk deploy
. But at this point we will need Docker running, otherwise the command will return an error.
3. Using esbuild
We have set up some bundling
options in the stack module, but CDK is still using a Docker image for bundling.
We can achieve great deployment times if we avoid using Docker and install esbuild
locally:
npm install -D esbuild
And this is all about it. The npm run cdk deploy
command will now work without Docker, and the deployment will be fast. CDK will use esbuild
to automatically transpile TypeScript to JavaScript. We don’t have to use webpack or other bundlers as CDK and esbuild will solve everything for us.
4. Summary
esbuild
is a great module bundler, which CDK v2 uses for transpiling TypeScript code at deployment time. We should install the package locally if we want to benefit from esbuild
’s fast bundling and CDK’s improved deployment time.
5. Further reading
esbuild documentation - Everything about esbuild