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.
- In your function's page, click on Select a test event on the top right, and then Configure test events:
- Give your event a descriptive name and specify the function's
payload
in JSON format. Then, click on Create:
Easy, right? Now we can click the Test button on the function's page, and see it in action:
⚠️ 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.
Login to your AWS account and go to the IAM service page:
Select Users on the left sidebar, and Add User in the next page:
Enter a name for the new user and check Programmatic access in Access Type:
In the next page, select Attach existing policies directly and click on Create policy:
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
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
The following step is a summary of the new user. Click on Create user:
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:
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
andAWS_SECRET_ACCESS_KEY
: The credentials we created in the Create a Lambda invoker user stepAWS_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.