Home

Creating a lambda Layer with Pulumi & Typescript.

Created: April 1, 2021

Last updated: July 11, 2023

So recently while developing a integration i had the need to share some code between a couple lambdas as they needed to use parts of the class that i had created. I'll go through my steps to get pulumi to compile and then deploy the layer so we can use it in our lambda.

First step i'll assume you have pulumi installed and have your project setup.

First up lets install lodash snakecase so we can use that inside our custom class.

npm i --save lodash.snakecase

Next lets create our class ./myAwesomeClass/index.ts:

const snakeCase = require('lodash.snakecase')

export default class myAwesomeClass {
  static transform(word: string): string {
    return snakeCase(word)
  }
}

Now that we have created our class lets update the ./index.ts to create our layer to include the myAwesomeClass class we just created above:

./index.ts

import * as pulumi from '@pulumi/pulumi'
import * as aws from '@pulumi/aws'
import myAwesomeClass from './myAwesomeClass'

const config = new pulumi.Config('aws')

// Compile our typescript file into a string.
const sFunc = async () => {
  const func = await pulumi.runtime.serializeFunction(myAwesomeClass, {
    exportName: myAwesomeClass.name,
  })
  return func.text
}

// Our layer with our custom class. We also includ our dependencies: lodash.snakecase.
let layer = new aws.lambda.LayerVersion('my-layer-version', {
  code: new pulumi.asset.AssetArchive({
    'myAwesomeClass.js': new pulumi.asset.StringAsset(sFunc()),
    'nodejs/node_modules/lodash.snakecase': new pulumi.asset.FileArchive(
      './node_modules/lodash.snakecase'
    ),
  }),
  compatibleRuntimes: [
    aws.lambda.NodeJS10dXRuntime,
    aws.lambda.NodeJS12dXRuntime,
  ],
  layerName: 'lambda_layer_name',
})

// Our lambda that is going to use the custom class.
const lambda = new aws.lambda.CallbackFunction('my-lambda-func', {
  callback: async (event: any, context: any, callback: any) => {
    const { name } = event

    // We use require so pulumi doesn't try to resolve these modules.
    const { myAwesomeClass } = require('/opt/myAwesomeClass.js')
    const result = myAwesomeClass.transform(name)
    callback(null, result)
  },
  name: 'my-lambda',
  runtime: aws.lambda.NodeJS12dXRuntime,
  layers: [layer.arn],
})

Now that we have created the layer lets deploy it using pulumi up

Let's navigate to the aws console and trigger the lambda we just created and create a test based on the 'Hello Word' test template and use the following as the event payload:

{
  "name": "John Smith"
}

Now we should get the following output

Lambda success message

Currently there is no support for automated dependency checking so every dependency will need to be added to your layer.