Invoke an AWS Lambda function from Kong. It can be used in combination with other request plugins to secure, manage or extend the function.

Note: The functionality of this plugin as bundled with versions of Kong prior to 0.14.0 and Kong Enterprise prior to 0.34 differs from what is documented herein. Refer to the CHANGELOG for details.

Terminology

  • plugin: a plugin executing actions inside Kong before or after a request has been proxied to the upstream API.
  • Service: the Kong entity representing an external upstream API or microservice.
  • Route: the Kong entity representing a way to map downstream requests to upstream services.
  • Consumer: the Kong entity representing a developer or machine using the API. When using Kong, a Consumer only communicates with Kong which proxies every call to the said upstream API.
  • Credential: a unique string associated with a Consumer, also referred to as an API key.
  • upstream service: this refers to your own API/service sitting behind Kong, to which client requests are forwarded.
  • API: a legacy entity used to represent your upstream services. Deprecated in favor of Services since CE 0.13.0 and EE 0.32.

Configuration

Enabling the plugin on a Service

Configure this plugin on a Service by making the following request:

$ curl -X POST http://kong:8001/services/{service}/plugins \
    --data "name=aws-lambda"  \
    --data-urlencode "config.aws_key=AWS_KEY" \
    --data-urlencode "config.aws_secret=AWS_SECRET" \
    --data "config.aws_region=AWS_REGION" \
    --data "config.function_name=LAMBDA_FUNCTION_NAME"

  • service: the id or name of the Service that this plugin configuration will target.

Enabling the plugin on a Route

Configure this plugin on a Route with:

$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
    --data "name=aws-lambda"  \
    --data-urlencode "config.aws_key=AWS_KEY" \
    --data-urlencode "config.aws_secret=AWS_SECRET" \
    --data "config.aws_region=AWS_REGION" \
    --data "config.function_name=LAMBDA_FUNCTION_NAME"

  • route_id: the id of the Route that this plugin configuration will target.

Enabling the plugin on a Consumer

You can use the http://localhost:8001/plugins endpoint to enable this plugin on specific Consumers:

$ curl -X POST http://kong:8001/plugins \
    --data "name=aws-lambda" \
    --data "consumer_id={consumer_id}"  \
    --data-urlencode "config.aws_key=AWS_KEY" \
    --data-urlencode "config.aws_secret=AWS_SECRET" \
    --data "config.aws_region=AWS_REGION" \
    --data "config.function_name=LAMBDA_FUNCTION_NAME"

Where consumer_id is the id of the Consumer we want to associate with this plugin.

You can combine consumer_id and service_id

in the same request, to furthermore narrow the scope of the plugin.

Enabling the plugin on an API

If you are using an older version of Kong with the legacy API entity (deprecated in favor of Services since CE 0.13.0 and EE 0.32.), you can configure this plugin on top of such an API by making the following request:

$ curl -X POST http://kong:8001/apis/{api}/plugins \
    --data "name=aws-lambda"  \
    --data-urlencode "config.aws_key=AWS_KEY" \
    --data-urlencode "config.aws_secret=AWS_SECRET" \
    --data "config.aws_region=AWS_REGION" \
    --data "config.function_name=LAMBDA_FUNCTION_NAME"

  • api: either id or name of the API that this plugin configuration will target.

Global plugins

All plugins can be configured using the http://kong:8001/plugins/ endpoint. A plugin which is not associated to any Service, Route or Consumer (or API, if you are using an older version of Kong) is considered "global", and will be run on every request. Read the Plugin Reference and the Plugin Precedence sections for more information.

Parameters

Here's a list of all the parameters which can be used in this plugin's configuration:

form parameterdefaultdescription
nameThe name of the plugin to use, in this case aws-lambda
service_idThe id of the Service which this plugin will target.
route_idThe id of the Route which this plugin will target.
enabledtrueWhether this plugin will be applied.
consumer_idThe id of the Consumer which this plugin will target.
api_idThe id of the API which this plugin will target. Note: The API Entity is deprecated in favor of Services since CE 0.13.0 and EE 0.32.
config.aws_key

The AWS key credential to be used when invoking the function

config.aws_secret

The AWS secret credential to be used when invoking the function

config.aws_region

The AWS region where the Lambda function is located. Regions supported are: us-east-1, us-east-2, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap-southeast-2, eu-central-1, eu-west-1

config.function_name

The AWS Lambda function name to invoke

config.qualifier
optional

The Qualifier to use when invoking the function.

config.invocation_type
optional

RequestResponse

The InvocationType to use when invoking the function. Available types are RequestResponse, Event, DryRun

config.log_type
optional

Tail

The LogType to use when invoking the function. By default None and Tail are supported

config.timeout
optional

60000

An optional timeout in milliseconds when invoking the function

config.keepalive
optional

60000

An optional value in milliseconds that defines how long an idle connection will live before being closed

config.unhandled_status
optional

200, 202 or 204

The response status code to use (instead of the default 200, 202, or 204) in the case of an Unhandled Function Error

config.forward_request_body
optional

false

An optional value that defines whether the request body is to be sent in the request_body field of the JSON-encoded request. If the body arguments can be parsed, they will be sent in the separate request_body_args field of the request. The body arguments can be parsed for application/json, application/x-www-form-urlencoded, and multipart/form-data content types.

config.forward_request_headers
optional

false

An optional value that defines whether the original HTTP request headers are to be sent as a map in the request_headers field of the JSON-encoded request.

config.forward_request_method
optional

false

An optional value that defines whether the original HTTP request method verb is to be sent in the request_method field of the JSON-encoded request.

config.forward_request_uri
optional

false

An optional value that defines whether the original HTTP request URI is to be sent in the request_uri field of the JSON-encoded request. Request URI arguments (if any) will be sent in the separate request_uri_args field of the JSON body.

Reminder: curl by default sends payloads with an application/x-www-form-urlencoded MIME type, which will naturally be URL- decoded by Kong. To ensure special characters that are likely to appear in your AWS key or secret (like +) are correctly decoded, you must URL-encode them, hence use --data-urlencode if you are using curl. Alternatives to this approach would be to send your payload with a different MIME type (like application/json), or to use a different HTTP client.

Sending parameters

Any form parameter sent along with the request, will be also sent as an argument to the AWS Lambda function.

Known Issues

Use a fake upstream service

When using the AWS Lambda plugin, the response will be returned by the plugin itself without proxying the request to any upstream service. This means that a Service’s host, port, path properties will be ignored, but must still be specified for the entity to be validated by Kong. The host property in particular must either be an IP address, or a hostname that gets resolved by your nameserver.

When the plugin is added to an API entity (which is deprecated as of 0.13.0), it is the upsream_url property which must be specified and resolvable as well (but ignored).

Response plugins

There is a known limitation in the system that prevents some response plugins from being executed. We are planning to remove this limitation in the future.


Step By Step Guide

The Steps

  1. Access to AWS Console as user allowed to operate with lambda functions and create user and roles.
  2. Create an Execution role in AWS
  3. Create an user which will be invoke the function via Kong, test it.
  4. Create an API in Kong, add the aws-lambda plugin linked to our aws function and execute it.

Configure

  1. First, let’s create an execution role called LambdaExecutor for our lambda function.

    In IAM Console create a new Role choosing the AWS Lambda service, there will be no policies as our function in this example will simply execute itself giving us back an hardcoded JSON as response without accessing other AWS resources.

  2. Now let’s create a user named KongInvoker, used by our Kong API gateway to invoke the function.

    In IAM Console create a new user, must be provided to it programmatic access via Access and Secret keys; then will attach existing policies directly particularly the AWSLambdaRole predefined. Once the user creation is confirmed, store Access Key and Secret Key in a safe place.

  3. Now we need to create the lambda function itself, will do so in N.Virginia Region (code us-east-1).

    In Lambda Management, create a new function Mylambda, there will be no blueprint as we are going to paste the code below; for the execution role let’s choose an existing role specifically LambdaExecutor created previously

    Use the inline code below to have a simple JSON response in return, note this is code for Python 3.6 interpreter.

     import json
     def lambda_handler(event, context):
         jsonbody='''{"response": "yes"}'''
         return json.loads(jsonbody)
    

    Test the lambda function from the AWS console and make sure the execution succeeds.

  4. Finally we setup the api in Kong and link it to the function just created.

    The api that we are going to create doesn’t really need a real upstream_url since we are not going to have an HTTP call to upstream but rather a response generated by our function.

     curl -i -X POST http://{kong_hostname}:8001/apis \
     --data 'name=lambda1' \
     --data 'upstream_url=http://localhost:8000' \
     --data 'uris=/lambda1'
    

    Add the plugin:

     curl -i -X POST http://{kong_hostname}:8001/apis/lambda1/plugins \
     --data 'name=aws-lambda' \
     --data-urlencode 'config.aws_key={KongInvoker user key}' \
     --data-urlencode 'config.aws_secret={KongInvoker user secret}' \
     --data 'config.aws_region=us-east-1' \
     --data 'config.function_name=MyLambda'
    

    Call the Api and verify the correct invocation, execution and response:

     curl http://{kong_hostname}:8000/lambda1
    

    Additional headers:

     x-amzn-Remapped-Content-Length, X-Amzn-Trace-Id, x-amzn-RequestId
    

    JSON response:

     {"response": "yes"}
    

Have fun leveraging the power of AWS Lambda in Kong!