Access AWS Lambda with a credentials secret

Use kgateway to route traffic requests directly to an Amazon Web Services (AWS) Lambda function.

Note that this guide uses a Kubernetes secret that contains long-lived IAM user access keys (prefixed AKIA), not temporary STS/SSO credentials, which can cause failures with signature errors. To use AWS IAM roles to control access instead, see Access AWS Lambda with a service account.

Before you begin

  1. Follow the Get started guide to install kgateway.

  2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

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

    export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
    echo $INGRESS_GW_ADDRESS  
    kubectl port-forward deployment/http -n kgateway-system 8080:8080

Create an AWS credentials secret

Create a Kubernetes secret that contains your AWS access key and secret key. You must use a long-lived IAM user access keys (prefixed AKIA), not temporary STS/SSO credentials. Kgateway uses this secret to connect to AWS Lambda for authentication and function invocation.

  1. Save the AWS account and region that your Lambda instance exists in as environment variables.

    export REGION=<us-east-1>
    export ACCOUNT_ID=<account_id>
  2. Save your IAM user access key (prefixed AKIA...) and secret key as environment variables. Make sure that the AWS_SESSION_TOKEN is not set.

    export AWS_ACCESS_KEY_ID="<AKIA-access-key>"
    export AWS_SECRET_ACCESS_KEY="<secret-key>"

    If you do not have a long-lived IAM user access key pair, you can create one for your IAM user.

    • AWS console:
      1. Navigate to IAM → Users → (your user).
      2. In the Security credentials tab, scroll to the Access keys panel, and click Create access key.
      3. Select the CLI option, and create the access key.
      4. Copy the output access key ID (prefixed AKIA...) and secret access key.
    • aws CLI:
      aws iam create-access-key --user-name <iam-user-name>
  3. Verify that these credentials have the appropriate permissions to interact with AWS Lambda.

    aws sts get-caller-identity --region ${REGION}
    aws lambda invoke --function-name echo2 --region ${REGION} /tmp/out.json

    If either command fails, grant the IAM user Lambda invocation permissions in one of the following ways, and re-run the test commands.

    • AWS console:
      1. Navigate to IAM → Users → (your user).
      2. In the Permissions tab, click Add permissions → Create inline policy.
      3. Toggle to the JSON editor.
      4. Paste the following policy to allow Lambda function invocation.
        {
        	"Version": "2012-10-17",
        	"Statement": [
        		{
        			"Effect": "Allow",
        			"Action": "lambda:InvokeFunction",
        			"Resource": "arn:aws:lambda:us-east-1:802411188784:function:echo2"
        		}
        	]
        }
    • aws CLI:
      aws iam put-user-policy \
        --user-name <iam-user-name> \
        --policy-name AllowInvokeEcho2 \
        --policy-document "{
          \"Version\": \"2012-10-17\",
          \"Statement\": [
            {\"Effect\": \"Allow\", \"Action\": \"lambda:InvokeFunction\", \"Resource\": \"arn:aws:lambda:${REGION}:${ACCOUNT_ID}:function:echo2\"}
          ]
        }"
  4. Create a Kubernetes secret that contains the AWS access key and secret key. Leave sessionToken empty for long-lived keys.

    kubectl apply -n kgateway-system -f - << EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: aws-creds
    stringData:
      accessKey: ${AWS_ACCESS_KEY_ID}
      secretKey: ${AWS_SECRET_ACCESS_KEY}
      sessionToken: ""
    type: Opaque
    EOF

Create a Lambda function

Create an AWS Lambda function to test kgateway 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 a Backend and HTTPRoute

Create Backend and HTTPRoute resources to route requests to the Lambda function.

  1. In your terminal, create a Backend resource that references the Lambda secret. Update the region with your AWS account region, such as us-east-1, and update the accountId.

    kubectl apply -f - <<EOF
    apiVersion: gateway.kgateway.dev/v1alpha1
    kind: Backend
    metadata:
      name: lambda
      namespace: kgateway-system
    spec:
      type: AWS
      aws:
        region: ${REGION}
        accountId: "${ACCOUNT_ID}"
        auth:
          type: Secret
          secretRef:
            name: aws-creds
        lambda:
          functionName: echo
    EOF
  2. Create an HTTPRoute resource that references the lambda Backend.

    kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: lambda
      namespace: kgateway-system
    spec:
      parentRefs:
        - name: http
          namespace: kgateway-system
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /echo
        backendRefs:
        - name: lambda
          namespace: kgateway-system
          group: gateway.kgateway.dev
          kind: Backend
    EOF
  3. Confirm that kgateway correctly routes requests to Lambda by sending a curl request to the echo function.

    curl -H "Host: lambda.${REGION}.amazonaws.com" \
      $INGRESS_GW_ADDRESS:8080/echo \
      -d '{"key1":"value1", "key2":"value2"}' -X POST
    curl -H "Host: lambda.${REGION}.amazonaws.com" \
      localhost:8080/echo \
      -d '{"key1":"value1", "key2":"value2"}' -X POST

    Example response:

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

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

Cleanup

You can remove the resources that you created in this guide.

  1. Delete the lambda HTTPRoute and lambda Backend.

    kubectl delete HTTPRoute lambda -n kgateway-system
    kubectl delete Backend lambda -n kgateway-system
  2. Delete the aws-creds secret.

    kubectl delete secret aws-creds -n kgateway-system
  3. Use the AWS Lambda console to delete the echo test function.