:wave: I was wondering about something, when writi...
# typescript
b
👋 I was wondering about something, when writing lambdas using Typescript and wanting to define it using
aws.lambda.Function
, do I have to bundle the typescript code or can I just point it to a directory?
Copy code
|- application
|  | - index.ts
|- infrastructure
| | - pulumi.ts
I was following the samples doing this:
Copy code
export const exampleFunction = new aws.lambda.Function('actionRunnerLambda', {
  role: lambdaRole.arn,
  runtime: 'nodejs18.x',
  handler: 'index.handler',
  code: new AssetArchive({
    '.': new FileArchive('./application/')
  })
})
Where
index.ts
exports a “handler” function. However, when trying to upload this I get that it can’t find the handler “index.handler”. I need to use the
Function
to defined the Lambda as I need to specify things like the runtime and environment variables. This I can not do if I use for instance
createFunctionFromEventHandler
. I was wondering if I have to compile the typescript first and then point the file archive there?
b
If you use a
callbackFunction
resource then yes you can point it at the handler
Most of our examples have the code within the resource, but you can do something like this https://gist.github.com/pierskarsenbarg/75040eeeee9d97d6f21289215df6bf84
(that’s old code, hence the node v12)
You can use the
CallbackFunction
pretty much everywhere in the AWS provider where you specify a
Function
resource
Worth noting that the way Pulumi serialises the code, you can’t do the usual best practices like having database connections outside of the main handler code
But you can have them inside the handler code like this:
Copy code
import * as aws from "@pulumi/aws";
import { BucketEvent } from "@pulumi/aws/s3";

export const onObjectCreatedLambda = (e: BucketEvent) => {
    const db = new aws.sdk.DynamoDB.DocumentClient();
    for (const rec of e.Records || []) {
        const key = rec.s3.object.key;
        let params = {
            TableName: process.env.TABLENAME || "",
            Item: {
                'objectkey': key,
                'timestamp': new Date().toISOString()
            }
        };
        db.put(params, function (err, data) {
            if (err) {
                console.log("Error", err);
            } else {
                console.log(`Written ${key} to db`);
            }
        });
    }
};
b
ahh, thanks a lot for explaining this. it did the trick of course 🙂
I have run into a new snag, which is that I continue to get problems with using libraries and Pulumi refusing to serialize. errors such as this:
Copy code
which could not be serialized because it was a native code function.
or
Copy code
arrow function captured 'this'. Assign 'this' to another name outside function and capture that.
is the only way to get around these to revert to using Function and then use FileAssets?
b
Yes that’s correct. The AWS SDK is built in to the Pulumi AWS Provider SDK, but you can’t serialise other packages. So yes, you’ll need to use Function with FileAssets and ensure that everything is bundled up (you can use things like webpack for this)
b
it would be only certain dependencies it doesn’t like though? as I have some which work just fine. I guess I will have to switch it then, and try to solve the issue I had with never being able to find the handler function when using those assets resources 😅 💦