AWS Lambda
Route traffic requests directly to an Amazon Web Services (AWS) Lambda function.
About
Gloo Gateway enables you to route traffic requests directly to your AWS Lambda functions. To also use Gloo Gateway in place of your AWS ALB or AWS API Gateway, you can configure the unwrapAsAlb
or unwrapAsApiGateway
setting (Gloo Gateway Enterprise only, version 1.12.0 or later) in the AWS destinationSpec
of the route to your Lambda upstream. These settings allow Gloo Gateway to manipulate a response from an upstream Lambda in the same way as an AWS ALB or AWS API Gateway.
For more information, see the AWS Lambda documentation on configuring Lambda functions as targets.
Set up routing to AWS Lambda
Before you begin: The following steps require you to use the access key and secret key for your AWS account. Ensure that the credentials for your AWS account have appropriate permissions to interact with AWS Lambda. For more information, see the AWS credentials documentation.
Step 1: Create an AWS Lambda
Create an AWS Lambda function to test with Gloo Gateway routing.
-
Log in to the AWS console and navigate to the Lambda page.
-
Note your region, which is used when configuring the AWS upstream in subsequent steps.
-
Click the Create Function button.
-
Name the function
echo
and selectNode.js 16.x
for the runtime. -
Replace the default contents of
index.js
with the following Node.js Lambda, which returns a response body that contains exactly what was sent to the function in the request body.exports.handler = async (event) => { return event; };
Step 2: Create an AWS credentials secret
Create a Kubernetes secret that contains your AWS access key and secret key. Gloo Gateway uses this secret to connect to AWS Lambda for service discovery.
-
Get the access key, secret key, and session token for your AWS account. If your AWS account setup does not require a session token, you can remove the session token parameter from the Kubernetes secret. Note that your AWS credentials must have the appropriate permissions to interact with AWS Lambda.
-
Create a Kubernetes secret that contains the AWS access key and secret key.
glooctl create secret aws \ --name 'aws-creds' \ --namespace gloo-system \ --access-key $ACCESS_KEY \ --secret-key $SECRET_KEY \ --session-token $SESSION_TOKEN
Step 3: Create an upstream and virtual service
Create Gloo Gateway Upstream
and VirtualService
resources to route requests to the Lambda function.
-
Create an upstream resource that references the Lambda secret. Update the region with your Lamda location, such as
us-east-1
.kubectl apply -f - <<EOF apiVersion: gloo.solo.io/v1 kind: Upstream metadata: name: aws-upstream namespace: gloo-system spec: aws: region: <region> secretRef: name: aws-creds namespace: gloo-system EOF
glooctl create upstream aws \ --name 'aws-upstream' \ --namespace 'gloo-system' \ --aws-region '<region>' \ --aws-secret-name 'aws-creds' \ --aws-secret-namespace 'gloo-system'
-
Verify that Gloo Gateway can access AWS Lambda via your AWS credentials. In the
spec.aws.lambdaFunctions
section of the output, verify that theecho
Lambda function is listed.kubectl get upstream -n gloo-system aws-upstream -o yaml
-
Create a VirtualService resource containing a
routeAction
that points to the AWS Lambda upstream. Note that this resource directs Gloo Gateway to route requests directly to the Lambda upstram, but does not manipulate the JSON response.kubectl apply -f - <<EOF apiVersion: gateway.solo.io/v1 kind: VirtualService metadata: name: aws-route namespace: gloo-system spec: virtualHost: domains: - '*' routes: - matchers: - exact: / routeAction: single: destinationSpec: aws: logicalName: echo upstream: name: aws-upstream namespace: gloo-system EOF
-
Confirm that Gloo Gateway is correctly routing requests to Lambda by sending a curl request.
curl $(glooctl proxy url)/ -d '{"key1":"value1", "key2":"value2"}' -X POST
Example response:
{"key1":"value1", "key2":"value2"}
At this point, Gloo Gateway is routing directly to the echo
Lambda function. To configure Gloo Gateway to also unwrap the JSON response from the function in the same way as an AWS ALB or AWS API Gateway, continue to the next section.
Transform requests and/or responses
Basic request transformations
When you use the AWS Lambda plug-in in Gloo Gateway, you might want to transform requests to increase the amount of information passed to the Lambda function.
The request transformation injects the headers of the request into the body. The resulting body will be a JSON object containing two keys: ‘headers’, which contains the injected headers, and ‘body’, which contains the original body.
Note that request transformations are incompatible with the wrapAsApiGateway
setting, which transforms requests into the format produced by an AWS API Gateway.
Before you begin: Install Gloo Gateway version 1.12.0 or later in a Kubernetes cluster or upgrade your existing installation to version 1.12.0 or later.
- Edit the VirtualService resource that you created in the previous section to add the
destinationSpec.aws.requestTransformation: true
setting.kubectl edit virtualservices.gateway.solo.io -n gloo-system aws-route
... routeAction: single: destinationSpec: aws: logicalName: echo requestTransformation: true upstream: name: aws-upstream namespace: gloo-system
Unwrap responses as an AWS ALB
Unwrap the JSON response from the function in the same way as an AWS ALB.
In the following steps, you configure the unwrapAsAlb
setting in the AWS destinationSpec
of the route to your Lambda upstream. These settings allow Gloo Gateway to manipulate a response from an upstream Lambda in the same way as an AWS ALB .
-
Edit the VirtualService resource that you created in the previous section to add the
destinationSpec.aws.unwrapAsAlb: true
setting.kubectl edit virtualservices.gateway.solo.io -n gloo-system aws-route
... routeAction: single: destinationSpec: aws: logicalName: echo unwrapAsAlb: true upstream: name: aws-upstream namespace: gloo-system
-
Verify that Gloo Gateway correctly routes traffic requests to the Lambda function and unwraps the response from the function.
curl $(glooctl proxy url)/ -d '{"body": "gloo edge is inserting this body", "headers": {"test-header-key": "test-header-value"}, "statusCode": 201}' -X POST -v
A successful response contains the same body string, response headers, and status code that you provided in the curl command, such as the following:
* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > POST / HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.64.1 > Accept: */* > Content-Length: 116 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 116 out of 116 bytes < HTTP/1.1 201 Created < test-header-key: test-header-value < content-length: 32 < date: Mon, 25 Jul 2022 13:37:05 GMT < server: envoy < * Connection #0 to host localhost left intact gloo edge is inserting this body* Closing connection 0
Wrap or unwrap requests and responses as an AWS API Gateway (Enterprise v1.12.0+ only)
In Gloo Gateway Enterprise, you can use Gloo Gateway in place of an AWS API Gateway. To do this, configure the wrapAsApiGateway
setting or the unwrapAsApiGateway
setting (Gloo Gateway Enterprise only, version 1.12.0 or later) in the AWS destinationSpec
of the route to your Lambda upstream. These settings allow Gloo Gateway to manipulate a response from an upstream Lambda in the same way as an AWS API Gateway.
Unwrap as API Gateway
Unwrap the JSON response from the function in the same way as an AWS API Gateway.
Note that to use the unwrapAsApiGateway
setting, your Lambda function must be capable of returning a response in the form that is required by an AWS API Gateway. Gloo Gateway looks for a JSON response from the Lambda upstream that contains the following specific fields:
body
: String containing the desired response body.headers
: JSON object containing a mapping from the desired response header keys to the desired response header values.multiValueHeaders
: JSON object containing a mapping from the desired response header keys to a list of the desired response header values that you want to map to a header key.statusCode
: Integer representing the desired HTTP response status code (default200
).isBase64Encoded
: Boolean for whether to decode the provided body string as base64 (defaultfalse
).
For more information, see the AWS Lambda documentation on how AWS API Gateways process Lambda responses.
Before you begin: Install Gloo Gateway Enterprise version 1.12.0 or later in a Kubernetes cluster or upgrade your existing Enterprise installation to version 1.12.0 or later.
-
Edit the VirtualService resource that you created in the previous section to add the
destinationSpec.aws.unwrapAsApiGateway: true
setting.kubectl edit virtualservices.gateway.solo.io -n gloo-system aws-route
... routeAction: single: destinationSpec: aws: logicalName: echo unwrapAsApiGateway: true upstream: name: aws-upstream namespace: gloo-system
-
Verify that Gloo Gateway correctly routes traffic requests to the Lambda function and unwraps the response from the function.
curl $(glooctl proxy url)/ -d '{"body": "gloo edge is inserting this body", "headers": {"test-header-key": "test-header-value"}, "statusCode": 201}' -X POST -v
A successful response contains the same body string, response headers, and status code that you provided in the curl command, such as the following:
* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > POST / HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.64.1 > Accept: */* > Content-Length: 116 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 116 out of 116 bytes < HTTP/1.1 201 Created < test-header-key: test-header-value < content-length: 32 < date: Mon, 25 Jul 2022 13:37:05 GMT < server: envoy < * Connection #0 to host localhost left intact gloo edge is inserting this body* Closing connection 0
Wrap as API Gateway
Wrap the request to the function in the same way as an AWS API Gateway.
Before you begin: Install Gloo Gateway Enterprise version 1.12.0 or later in a Kubernetes cluster or upgrade your existing Enterprise installation to version 1.12.0 or later.
-
Edit the VirtualService resource that you created in the previous section to add the
destinationSpec.aws.unwrapAsApiGateway: true
setting.kubectl edit virtualservices.gateway.solo.io -n gloo-system aws-route
... routeAction: single: destinationSpec: aws: logicalName: echo wrapAsApiGateway: true upstream: name: aws-upstream namespace: gloo-system
-
Verify that Gloo Gateway correctly routes traffic requests to the Lambda function and unwraps the response from the function.
curl $(glooctl proxy url)/ -d 'gloo edge is inserting this body' -H 'test-header-key: test-header-value' -X POST -v
A successful response contains the body as received by the upstream lambda function, such as the following:
* Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > POST / HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.85.0 > Accept: */* > test-header-key: test-header-value > Content-Length: 32 > Content-Type: application/x-www-form-urlencoded > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < date: Mon, 13 Feb 2023 13:22:06 GMT < content-type: application/json < content-length: 754 < x-amzn-requestid: 24c24091-ddf9-4bc5-9799-e86f06ca60b7 < x-amzn-remapped-content-length: 0 < x-amz-executed-version: $LATEST < x-amzn-trace-id: root=1-63ea397d-75fcad35063993b6357a03ce;sampled=0 < x-envoy-upstream-service-time: 397 < server: envoy < * Connection #0 to host localhost left intact {"body": "gloo edge is inserting this body", "headers": {":authority": "localhost:8080", ":method": "POST", ":path": "/", ":scheme": "http", "accept": "*/*", "content-length": "32", "content-type": "application/x-www-form-urlencoded", "test-header-key": "test-header-value", "user-agent": "curl/7.85.0", "x-forwarded-proto": "http", "x-request-id": "347975da-fa61-4d8a-9285-ee0826202819"}, "httpMethod": "POST", "isBase64Encoded": false, "multiValueHeaders": null, "multiValueQueryStringParameters": null, "path": "/", "pathParameters": null, "queryStringParameters": null, "requestContext": {"httpMethod": "POST", "path": "/", "protocol": "HTTP/1.1", "resourcePath": "/"}, "resource": "/", "routeKey": "POST /", "stageVariables": null, "version": "1.0"}%