Access AWS Lambda with a service account
Associate an IAM role with a gateway proxy service account, and configure Gloo Gateway to use that service account to access AWS Lambda.
About
Amazon Web Services (AWS) offers the ability to associate an IAM role with a Kubernetes service account, also known as creating an IRSA. Gloo Gateway supports discovering and invoking AWS Lambda functions by using an IRSA. For more information, see the AWS documentation.
In this guide, you follow these steps:
AWS resources:
- Associate your EKS cluster with an IAM OIDC provider
- Create an IAM policy that allows interactions with Lambda functions
- Create an IAM role that associates the IAM policy with the gateway proxy service account (an IRSA)
- Deploy the Amazon EKS Pod Identity Webhook to your cluster
- Create a Lambda function for testing
Gloo Gateway resources:
- Install Gloo Gateway
- Annotate the gateway proxy service account with the IRSA
- Set up routing to your function by creating
UpstreamandHTTPRouteresources
Configure AWS IAM resources
Save your AWS details, and create an IRSA for the gateway proxy pod to use.
Save the region where your Lambda functions exist, the region where your EKS cluster exists, your cluster name, and the ID of the AWS account.
export AWS_LAMBDA_REGION=<lambda_function_region> export AWS_CLUSTER_REGION=<cluster_region> export CLUSTER_NAME=<cluster_name> export AWS_ACCOUNT_ID=<account_id>Check whether your EKS cluster has an OIDC provider.
export OIDC_PROVIDER=$(aws eks describe-cluster --name ${CLUSTER_NAME} --region ${AWS_CLUSTER_REGION} --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///") echo $OIDC_PROVIDER- If an OIDC provider in the format
oidc.eks.<region>.amazonaws.com/id/<cluster_id>is returned, continue to the next step. - If an OIDC provider is not returned, follow the AWS documentation to Create an IAM OIDC provider for your cluster, and then run this command again to save the OIDC provider in an environment variable.
- If an OIDC provider in the format
Create an IAM policy to allow access to the following four Lambda actions. Note that the permissions to discover and invoke functions are listed in the same policy. In a more advanced setup, you might separate discovery and invocation permissions into two IAM policies.
cat >policy.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lambda:ListFunctions", "lambda:InvokeFunction", "lambda:GetFunction", "lambda:InvokeAsync" ], "Resource": "*" } ] } EOF aws iam create-policy --policy-name lambda-policy --policy-document file://policy.jsonUse an IAM role to associate the policy with the Kubernetes service account for the HTTP gateway proxy, which assumes this role to invoke Lambda functions. For more information about these steps, see the AWS documentation.
- Create the following IAM role. Note that the service account name
httpin thegloo-systemnamespace is specified, because in later steps you create an HTTP gateway namedhttp.cat >role.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${OIDC_PROVIDER}:sub": "system:serviceaccount:gloo-system:http" } } } ] } EOF aws iam create-role --role-name lambda-role --assume-role-policy-document file://role.json - Attach the IAM role to the IAM policy. This IAM role for the service account is known as an IRSA.
aws iam attach-role-policy --role-name lambda-role --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/lambda-policy - Verify that the policy is attached to the role.Example output:
aws iam list-attached-role-policies --role-name lambda-role{ "AttachedPolicies": [ { "PolicyName": "lambda-policy", "PolicyArn": "arn:aws:iam::111122223333:policy/lambda-policy" } ] }
- Create the following IAM role. Note that the service account name
Deploy the Amazon EKS Pod Identity Webhook
Before you install Gloo Gateway, deploy the Amazon EKS Pod Identity Webhook, which allows pods’ service accounts to use AWS IAM roles. When you create the Gloo Gateway proxy in the next section, this webhook mutates the proxy’s service account so that it can assume your IAM role to invoke Lambda functions.
In your EKS cluster, install cert-manager, which is a prerequisite for the webhook.
wget https://github.com/cert-manager/cert-manager/releases/download/v1.12.4/cert-manager.yaml kubectl apply -f cert-manager.yamlVerify that all cert-manager pods are running.
kubectl get pods -n cert-managerDeploy the Amazon EKS Pod Identity Webhook.
kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/gloo-gateway/1-19/enterprise/lambda/data/steps/deploy-amazon-pod-identity-webhook/auth.yaml kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/gloo-gateway/1-19/enterprise/lambda/data/steps/deploy-amazon-pod-identity-webhook/deployment-base.yaml kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/gloo-gateway/1-19/enterprise/lambda/data/steps/deploy-amazon-pod-identity-webhook/mutatingwebhook.yaml kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/gloo-gateway/1-19/enterprise/lambda/data/steps/deploy-amazon-pod-identity-webhook/service.yamlVerify that the webhook deployment completes.
kubectl rollout status deploy/pod-identity-webhook
Install Gloo Gateway
Be sure that you deployed the Amazon EKS Pod Identity Webhook to your cluster first before you continue to install Gloo Gateway.
Set your Gloo Gateway license key as an environment variable. If you do not have one, contact an account representative.
If you want to use the capabilities of agentgateway enterprise, you need an additional agentgateway enterprise license.
export GLOO_GATEWAY_LICENSE_KEY=<gloo-gateway-license-key> export AGENTGATEWAY_LICENSE_KEY=<agentgateway-license-key>Deploy the Kubernetes Gateway API CRDs.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard-install.yamlDeploy the Gloo Gateway CRDs by using Helm. The following command uses the latest stable release, 2.0.2. For active development, update the version to 2.1.0-main.
helm upgrade -i gloo-gateway-crds oci://us-docker.pkg.dev/solo-public/gloo-gateway/charts/gloo-gateway-crds \ --create-namespace \ --namespace gloo-system \ --version 2.0.2Install Gloo Gateway by using Helm. Choose between the Envoy-based kgateway proxy or the AI-first agentgateway proxy. You can also enable both gateway proxy types. Note that you need a separate license for each gateway proxy type that you want to enable. For more information, see Gateway proxies.
Make sure that the
gloo-gatewaycontrol plane is running.kubectl get pods -n gloo-systemExample output:
NAME READY STATUS RESTARTS AGE gloo-gateway-5495d98459-46dpk 1/1 Running 0 19s
Annotate the gateway proxy service account
Create a GatewayParameters resource to specify the
eks.amazonaws.com/role-arnIRSA annotation for the gateway proxy service account.kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: GatewayParameters metadata: name: http-lambda namespace: gloo-system spec: kube: serviceAccount: extraAnnotations: eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda-role EOFCreate the following
httpGateway resource, which includes a reference to thehttp-lambdaGatewayParameters.kubectl apply -f- <<EOF kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: http namespace: gloo-system annotations: spec: gatewayClassName: gloo-gateway-v2 infrastructure: parametersRef: name: http-lambda group: gateway.kgateway.dev kind: GatewayParameters listeners: - protocol: HTTP port: 8080 name: http allowedRoutes: namespaces: from: All EOFCheck the status of the gateway to make sure that your configuration is accepted. Note that in the output, a
NoConflictsstatus ofFalseindicates that the gateway is accepted and does not conflict with other gateway configuration.kubectl get gateway http -n gloo-system -o yamlVerify that the
httpservice account has theeks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda-roleannotation.kubectl describe serviceaccount http -n gloo-system
Create a Lambda function
Create an AWS Lambda function to test Gloo Gateway routing.
Log in to the AWS console and navigate to the Lambda page.
Click the Create Function button.
Name the function
echoand click Create function.Replace the default contents of
index.mjswith 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; };Click Deploy.
Set up routing to your function
Create Backend and HTTPRoute resources to route requests to the Lambda function.
Create a Backend resource that references the AWS region, ID of the account that contains the IAM role, and
echofunction that you created.kubectl apply -f - <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: Backend metadata: name: lambda namespace: gloo-system spec: type: AWS aws: region: ${AWS_LAMBDA_REGION} accountId: "${AWS_ACCOUNT_ID}" lambda: functionName: echo EOFCreate an HTTPRoute resource that references the
lambdaBackend.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: gateway.kgateway.dev kind: Backend EOFGet the external address of the gateway and save it in an environment variable.
Confirm that Gloo Gateway correctly routes requests to Lambda by sending a curl request to the
echofunction. Note that the first request might take a few seconds to process, because the AWS Security Token Service (STS) credential request must be performed first. However, after the credentials are cached, subsequent requests are processed more quickly.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 using an IRSA!
Cleanup
You can remove the resources that you created in this guide.
Resources for the echo function
Delete the
lambdaHTTPRoute andlambdaBackend.kubectl delete HTTPRoute lambda -n gloo-system kubectl delete Backend lambda -n gloo-systemUse the AWS Lambda console to delete the
echotest function.
IRSA authorization (optional)
If you no longer need to access Lambda functions from Gloo Gateway:
Delete the GatewayParameters resources.
kubectl delete GatewayParameters http-lambda -n gloo-systemRemove the reference to the
http-lambdaGatewayParameters from thehttpGateway.kubectl apply -f- <<EOF kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: http namespace: gloo-system spec: gatewayClassName: gloo-gateway-v2 listeners: - protocol: HTTP port: 8080 name: http allowedRoutes: namespaces: from: All EOFDelete the pod identity webhook.
kubectl delete deploy pod-identity-webhookRemove cert-manager.
kubectl delete -f cert-manager.yaml -n cert-manager kubectl delete ns cert-managerDelete the AWS IAM resources that you created.
aws iam detach-role-policy --role-name lambda-role --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/lambda-policy aws iam delete-role --role-name lambda-role aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/lambda-policy