Problem using Lambda Layer Code in cdk Lambda nodejs

Viewed 44

I have created a Lambda Layer in cdk in typescript. But I am unable to access the library inside my lambda code...

Lambda & Layer Code:

  public lambdaDevicePut(options?: any): lambda_nodejs.NodejsFunction {

    const ajvLambdaLayer = new lambda.LayerVersion(this, 'ajv', {
      compatibleRuntimes: [
        lambda.Runtime.NODEJS_12_X,
        lambda.Runtime.NODEJS_14_X,
      ],
      code: lambda.Code.fromAsset('lambda/lambda-layers/' + 'ajv'),
      description: 'Lambda Layer for 3rd party library - ' + 'ajv',
    });

    const testLambda = new lambda_nodejs.NodejsFunction(this, 'lambda-device-put', {
      runtime: lambda.Runtime.NODEJS_12_X,
      entry: 'lambda/sn-release/device-put.js',
      handler: 'handler',
      functionName: this.TAG + 'device-put',
      description: 'API PUT Device/{id} : Update / Claim / Revoke Device.',
      memorySize: 128,
      timeout: cdk.Duration.seconds(60),
      environment: options.env,
      bundling: {
        minify: false,
        externalModules: ['aws-sdk', 'ajv'] // 'aws-sdk' is included by default - so need to include 
      },
      layers: [ajvLambdaLayer] // options.lambdaLayers
    });
    return testLambda;
  }

Folder Structure

  • Lambda
    • includes
      • dynamodb
      • s3
      • common
      • etc ...
    • Release
      • lambda-function-A.js
    • Admin
    • Layers
      • ajv
        • nodejs
          • node_modules
          • ajv.ts
          • package.json

Lambda Code

Then in my lambda function again:

const AWS               = require('aws-sdk');
const ajv               = require('ajv');       // import lambda layer 3rd party - Api Json Validator
// const ajv               = require('/opt/nodejs/ajv.js');
// import * as ajv from "ajv";
// import * as ajv from "/opt/nodejs/ajv.js";

var ses                 = new AWS.SES({ region: 'ap-southeast-2' });
var iotData             = new AWS.IotData({ endpoint: 'anegi7fk0f2xt.iot.ap-southeast-2.amazonaws.com' });
// const dynamodb       = new AWS.DynamoDB({ region: 'ap-southeast-2', apiVersion: '2012-8-10' });

const monkeyCommon      = require("../includes/common/monkey-common.js");

....
        ....

            // test out lib:
            const my_schema = {
                properties: {
                    foo: {type: "int32"}
                },
                optionalProperties: {
                    bar: {type: "string"}
                }
            };
            const my_validate = ajv.compile(my_schema);
            const my_data = {
                foo: 1,
                bar: "abc"
            }       
            const my_valid = my_validate(my_data)
            if (!my_valid) console.log(my_validate.errors)
            console.log(my_validate);
        

As you can see from the code, I'm running a few test lines from the ajv getting started section just to see if it's working. What I get is error:

{ "errorType": "TypeError", "errorMessage": "ajv.compile is not a function", "stack": [ "TypeError: ajv.compile is not a function", " at Runtime.exports.handler (/var/task/index.js:240:31)", " at processTicksAndRejections (internal/process/task_queues.js:97:5)" ] }

I've tried a few other things, on the assumption that I've not done the import right...

const ajv               = require('/opt/nodejs/ajv.js');

but here get the error:

[ERROR] Could not resolve "/opt/nodejs/ajv.js"

It's not something that's well documented, possibly assuming that users should know this stuff, but I don't have much formal training in this area. I must be doing something wrong, probably in the typescript export or nodejs import code.

0 Answers
Related