Skip to content

Instantly share code, notes, and snippets.

@abrgr
Last active October 1, 2023 20:47
Show Gist options
  • Save abrgr/fb4987920d1f14d817a0ac4e0b49e010 to your computer and use it in GitHub Desktop.
Save abrgr/fb4987920d1f14d817a0ac4e0b49e010 to your computer and use it in GitHub Desktop.
Using turborepo to build minimal lambdas with CDK
import * as path from "path";
import * as cdk from "aws-cdk-lib";
import {
Function as LambdaFunction,
IFunction,
Runtime,
Code,
} from "aws-cdk-lib/aws-lambda";
import { Construct } from "constructs";
import { BundlingOutput, Duration } from "aws-cdk-lib";
import pkgjson from "../../../package.json"; // root package.json
export interface LocalNodeLambdaProps {
functionName: string;
functionDescription?: string;
pkg: string; // package name of the yarn workspace with the code for the lambda function
timeout: Duration;
memorySize: number;
rootDir: string; // directory for the root of the projects. this directory contains a package.json with the workspaces key
env?: Record<string, string>;
}
export class LocalNodeLambda extends Construct {
public readonly fn: IFunction;
constructor(scope: Construct, id: string, props: LocalNodeLambdaProps) {
super(scope, id);
const runtime = Runtime.NODEJS_16_X;
this.fn = new LambdaFunction(this, props.functionName, {
description: props.functionDescription,
runtime,
timeout: props.timeout,
memorySize: props.memorySize,
environment: {
AWS_NODEJS_CONNECTION_REUSE_ENABLED: "1",
...props.env,
},
code: Code.fromAsset(props.rootDir, {
bundling: {
image: runtime.bundlingImage,
// let cdk zip for us
outputType: BundlingOutput.NOT_ARCHIVED,
// npm and yarn really don't like to run without a home directory. just gives error code 243 without one. so run as root and then drop to user account
user: "0",
command: [
"bash",
"-c",
[
`npm install --location=global ${pkgjson.packageManager}`,
`/sbin/useradd --uid 1000 --create-home node`,
`su --login node`,
`yarn --cwd '${cdk.AssetStaging.BUNDLING_INPUT_DIR}' install --frozen-lockfile`,
`yarn --cwd '${cdk.AssetStaging.BUNDLING_INPUT_DIR}' run prune --scope=${props.pkg}`,
`echo 'module.exports = require("${props.pkg}");' > '${cdk.AssetStaging.BUNDLING_INPUT_DIR}/out/index.js'`,
`yarn --cwd '${cdk.AssetStaging.BUNDLING_INPUT_DIR}/out' install --frozen-lockfile`,
`yarn --cwd '${cdk.AssetStaging.BUNDLING_INPUT_DIR}/out' run build`,
`yarn --cwd '${cdk.AssetStaging.BUNDLING_INPUT_DIR}/out' install --production --ignore-scripts --prefer-offline --frozen-lockfile`,
`mv ${cdk.AssetStaging.BUNDLING_INPUT_DIR}/out/* '${cdk.AssetStaging.BUNDLING_OUTPUT_DIR}'`,
`rm -rf "${cdk.AssetStaging.BUNDLING_INPUT_DIR}/out"`,
].join(" && "),
],
},
}),
handler: "index.handler",
});
}
}
{
"name": "...",
"version": "...",
"description": "this is the root pakage.json",
"private": true,
"packageManager": "yarn@1.22.19",
"workspaces": [
"cdk",
"lambdas/*",
"common/*"
],
"scripts": {
"build": "turbo run build",
"test": "turbo run test",
"cdk": "yarn workspace @scope/cdk cdk",
"prune": "run(){ turbo prune $@ && cp tsconfig.json out/tsconfig.json; }; run",
"prettier": "turbo run prettier"
},
"devDependencies": {
"@types/jest": "^29.1.1",
"@types/node": "^18.8.2",
"eslint": "^8.24.0",
"jest": "^29.1.2",
"prettier": "^2.7.1",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"turbo": "^1.5.5",
"typescript": "^4.8.4"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment