About

Serverless functions, such as Lambda functions, provide an alternative to traditional applications or services. The functions run on servers that you do not have to manage yourself, and you pay for only for the compute time you use. However, you might want to invoke your serverless functions from other services or apps, such as the Kubernetes workloads that run in your Gloo Gateway environment. By abstracting a Lambda as a type of destination in your Gloo Gateway environment, your workloads can send requests to the Lambda destination in the same way that you set up routing through Gloo Gateway to other types of destinations. Gloo Gateway does the work of assuming an AWS IAM role to invoke the actual Lambda function in your AWS account.

For more information, see the AWS Lambda documentation on configuring Lambda functions as targets.

Before you begin

  1. Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.

  2. Get the external address of the gateway and save it in an environment variable.

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 authentication and function invocation.

  1. 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.

  2. 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 ${AWS_ACCESS_KEY_ID} \
        --secret-key ${AWS_SECRET_ACCESS_KEY} \
        --session-token ${AWS_SESSION_TOKEN}
      

Create a Lambda function

Create an AWS Lambda function to test routing.

  1. Log in to the AWS console and navigate to the Lambda page.

  2. Click the Create Function button.

  3. Name the function echo and click Create function.

  4. Replace the default contents of index.mjs with the following Node.js function, which returns a response body that contains exactly what was sent to the function in the request body.

      export const handler = async(event) => {
        const response = {
            statusCode: 200,
            body: `Response from AWS Lambda. Here's the request you just sent me: ${JSON.stringify(event)}`
        };
        return response;
    };
      
  5. Click Deploy.

Create an Upstream and HTTPRoute

Create Gloo Gateway Upstream and HTTPRoute resources to route requests to the Lambda function.

  1. Save the AWS region where your account and Lambda fuction exist, such as us-east-1, in an environment variable.

      export AWS_LAMBDA_REGION=<region>
      
  2. In your terminal, create an Upstream resource that references the Lambda secret.

      kubectl apply -f - <<EOF
    apiVersion: gloo.solo.io/v1
    kind: Upstream
    metadata:
      name: lambda
      namespace: gloo-system
    spec:
      aws:
        region: $AWS_LAMBDA_REGION
        secretRef:
          name: aws-creds
          namespace: gloo-system
        lambdaFunctions:
        - lambdaFunctionName: echo
          logicalName: echo
          qualifier: $LATEST
    EOF
      
  3. Create an HTTPRoute resource that references the lambda Upstream.

      kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: lambda
      namespace: gloo-system
    spec:
      parentRefs:
        - name: http
          namespace: gloo-system
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /echo
        backendRefs:
        - name: lambda
          namespace: gloo-system
          group: gloo.solo.io
          kind: Upstream
          filters:
            - type: ExtensionRef
              extensionRef:
                group: "gloo.solo.io"
                kind: Parameter
                name: echo
    EOF
      
  4. Confirm that Gloo Gateway correctly routes requests to Lambda by sending a curl request to the echo function.

    Example response:

      {"statusCode":200,"body":"Response from AWS Lambda. Here's the request you just sent me: {\"key1\":\"value1\",\"key2\":\"value2\"}"}% 
      

At this point, Gloo Gateway is routing directly to the echo Lambda function!

Transform responses

You can use the aws.destinationOverrides.unwrapAsApiGateway=true setting in Upstream resources to configure Gloo Gateway to unwrap the response as if the gateway proxy is an AWS API Gateway. This can help provide a smooth migration from AWS gateways to Gloo Gateway.

  1. Use the AWS Lambda console again to create another Node.js function named unwrap-test. Use the following code for the function.

      export const handler = async(event) => {
        const response = {
            "statusCode": 201,
            "headers": {
                "key": "value"
            },
            "isBase64Encoded": false,
            "multiValueHeaders": { 
                "X-Custom-Header": ["My value", "My other value"],
            },
            "body": JSON.stringify({TotalCodeSize: 104330022,FunctionCount: 26})
        }
        return response;
    };
      
  2. Create a new Upstream resource to reference the upwrap-test function. Note that this Upstream does not yet include the unwrapAsApiGateway setting.

      kubectl apply -f - <<EOF
    apiVersion: gloo.solo.io/v1
    kind: Upstream
    metadata:
      name: unwrap-test
      namespace: gloo-system
    spec:
      aws:
        region: $AWS_LAMBDA_REGION
        secretRef:
          name: aws-creds
          namespace: gloo-system
        lambdaFunctions:
        - lambdaFunctionName: unwrap-test
          logicalName: unwrap-test
    EOF
      
  3. Update the HTTPRoute resource that you previously created to add a route for the unwrap-test function.

      kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: lambda
      namespace: gloo-system
    spec:
      parentRefs:
        - name: http
          namespace: gloo-system
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /echo
        backendRefs:
        - name: lambda
          namespace: gloo-system
          group: gloo.solo.io
          kind: Upstream
          filters:
            - type: ExtensionRef
              extensionRef:
                group: "gloo.solo.io"
                kind: Parameter
                name: echo
      - matches:
        - path:
            type: PathPrefix
            value: /unwrap-test
        backendRefs:
        - name: unwrap-test
          namespace: gloo-system
          group: gloo.solo.io
          kind: Upstream
          filters:
            - type: ExtensionRef
              extensionRef:
                group: "gloo.solo.io"
                kind: Parameter
                name: unwrap-test
    EOF
      
  4. Send a curl request to the unwrap-test function.

    Note that the response is in unformatted JSON:

      {"statusCode":201,"headers":{"key":"value"},"isBase64Encoded":false,"multiValueHeaders":{"X-Custom-Header":["My value","My other value"]},"body":"{\"TotalCodeSize\":104330022,\"FunctionCount\":26}"}
      
  5. Update the Upstream resource to include the unwrapAsApiGateway setting.

      kubectl apply -f - <<EOF
    apiVersion: gloo.solo.io/v1
    kind: Upstream
    metadata:
      name: unwrap-test
      namespace: gloo-system
    spec:
      aws:
        region: $AWS_LAMBDA_REGION
        secretRef:
          name: aws-creds
          namespace: gloo-system
        lambdaFunctions:
        - lambdaFunctionName: unwrap-test
          logicalName: unwrap-test
        destinationOverrides:
          unwrapAsApiGateway: true
    EOF
      
  6. Send another curl request to the unwrap-test function.

    This time, the response is unwrapped in the format required by AWS API gateways:

      {"TotalCodeSize":104330022,"FunctionCount":26}
      

Next steps

Cleanup

You can optionally remove the resources that you set up as part of this guide.

  1. Delete the lambda HTTPRoute, and the lambda and unwrap-test Upstreams.

      kubectl delete HTTPRoute lambda -n gloo-system
    kubectl delete Upstream lambda -n gloo-system
    kubectl delete Upstream unwrap-test -n gloo-system
      
  2. Delete the aws-creds secret.

      kubectl delete secret aws-creds -n gloo-system
      
  3. Use the AWS Lambda console to delete the echo and unwrap-test functions.

Known limitations

  • Currently, the only parameter that is supported for the backendRefs.filters.extensionRef field in the HTTPRoute resource is the name of the Lambda function. Additional parameters, such as wrapAsApiGateway, unwrapAsApiGateway, or invocationStyle, are not supported in your HTTPRoute resource. However, you can use the aws.destinationOverrides.unwrapAsApiGateway=true setting in Upstream resources to configure Gloo Gateway to unwrap the response as if the gateway proxy is an AWS API Gateway.