AWS Lambda Extension (Experimental)edit
This functionality is in technical preview and may be changed or removed in a future release. Elastic will apply best effort to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.
Elastic’s APM Agents instrument AWS Lambda functions via an AWS Lambda Extension.
Extension Architectureedit
Normally, during the execution of a Lambda function, there’s only a single language process running in the AWS Lambda execution environment. However, with an AWS Lambda Extension, Lambda users can run a second process alongside their main service/application process.
By using a custom-built AWS Lambda Extension, Elastic APM Agents can send data to a locally running Lambda Extension process, and that process will forward data on to APM Server. The Lambda Extension ensures that any latency between the Lambda function and the AWS Server instance will not cause latency in the Lambda function/Service itself.
Instrumenting a Lambda Functionedit
The rest of this guide contains instructions for instrumenting a Lambda function. There are two high level steps to instrumenting an AWS Lambda function.
-
Installing the Lambda Extension
- Configuring the Agent and Lambda Function handler
We’ll start with installing the Lambda extension.
Installing the Lambda Extension using the Installeredit
Elastic offers an installer for adding the Lambda Extension to your Lambda functions. If you’d prefer to skip the installer and manually install the extension, see the Manual Installation section below.
This installer will:
- Compile the Lambda Extension from source (written in go)
- Publish the Lambda Extension as a layer
- Configure a named Lambda function with the just published layer
- Configure the required environmental variables
If you’d rather manually install and configuration the Lambda Extension, see the Manual Installation section below.
The installer is distributed via GitHub as a Node.js project. Once you’ve cloned the repository and installed a version of Node.js, run the following commands.
$ cd cli $ npm install # installs the dependencies for the cli $ cp install.yaml.dist install.yaml # edit install.yaml to use your values (see below) $ ./elastic-lambda.js install
The elastic-lambda.js
command assumes you have a install.yaml
file configured. There’s a sample of this file distributed with the repository. To use it, just copy the file and edit its contents.
$ cp install.yaml install.yaml.dist
Important: The installer assumes your local environment is configured to authenticate against the AWS APIs using Amazon’s standard environment variables. Depending on your authentication method, this may look something like the following
$ AWS_DEFAULT_REGION=us-west-2 \ AWS_ACCESS_KEY_ID=AKIAZEDJODE3B3UMDAKX \ AWS_SECRET_ACCESS_KEY=hmE7n1gfiyXzgwOQu2bxOA92HrVVWh8WG \ ./elastic-lambda.js install
Configuring the Installeredit
A fully configured install.yaml
might look like the following
install: config: layer_name: "apm-lambda-extension" function_name: "your-function-name" lambda_env: ELASTIC_APM_LOG_LEVEL: "info" ELASTIC_APM_SECRET_TOKEN: "D...a" ELASTIC_APM_SERVER_URL: "https://apm-server.example.com:443" ELASTIC_APM_SERVICE_NAME: "Your Service Name" ELASTIC_APM_DATA_RECEIVER_TIMEOUT_SECONDS: "15"
The meaning of each install.yaml
configuration field is as follows.
layer_name
edit
This is the name the compiler will use for your AWS Layer. The default, apm-lambda-extension
, should work for most scenarios.
function_name
edit
The name of your Lambda function. The installer will use this to configure the correct Lambda function. This must be the name of a function that already exists.
lambda_env
edit
The installer will use the key/value pairs in this section of the configuration file to add environment variables to your Lambda function. The provided variables are those required to make the extension work correctly.
ELASTIC_APM_LOG_LEVEL
edit
The log level for the APM Agent. Consult your APM Agent’s documentation for more information.
ELASTIC_APM_SECRET_TOKEN
edit
The APM secret token. The extension will use this when communicating with APM Server.
ELASTIC_APM_API_KEY
edit
An alternative authentication method to the secret token. The extension will use this when communicating with APM Server.
ELASTIC_APM_SERVER_URL
edit
Your APM Server URL. This is the final destination for your data.
ELASTIC_APM_SERVICE_NAME
edit
The configured name of your application or service. The APM Agent will use this value when reporting data to APM Server.
If unset, the APM Agent will automatically set the value based on AWS_LAMBDA_FUNCTION_NAME
or context.functionName
.
ELASTIC_APM_DATA_RECEIVER_TIMEOUT_SECONDS
edit
The timeout value, in seconds, for the Lambda Extension’s server.
Manual Installationedit
It’s possible to install and configure the extension manually. In order to do so, you’ll need to
- Download a release zip file
- Publish that release zip file as a Lambda layer
- Configure your function to use that layer
- Configure your function’s environment variables correctly
Download a Released Extensionedit
The extension is released as a ZIP archive via the GitHub releases page. To download an archive, simply navigate to the latest version, and choose either the AMD64 or ARM64 release (depending on which architecture your Lambda function uses).
Publish a Lambda layeredit
Next, you’ll want to take that release ZIP file and publish it as a Lambda layer. A Lambda layer is a zip file archive that contains additional code or files for your Lambda function.
To do this, navigate to the Layers section of the AWS console, click the Create layer button, and follow the prompts to upload the ZIP archive as a layer.
After publishing a layer, you’ll receive a Version ARN. This ARN is the layer’s unique identifier.
Configure the Layeredit
Once you’ve published a layer, you’ll need to configure your function to use that layer. To add a layer
- Navigate to your function in the AWS Console
-
Scroll to the Layers section and click the Add a layer button
- Choose the Specify an ARN radio button
- Enter the Version ARN of your layer in the Specify an ARN text input
- Click the Add button
Configure your Environment Variablesedit
Finally, once the layer’s in place you’ll need to configure a few environmental variables. To configure variables
- Navigate to your function in the AWS Console
- Click on the Configuration tab
- Click on Environment variables
- Add the necessary variables.
The Necessary Variablesedit
The necessary environment variables depend on the APM agent being used. Follow the Node.js agent setup guide, Python agent setup guide or Java agent setup guide, respectively, for specific instructions on setting the environment variables.
ELASTIC_APM_CENTRAL_CONFIG
edit
The ELASTIC_APM_CENTRAL_CONFIG
value must be set to false
. Central configuration does not work in a Lambda environment, and having this on will negatively impact the performance of your Lambda function.
ELASTIC_APM_CLOUD_PROVIDER
edit
The ELASTIC_APM_CLOUD_PROVIDER
value must be set to none
. Amazon’s Cloud Metadata APIs are not available in an AWS Lambda environment, and attempting to fetch this data will negatively impact the performance of your Lambda function.
ELASTIC_APM_LAMBDA_APM_SERVER
edit
The ELASTIC_APM_LAMBDA_APM_SERVER
controls where the Lambda extension will ship data. This should be the URL of the final APM Server destination for your telemetry.
ELASTIC_APM_SECRET_TOKEN
or ELASTIC_APM_API_KEY
edit
Either ELASTIC_APM_API_KEY
or ELASTIC_APM_SECRET_TOKEN
needs to be set. This controls the authentication method that the extension uses when sending data to the URL configured via ELASTIC_APM_LAMBDA_APM_SERVER
.
ELASTIC_APM_SERVER_URL
edit
This must be configured to the value http://localhost:8200
. This configuration field controls where your APM Agent sends data. The extension listens for data on localhost:8200
.
Configuring the Agent and Lambda Function handleredit
Once you’ve installed the extension, there’s one last step to take. You’ll need to wrap the Lambda function handler.
Node.jsedit
In Node.js, you wrap a Lambda function handler using the following syntax.
const apm = require('elastic-apm-node').start({/*...*/}) exports.handler = apm.lambda(async function handler (event, context) { const response = { statusCode: 200, body: "hello new async." }; return response })
See the Node.js agent setup guide for detailed instructions on setting up the Node.js agent for AWS Lambda.
Pythonedit
In Python, you wrap a Lambda function handler using the following syntax.
from elasticapm import capture_serverless @capture_serverless() def handler(event, context): return {"statusCode": r.status_code, "body": "Success!"}
See the Python agent setup guide for detailed instructions on setting up the Python agent for AWS Lambda.
Javaedit
Like the extension, the Elastic APM Java agent is installed as a Lambda layer. Since it relies on a wrapper script to automatically attach to the Lambda function, not all environment variables listed in The Necessary Variables need to be configured.
See the Java agent setup guide for detailed instructions on setting up the Java agent for AWS Lambda.