Invoke an AWS Lambda function

AWS Lambda is a flexible and cost effective service which allows you to implement back-end functionality in a serverless environment. In this tutorial we will learn how to invoke a Lambda function. There are mainly two way to do that:

  • Manually (using a test event)
  • Programmatically

JavaScript/Node.js will be used in code snippets, but their logic should be easily transferable to the rest of the supported languages.

This article assumes that you already have a Lambda function in your AWS account.

Manual invocation

This is the most straight forward way to invoke your Lambda function.

  1. In your function's page, click on Select a test event on the top right, and then Configure test events: Select test event
  2. Give your event a descriptive name and specify the function's payload in JSON format. Then, click on Create: Create test event

Easy, right? Now we can click the Test button on the function's page, and see it in action: Execute test event

⚠️ Bear in mind that although this is called a test event, the function is executed in its real environment and not in a sandbox. Emails will be sent, files will be deleted etc.

Use cases

Test events are very helpful when you want to quickly test your function, especially when you first deploy it. Since they are saved in your account, you can reuse them in future testing. There are some limitations though:

  • A function can have up to 10 test events (see AWS Lambda limits)
  • You cannot specify the expected output in the event configuration

For those reasons and also in general, automated tests may be a better investment in the longer term.

Test events also work in cases where you want your function to be invoked manually. For example, you may create a function that deploys a server based on the provided configuration, but you don't want to do this in every build. Or you function may perform a data integrity check, required on specific occasions.

Programmatic invocation

Create a Lambda invoker user

In order to invoke our Lambda function programatically, we need a user with appropriate permissions.

The simplest approach is is creating an admin user and keep attaching permissions to them. While this may be fine for a personal project, it is generally not best practice. For collaborative projects you will most probably need a more sophisticated approach.

Here we will guide you on creating a user with as fine-grained permissions as possible.

  1. Login to your AWS account and go to the IAM service page: Select IAM

  2. Select Users on the left sidebar, and Add User in the next page: Add User

  3. Enter a name for the new user and check Programmatic access in Access Type: Add User - Step 1

  4. In the next page, select Attach existing policies directly and click on Create policy: Add User - Step 2a

  5. A page will open in a new tab. Enter the following values, then click on Review policy:

    • Service: Lambda
    • Actions: InvokeAsync
    • Resources: Click on Add ARN to provide the ARN of your function. You can find this in your function's page, or you can use the popup the appears to calculate it on the spot
    • Request Conditions: Use the default values

    Create Policy

  6. Enter a name for your policy and click on Create Policy: Review Policy

  7. Go back to the original user creation tab, and find the new policy in the list. Check the box on its left and click on Next: Tags

    ⚠️ You need to refresh the page to view the new policy Add User - Step 2b

  8. We can skip adding tags by clicking on Next: Review Add User - Step 3

  9. The following step is a summary of the new user. Click on Create user: Add User - Step 4

  10. The final step provides us with the credentials (access key id & secret access key) for the new user. Note them down since we will need them later on: Add User - Step 5

Code Implementation

We will use aws-sdk to invoke our Lambda function in a Node.js application. First, let's add it as dependency:

npm install aws-sdk

Now let's create an invokeAsyncLambda helper for invoking lambda functions:

const Lambda = require('aws-sdk/clients/lambda');

const lambda = new Lambda({
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region: process.env.AWS_REGION,
});

const invokeAsyncLambda = (functionName, payload, callback) =>
lambda.invoke(
{
FunctionName: functionName,
InvocationType: 'Event',
Payload: JSON.stringify(payload),
},
/**
* @function
* @param {?Error} error
* @param {?{ StatusCode, Payload }} results
*/
(error, results) => callback(error, results),
);

module.exports = invokeAsyncLambda;

This code expects some variables to be defined in the runtime environment:

  • AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY: The credentials we created in the Create a Lambda invoker user step Find SMTP Host
  • AWS_REGION: The AWS region of our function

Usage example

The snippet below will invoke a senEmail function with an event of the form
{ from, to, subject, text, html }:

const senEmail = ({ from, to, subject, text, html }) => {
const payload = { from, to, subject, text, html };

return invokeAsyncLambda('sendEmail', payload, (error, results) => {
if (error) {
throw new Error(error);
}
const { StatusCode } = results;
console.log(
`Email was sent successfully! Status code: ${StatusCode}`,
);
});
};

Other implementations

Your application may need to call multiple Lambda functions. The above code will still work under the following conditions:

  • All functions are defined in the same region
  • The specified user has access to all of them

In reality, your circumstances may be different, so you will need to adjust the exact implementation accordingly. For example, your functions may be defined across multiple regions. In this case you can use the Registry Pattern in a LambdaClients class, which instantiates and grants access to specific Lambda clients according to the region.