diff --git a/src/aurora.ts b/src/aurora.ts index 3f2a3d3..269880c 100644 --- a/src/aurora.ts +++ b/src/aurora.ts @@ -396,7 +396,7 @@ export class Aurora extends Construct { if (props.activityStream) { function activityStreamHandler(handler: string): aws_lambda_nodejs.NodejsFunction { const fn = new aws_lambda_nodejs.NodejsFunction(myConstruct, `ActivityStream${handler}`, { - runtime: aws_lambda.Runtime.NODEJS_LATEST, + runtime: aws_lambda.determineLatestNodeRuntime(myConstruct), bundling: { externalModules: ['@aws-sdk/client-secrets-manager', '@aws-sdk/client-rds'], }, @@ -450,7 +450,7 @@ export class Aurora extends Construct { } const provisionerProps: aws_lambda_nodejs.NodejsFunctionProps = { - runtime: aws_lambda.Runtime.NODEJS_LATEST, + runtime: aws_lambda.determineLatestNodeRuntime(this), bundling: { externalModules: ['@aws-sdk/client-secrets-manager', '@aws-sdk/client-rds'], nodeModules: ['pg', 'pg-format'], diff --git a/test/aurora.test.ts b/test/aurora.test.ts index b1b82e0..67f3edb 100644 --- a/test/aurora.test.ts +++ b/test/aurora.test.ts @@ -23,6 +23,19 @@ import { Namer } from 'multi-convention-namer'; import { Aurora, AuroraProps } from '../src'; +// Define the shape of Lambda function properties we care about +interface LambdaFunctionCfnProperties { + Runtime: string; + [key: string]: any; +} + +interface LambdaFunctionCfn { + Properties: LambdaFunctionCfnProperties; + [key: string]: any; +} + +const MINIMUM_NODEJS_MAJOR_VERSION = 20; + const databaseName = 'fakeDbName'; let app: App; @@ -47,7 +60,7 @@ describe('Aurora', () => { describe('default', () => { beforeAll(() => { app = new App(); - stack = new Stack(app, 'test'); + stack = new Stack(app, 'test', { env: { region: 'us-west-2' } }); // We're using determineLatestNodeRuntime() which is region aware. kmsKey = new Key(stack, 'Key'); vpc = new Vpc(stack, 'TestVpc', { subnetConfiguration: [ @@ -65,7 +78,12 @@ describe('Aurora', () => { }, ], }); - defaultAuroraProps = { databaseName, kmsKey, vpc }; + defaultAuroraProps = { + activityStream: true, // this will cause additional lambdas to be deployed, and we want to test them. + databaseName, + kmsKey, + vpc, + }; createAurora(); }); it('creates resources', () => { @@ -74,7 +92,7 @@ describe('Aurora', () => { ['AWS::SecretsManager::RotationSchedule', 'AWS::SecretsManager::Secret'].forEach((r) => template.resourceCountIs(r, 3), ); - template.resourceCountIs('AWS::Lambda::Function', 5); + template.resourceCountIs('AWS::Lambda::Function', 10); }); describe('cloudwatch logs', () => { it('exports', () => { @@ -96,6 +114,25 @@ describe('Aurora', () => { }); template.hasResourceProperties('Custom::AuroraDatabase', { databaseName }); }); + + it('nodejs lambda runtime minimum version is >= 20', () => { + const lambdaResources = template.findResources('AWS::Lambda::Function') as { [key: string]: LambdaFunctionCfn }; + const nodeLambdasProperties = Object.entries(lambdaResources).map(([key, value]) => { + return { + ...value.Properties, + key, + }; + }); + + nodeLambdasProperties.forEach((p) => { + const nodejsMatch = p.Runtime.match(/^nodejs(\d+)\.x$/); + if (nodejsMatch) { + const version = parseInt(nodejsMatch[1], 10); + expect(version).toBeGreaterThanOrEqual(MINIMUM_NODEJS_MAJOR_VERSION); + } + }); + }); + it('performanceInsights', () => { template.hasResourceProperties('AWS::RDS::DBInstance', { PerformanceInsightsKMSKeyId: { 'Fn::GetAtt': [stack.getLogicalId(kmsKey.node.defaultChild as CfnKey), 'Arn'] }, @@ -141,18 +178,7 @@ describe('Aurora', () => { 'kms:CallerAccount': { Ref: 'AWS::AccountId', }, - 'kms:ViaService': { - 'Fn::Join': [ - '', - [ - 'secretsmanager.', - { - Ref: 'AWS::Region', - }, - '.amazonaws.com', - ], - ], - }, + 'kms:ViaService': 'secretsmanager.us-west-2.amazonaws.com', }, }, Effect: 'Allow', @@ -185,7 +211,7 @@ describe('Aurora', () => { describe('options', () => { beforeEach(() => { app = new App(); - stack = new Stack(app, 'test'); + stack = new Stack(app, 'test', { env: { region: 'us-west-2' } }); // We're using determineLatestNodeRuntime() which is region aware. kmsKey = new Key(stack, 'Key'); vpc = new Vpc(stack, 'TestVpc', { subnetConfiguration: [