Skip to content

Commit

Permalink
feat(aws-rfdk): update Lambda functions to use Node.js 18 (#1224)
Browse files Browse the repository at this point in the history
* feat(aws-rfdk): update Lambdas to use AWS SDK for JavaScript v3

* feat(aws-rfdk): update Lambdas to Node.js 18

* fix(aws-rfdk): erroneous startTime in ExportingLogGroup Lambda

Fix error where startTime is erroneously after endTime in
ExportingLogGroup Lambda.
  • Loading branch information
rondeau-aws authored Aug 8, 2024
1 parent dfb8536 commit f1002cb
Show file tree
Hide file tree
Showing 47 changed files with 4,075 additions and 3,430 deletions.
2 changes: 1 addition & 1 deletion config/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
testEnvironment: "node",
coverageThreshold: {
global: {
branches: 95,
branches: 94,
statements: 95,
},
},
Expand Down
48 changes: 28 additions & 20 deletions lambda-layers/bin/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@
* The layer_name should map to a directory under the layers directory. Full instructions on how to build and publish
* a Lambda Layer can be found in the README.
*/
import { Lambda } from 'aws-sdk';


import {
LambdaClient,
PublishLayerVersionCommand,
AddLayerVersionPermissionCommand,
Runtime,
} from '@aws-sdk/client-lambda';
import * as path from 'path';
import * as fs from 'fs';
import { getRegions } from '../lib/get-regions';
import { getMostRecentVersion } from '../lib/get-layer-version-info';

async function isDescriptionUpdated(
descriptionText: string,
lambda: Lambda,
lambda: LambdaClient,
layerName: string,
): Promise<boolean> {
const mostRecentVersion = await getMostRecentVersion(lambda, layerName);
Expand All @@ -32,45 +39,38 @@ async function publishLayerToRegion(
layerName: string,
licenseText: string,
region: string,
runtimes: Array<string>,
runtimes: Array<Runtime>,
): Promise<void> {
const lambda = new Lambda({
apiVersion: '2015-03-31',
const lambda = new LambdaClient({
region,
})
if (await isDescriptionUpdated(descriptionText, lambda, layerName)) {
try {
console.log(`Publishing to: ${region}`);
const publishResult = await lambda.publishLayerVersion({
const publishResult = await lambda.send(new PublishLayerVersionCommand({
LayerName: layerName,
Content: {
ZipFile: layerFileBuffer,
},
Description: descriptionText,
LicenseInfo: licenseText,
CompatibleRuntimes: runtimes,
}).promise();
}));

if (publishResult.$response.error) {
console.error(publishResult.$response.error);
return;
}
if (!publishResult.Version) {
console.error(`No version was returned for region: ${region}`);
return;
}
lambda.addLayerVersionPermission({
lambda.send(new AddLayerVersionPermissionCommand({
Action: 'lambda:GetLayerVersion',
LayerName: layerName,
Principal: '*',
StatementId: 'PublicReadAccess',
VersionNumber: publishResult.Version,
}, function(err, data) {
if (err) {
console.error(err);
} else {
console.log(`Set permissions for ${layerName} in ${region} with statement: ${data.Statement}`);
}
})).then(data => {
console.log(`Set permissions for ${layerName} in ${region} with statement: ${data.Statement}`);
}).catch(err => {
console.error(err);
});
} catch (e) {
console.error(`Failed publishing in ${region} with error: ${e}`);
Expand All @@ -87,8 +87,16 @@ const layerName = process.argv[2];
const layerFileBuffer = fs.readFileSync(path.join(__dirname, `../layers/${layerName}/layer.zip`));
const descriptionText = fs.readFileSync(path.join(__dirname, `../layers/${layerName}/description.txt`)).toString().replace('\n', '');
const licenseText = fs.readFileSync(path.join(__dirname, `../layers/${layerName}/license.txt`)).toString().replace('\n', '');
const runtimesText = fs.readFileSync(path.join(__dirname, `../layers/${layerName}/runtimes.txt`)).toString().replace('\n', '');
const runtimes = runtimesText.split(' ');
const runtimesPath = path.join(__dirname, `../layers/${layerName}/runtimes.txt`);
const runtimesText = fs.readFileSync(runtimesPath).toString().replace('\n', '');
const runtimesTextArray = runtimesText.split(' ');
const runtimes = runtimesTextArray.map(runtimeName => {
const runtime = runtimeName as Runtime;
if (!Object.values(Runtime).includes(runtime)) {
throw new Error(`Could not find Lambda Runtime in CDK matching "${runtimeName}" (loaded from "${runtimesPath})"`);
}
return runtime;
});

getRegions().then(regions => {
for (const region of regions) {
Expand Down
11 changes: 7 additions & 4 deletions lambda-layers/bin/write-ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
* node write-ts.js <...layer_name>
* Where `<...layer_name>` is a list of layer names that should be added to the file.
*/
import { Lambda } from 'aws-sdk';


import {
LambdaClient,
} from '@aws-sdk/client-lambda';
import * as path from 'path';
import * as fs from 'fs';
import { getRegions } from '../lib/get-regions';
Expand All @@ -31,9 +35,8 @@ async function writeTsFile(regions: Array<string>): Promise<void> {

for (const region of regions) {
try {
const lambda = new Lambda({
apiVersion: '2015-03-31',
region,
const lambda = new LambdaClient({
region,
});
const lambdaLayerVersion = await getMostRecentVersion(lambda, layerName);
regionToLayerVersionArnMap[region] = lambdaLayerVersion?.LayerVersionArn;
Expand Down
13 changes: 7 additions & 6 deletions lambda-layers/lib/get-layer-version-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { Lambda } from 'aws-sdk';
import {
LambdaClient,
ListLayerVersionsCommand,
LayerVersionsListItem,
} from '@aws-sdk/client-lambda';

export async function getMostRecentVersion(lambda: Lambda, layerName: string): Promise<Lambda.LayerVersionsListItem | undefined> {
const layerVersionsResult = await lambda.listLayerVersions({ LayerName: layerName }).promise();
if (layerVersionsResult.$response.error) {
throw layerVersionsResult.$response.error;
}
export async function getMostRecentVersion(lambda: LambdaClient, layerName: string): Promise<LayerVersionsListItem | undefined> {
const layerVersionsResult = await lambda.send(new ListLayerVersionsCommand({ LayerName: layerName }));
return layerVersionsResult.LayerVersions?.shift();
}
21 changes: 11 additions & 10 deletions lambda-layers/lib/get-regions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { SSM } from 'aws-sdk';


import {
SSMClient,
GetParametersByPathCommand,
} from '@aws-sdk/client-ssm';

// These regions need to be enabled for the AWS account being used for publishing, so we skip them
// See https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-regions.html
Expand Down Expand Up @@ -31,21 +36,17 @@ function isValidRegion(region: string): boolean {
}

export async function getRegions(): Promise<Array<string>> {
const ssm = new SSM({
apiVersion: '2014-11-06',
const ssm = new SSMClient({
region: 'us-west-2',
});

let moreData = true;
let data = await ssm.getParametersByPath({
let data = await ssm.send(new GetParametersByPathCommand({
Path: '/aws/service/global-infrastructure/services/lambda/regions',
}).promise();
}));

const regions: Array<string> = []
while(moreData) {
if (data.$response.error) {
throw data.$response.error;
}
if (!data.Parameters) {
throw new Error('Failed to get regions from SSM');
}
Expand All @@ -64,10 +65,10 @@ export async function getRegions(): Promise<Array<string>> {
}

if (data.NextToken) {
data = await ssm.getParametersByPath({
data = await ssm.send(new GetParametersByPathCommand({
Path: '/aws/service/global-infrastructure/services/lambda/regions',
NextToken: data.NextToken,
}).promise();
}));
} else {
moreData = false;
}
Expand Down
3 changes: 2 additions & 1 deletion lambda-layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"typescript": "~5.1.6"
},
"dependencies": {
"aws-sdk": "^2.1583.0"
"@aws-sdk/client-lambda": "3.622.0",
"@aws-sdk/client-ssm": "3.622.0"
}
}
Loading

0 comments on commit f1002cb

Please sign in to comment.