Skip to content

Commit

Permalink
✨ feat(runtime): allow configuration of NodeJS runtime for Lambda (#74)
Browse files Browse the repository at this point in the history
Updated depdencies to allow node18 runtime. Commander next major version (ndoe14 needed, so no change for us). All AWS related packages updated to accomodate node18 support

#74
  • Loading branch information
sladg committed Feb 15, 2023
1 parent 8932add commit fd1e1da
Show file tree
Hide file tree
Showing 8 changed files with 752 additions and 235 deletions.
15 changes: 15 additions & 0 deletions lib/cdk/config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import { Runtime } from 'aws-cdk-lib/aws-lambda'
import { bool, cleanEnv, num, str } from 'envalid'
import { DEFAULT_MEMORY as IMAGE_LAMBDA_DEFAULT_MEMORY, DEFAULT_TIMEOUT as IMAGE_LAMBDA_DEFAULT_TIMEOUT } from './utils/imageLambda'
import { DEFAULT_MEMORY as SERVER_LAMBDA_DEFAULT_MEMORY, DEFAULT_TIMEOUT as SERVER_LAMBDA_DEFAULT_TIMEOUT } from './utils/serverLambda'

enum RuntimeEnum {
NODEJS_14_X = 'node14',
NODEJS_16_X = 'node16',
NODEJS_18_X = 'node18',
}

const runtimeMap = {
[RuntimeEnum.NODEJS_14_X]: Runtime.NODEJS_14_X,
[RuntimeEnum.NODEJS_16_X]: Runtime.NODEJS_16_X,
[RuntimeEnum.NODEJS_18_X]: Runtime.NODEJS_18_X,
}

const RawEnvConfig = cleanEnv(process.env, {
STACK_NAME: str(),
LAMBDA_TIMEOUT: num({ default: SERVER_LAMBDA_DEFAULT_TIMEOUT }),
LAMBDA_MEMORY: num({ default: SERVER_LAMBDA_DEFAULT_MEMORY }),
LAMBDA_RUNTIME: str({ default: RuntimeEnum.NODEJS_16_X, choices: Object.values(RuntimeEnum) }),
IMAGE_LAMBDA_TIMEOUT: num({ default: IMAGE_LAMBDA_DEFAULT_TIMEOUT }),
IMAGE_LAMBDA_MEMORY: num({ default: IMAGE_LAMBDA_DEFAULT_MEMORY }),
HOSTED_ZONE: str({ default: undefined }),
Expand All @@ -18,6 +32,7 @@ export const envConfig = {
stackName: RawEnvConfig.STACK_NAME,
lambdaMemory: RawEnvConfig.LAMBDA_MEMORY,
lambdaTimeout: RawEnvConfig.LAMBDA_TIMEOUT,
lambdaRuntime: runtimeMap[RawEnvConfig.LAMBDA_RUNTIME],
imageLambdaMemory: RawEnvConfig.IMAGE_LAMBDA_MEMORY,
imageLambdaTimeout: RawEnvConfig.IMAGE_LAMBDA_TIMEOUT,
hostedZone: RawEnvConfig.HOSTED_ZONE,
Expand Down
3 changes: 2 additions & 1 deletion lib/cdk/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class NextStandaloneStack extends Stack {
this.domainName = config.dnsPrefix ? `${config.dnsPrefix}.${config.hostedZone}` : config.hostedZone
}

console.log('Hosted zone:', this.hostedZone)
console.log('Hosted zone:', this.hostedZone?.zoneName)
console.log('Normalized domain name:', this.domainName)

this.assetsBucket = this.setupAssetsBucket()
Expand All @@ -58,6 +58,7 @@ export class NextStandaloneStack extends Stack {
dependenciesPath: config.dependenciesZipPath,
timeout: config.lambdaTimeout,
memory: config.lambdaMemory,
runtime: config.lambdaRuntime,
})

this.apiGateway = this.setupApiGateway({
Expand Down
2 changes: 2 additions & 0 deletions lib/cdk/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { StackProps } from 'aws-cdk-lib'
import { Runtime } from 'aws-cdk-lib/aws-lambda'

export interface CustomStackProps extends StackProps {
apigwServerPath: string
Expand All @@ -13,6 +14,7 @@ export interface CustomStackProps extends StackProps {
customImageHandler: string
lambdaTimeout: number
lambdaMemory: number
lambdaRuntime: Runtime
imageLambdaTimeout?: number
imageLambdaMemory?: number
hostedZone?: string
Expand Down
6 changes: 4 additions & 2 deletions lib/cdk/utils/serverLambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ export interface SetupServerLambdaProps {
basePath: string
memory: number
timeout: number
runtime: Runtime
}

export const DEFAULT_MEMORY = 1024
export const DEFAULT_TIMEOUT = 20
export const DEFAULT_RUNTIME = Runtime.NODEJS_16_X

export const setupServerLambda = (
scope: Stack,
{ basePath, codePath, dependenciesPath, handler, memory = DEFAULT_MEMORY, timeout = DEFAULT_TIMEOUT }: SetupServerLambdaProps,
{ basePath, codePath, dependenciesPath, handler, memory = DEFAULT_MEMORY, timeout = DEFAULT_TIMEOUT, runtime = DEFAULT_RUNTIME }: SetupServerLambdaProps,
) => {
const depsLayer = new LayerVersion(scope, 'DepsLayer', {
// This folder does not use Custom hash as depenendencies are most likely changing every time we deploy.
Expand All @@ -24,7 +26,7 @@ export const setupServerLambda = (

const serverLambda = new Function(scope, 'DefaultNextJs', {
code: Code.fromAsset(codePath),
runtime: Runtime.NODEJS_16_X,
runtime,
handler,
layers: [depsLayer],
// No need for big memory as image handling is done elsewhere.
Expand Down
3 changes: 3 additions & 0 deletions lib/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ program
.option('--lambdaMemory <mb>', 'Set memory for lambda function handling server requests.', Number, 512)
.option('--imageLambdaTimeout <sec>', 'Set timeout for lambda function handling image optimization.', Number, IMAGE_LAMBDA_DEFAULT_TIMEOUT)
.option('--imageLambdaMemory <mb>', 'Set memory for lambda function handling image optimization.', Number, IMAGE_LAMBDA_DEFAULT_MEMORY)
.option('--lambdaRuntime <runtime>', "Specify version of NodeJS to use as Lambda's runtime. Options: node14, node16, node18.", 'node16')
.option('--hostedZone <domainName>', 'Hosted zone domain name to be used for creating DNS records (example: example.com).', undefined)
.option('--domainNamePrefix <prefix>', 'Prefix for creating DNS records, if left undefined, hostedZone will be used (example: app).', undefined)
.option('--customApiDomain <domain>', 'Domain to forward the requests to /api routes, by default API routes will be handled by the server lambda.', undefined)
Expand All @@ -72,6 +73,7 @@ program
region,
lambdaTimeout,
lambdaMemory,
lambdaRuntime,
imageLambdaMemory,
imageLambdaTimeout,
hostedZone,
Expand All @@ -88,6 +90,7 @@ program
region,
lambdaTimeout,
lambdaMemory,
lambdaRuntime,
imageLambdaMemory,
imageLambdaTimeout,
hostedZone,
Expand Down
5 changes: 4 additions & 1 deletion lib/cli/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface Props {
region?: string
lambdaMemory?: number
lambdaTimeout?: number
lambdaRuntime?: string
imageLambdaMemory?: number
imageLambdaTimeout?: number
customApiDomain?: string
Expand All @@ -24,6 +25,7 @@ export const deployHandler = async ({
region,
lambdaMemory,
lambdaTimeout,
lambdaRuntime,
imageLambdaMemory,
imageLambdaTimeout,
domainNamePrefix,
Expand All @@ -33,13 +35,14 @@ export const deployHandler = async ({
}: Props) => {
// All paths are absolute.
const cdkApp = `node ${appPath}`
const cdkCiFlags = `--require-approval never --ci`
const cdkCiFlags = `--require-approval never --ci --hotswap`

const variables = {
STACK_NAME: stackName,
...(region && { AWS_REGION: region }),
...(lambdaMemory && { LAMBDA_MEMORY: lambdaMemory.toString() }),
...(lambdaTimeout && { LAMBDA_TIMEOUT: lambdaTimeout.toString() }),
...(lambdaRuntime && { LAMBDA_RUNTIME: lambdaRuntime.toString() }),
...(imageLambdaMemory && { IMAGE_LAMBDA_MEMORY: imageLambdaMemory.toString() }),
...(imageLambdaTimeout && { IMAGE_LAMBDA_TIMEOUT: imageLambdaTimeout.toString() }),
...(hostedZone && { HOSTED_ZONE: hostedZone }),
Expand Down
Loading

0 comments on commit fd1e1da

Please sign in to comment.