Get started
Invoke AWS Lambda functions from your Gloo Gateway cluster by using an IAM role for a service account (IRSA).
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 getting started tutorial, 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 Gloo Gateway service accounts (an IRSA)
- Create a Lambda function for testing
Gloo resources:
- Annotate Gloo Gateway service accounts with the IRSA
- Provide AWS account and Lambda details in
CloudProvider
andCloudResources
custom resources (CRs) - Set up routing to your function by creating a
RouteTable
CR
After you create these resources, requests to your Lambda function follow this network traffic flow:
- A client makes a request to the host and path that you set up for the function, such as
https://www.example.com/test-lambda
. - Gloo Gateway receives the request for the host as specified in the route table, and matches the host to a particular AWS account and Lambda function as specified in the cloud provider and cloud resource. Using these details, Gloo Gateway assumes an IAM role to invoke the function.
- The Lambda function in your AWS account receives the request, and returns a response to Gloo Gateway.
- Gloo Gateway applies any transformations that you configured (such as AWS response transformations) to the response, and returns it to the client.
Before you begin
The AWS Lambda integration is a beta feature. Beta features might change and are not supported for production. For more information, see Gloo feature maturity.
-
Install Gloo Gateway. Note that certain Lambda integration features, such as unwrapping Lambda responses in the same way as an AWS API Gateway, require ingress gateway proxies to run Istio 1.15.1 or later.
Configure AWS IAM resources
Save your AWS details, and create an IRSA for the Gloo Gateway deployment pods to use.
-
Save the details of the AWS region and account that your Lambda functions are in.
export AWS_REGION=<region> export ACCOUNT_ID=<account_id>
-
Save the AWS Security Token Service (AWS STS) endpoint to use when retrieving the necessary AWS credentials for accessing Lambda functions. Note that STS endpoints are unique to a particular listener port on a workload. For more information about STS endpoints, see the AWS documentation.
- Global STS endpoint (default):
export STS_ENDPOINT=sts.amazonaws.com
- Regional STS endpoints:
export STS_ENDPOINT=sts.$AWS_REGION.com
- Global STS endpoint (default):
-
Associate an IAM OIDC provider to the EKS cluster that you plan to use for Gloo Gateway.
-
Save your cluster's OIDC identity provider in an environment variable.
export OIDC_PROVIDER=$(aws eks describe-cluster --name $CLUSTER_NAME --region $AWS_REGION --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
-
Create an IAM policy to allow access to the following four Lambda actions. Note: In this getting started guide, the permissions to discover and invoke functions are listed in the same policy, and this policy is used by both the Gloo Gateway management server for discovery and the gateway proxy for invocation. In a more advanced setup, you might separate discovery and invocation permissions into two IAM policies. For more information, see Roles for invocation and discovery.
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 gloo-lambda-policy --policy-document file://policy.json
-
Use an IAM role to associate the policy with the Kubernetes service account for the Gloo management server. The management server assumes this role to discover Lambda functions. For more information about these steps, see the AWS documentation.
- Create the following IAM role.
cat >discover-role.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${OIDC_PROVIDER}:aud": "${STS_ENDPOINT}", "${OIDC_PROVIDER}:sub": "system:serviceaccount:gloo-mesh:gloo-mesh-mgmt-server" } } } ] } EOF aws iam create-role --role-name gloo-lambda-mgmt-discover --assume-role-policy-document file://discover-role.json
- Use the IAM role to associate the IAM policy with the service account. This IAM role for the service account is known as an IRSA.
aws iam attach-role-policy --role-name gloo-lambda-mgmt-discover --policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/gloo-lambda-policy
- Verify that the policy is attached to the role.
aws iam list-attached-role-policies --role-name gloo-lambda-mgmt-discover
Example output:
{ "AttachedPolicies": [ { "PolicyName": "gloo-lambda-policy", "PolicyArn": "arn:aws:iam::111122223333:policy/gloo-lambda-policy" } ] }
- Annotate the management server service account with the ARN of its IAM role. In the following Helm upgrade command, make sure to include the same Helm values that you specifed when you installed Gloo Gateway, either as a configuration file in the
--values
flag or with--set
flags. Otherwise, any previous custom values that you set might be overwritten, which might mean that your Gloo agent and gateway proxies are removed. Additionally, note that your release might be namedgloo-mesh-enterprise
instead ofgloo-mgmt
. For more information, see Get your Helm chart values.helm upgrade --install gloo-platform gloo-platform/gloo-platform \ --namespace gloo-mesh \ --version $GLOO_VERSION \ --values gloo-gateway-single.yaml \ --set common.cluster=$CLUSTER_NAME \ --set licensing.glooGatewayLicenseKey=$GLOO_GATEWAY_LICENSE_KEY \ --set glooMgmtServer.serviceAccount.extraAnnotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::$ACCOUNT_ID:role/gloo-lambda-mgmt-discover
- Verify that the service account is annotated with the IRSA.
kubectl describe serviceaccount gloo-mesh-mgmt-server -n gloo-mesh
Example output:
Name: gloo-mesh-mgmt-server Namespace: gloo-mesh Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/gloo-lambda-mgmt-discover Image pull secrets: <none> Mountable secrets: gloo-mesh-mgmt-server-token-qqjfl Tokens: gloo-mesh-mgmt-server-token-qqjfl ...
- Create the following IAM role.
-
Use an IAM role to associate the policy with the Kubernetes service account for the ingress gateway. The gateway assumes this role to invoke Lambda functions. For more information about these steps, see the AWS documentation.
- Find the name of the service account for the ingress gateway. The service account might exist in another namespace, depending on where you deployed your gateway proxy.
kubectl get serviceaccount -n gloo-mesh-gateways
In this example output,
istio-ingressgateway-1-17-service-account
is the name of the ingress gateway service account:NAME SECRETS AGE default 1 45m istio-ingressgateway-1-17-service-account 1 45m
- Create the following IAM role. Change the namespace and name of the ingress gateway service account as needed.
cat >invoke-role.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${OIDC_PROVIDER}:aud": "${STS_ENDPOINT}", "${OIDC_PROVIDER}:sub": "system:serviceaccount:gloo-mesh-gateways:istio-ingressgateway-1-17-service-account" } } } ] } EOF aws iam create-role --role-name gloo-lambda-gateway-invoke --assume-role-policy-document file://invoke-role.json
- Use the IAM role to associate the IAM policy with the service account. This IAM role for the service account is known as an IRSA.
aws iam attach-role-policy --role-name gloo-lambda-gateway-invoke --policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/gloo-lambda-policy
- Verify that the policy is attached to the role.
aws iam list-attached-role-policies --role-name gloo-lambda-gateway-invoke
Example output:
{ "AttachedPolicies": [ { "PolicyName": "gloo-lambda-policy", "PolicyArn": "arn:aws:iam::111122223333:policy/gloo-lambda-policy" } ] }
- Annotate the ingress gateway service account with the ARN of its IAM role. These steps differ depending on whether you installed the ingress gateway with the
istioInstallations
Helm chart setting, created aGatewayLifecycleManager
custom resource, or manually deployed an unmanaged ingress gateway with an Istio Helm chart.If you installed managed gateway proxies by using the
istioInstallations
Helm chart setting:- Perform a canary upgrade of your gateway proxy. When you update your values file to add a canary entry to the
istioInstallations.northSouthGateways.installations
list, include the following following section. Replace$ACCOUNT_ID
with your actual account ID, and update the name of the ingress gateway service account as needed. Note that the other environment variables are provided as example placeholders for the actual values in your file.istioInstallations: ... northSouthGateways: - enabled: true name: istio-ingressgateway installations: # Installation entry for the canary revision - gatewayRevision: $REVISION clusters: - name: $CLUSTER_NAME activeGateway: false istioOperatorSpec: profile: empty hub: $REPO tag: $ISTIO_IMAGE namespace: gloo-mesh-gateways # NEW SECTION k8s: overlays: - apiVersion: v1 kind: ServiceAccount name: istio-ingressgateway-1-17-2-service-account patches: - path: metadata.annotations.eks\.amazonaws\.com/role-arn value: arn:aws:iam::$ACCOUNT_ID:role/gloo-lambda-gateway-invoke
- When you follow the other steps in the upgrade guide, be sure to also include the annotation that you set for the management server in prior steps, so that the value is not overwritten.
helm upgrade --install gloo-platform gloo-platform/gloo-platform \ --namespace gloo-mesh \ --version $GLOO_VERSION \ --values gloo-gateway-single.yaml \ --set common.cluster=$CLUSTER_NAME \ --set licensing.glooGatewayLicenseKey=$GLOO_GATEWAY_LICENSE_KEY \ --set glooMgmtServer.serviceAccount.extraAnnotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::$ACCOUNT_ID:role/gloo-lambda-mgmt-discover
If you installed managed gateway proxies by creating a
GatewayLifecycleManager
CR, perform a canary upgrade to annotate the ingress gateway service account. For more information about these steps, see Performing a canary upgrade.- Edit the
GatewayLifecycleManager
resource for the gateway that you deployed to add another installation entry for the canary revision. For the canary revision, be sure to setdefaultRevision
tofalse
so that only the existing revision continues to run.kubectl edit GatewayLifecycleManager istio-ingressgateway -n gloo-mesh
For example, you might add the following
$REVISION-lambda
canary revision as a new entry in theinstallations
section. Replace$ACCOUNT_ID
with your actual account ID, and update the name of the ingress gateway service account as needed. Note that the other environment variables are provided as example placeholders for the actual values in your file.apiVersion: admin.gloo.solo.io/v2 kind: GatewayLifecycleManager metadata: name: istio-ingressgateway namespace: gloo-mesh spec: installations: # Existing revision - gatewayRevision: $REVISION clusters: - name: $CLUSTER_NAME # Keep this field set to TRUE so that only the existing revision continues to run activeGateway: true istioOperatorSpec: profile: empty ... # Canary revision - gatewayRevision: $REVISION-lambda clusters: - name: $CLUSTER_NAME # Set this field to FALSE so that only the existing revision continues to run activeGateway: false istioOperatorSpec: profile: empty hub: $REPO tag: $ISTIO_IMAGE components: ingressGateways: - name: istio-ingressgateway namespace: gloo-mesh-gateways enabled: true label: istio: ingressgateway app: istio-ingressgateway k8s: service: type: LoadBalancer selector: istio: ingressgateway ports: - name: status-port port: 15021 targetPort: 15021 - port: 80 targetPort: 8080 name: http2 - port: 443 targetPort: 8443 name: https overlays: - apiVersion: v1 kind: ServiceAccount # Change the name of the ingress gateway service account as needed name: istio-ingressgateway-1-17-service-account patches: - path: metadata.annotations.eks\.amazonaws\.com/role-arn value: # Replace with your own account ID arn:aws:iam::$ACCOUNT_ID:role/gloo-lambda-gateway-invoke
- Verify that the ingress gateway for the canary installation is created.
kubectl get all -n gloo-mesh-gateways
- Switch to the new gateway by changing
activeGateway
tofalse
for the old revision and totrue
for the new revision.kubectl edit GatewayLifecycleManager istio-ingressgateway -n gloo-mesh
Example:
apiVersion: admin.gloo.solo.io/v2 kind: GatewayLifecycleManager metadata: name: istio-ingressgateway namespace: gloo-mesh spec: installations: # Old revision - gatewayRevision: $REVISION clusters: - name: $CLUSTER_NAME # Set this field to FALSE activeGateway: false istioOperatorSpec: profile: empty ... # New revision - gatewayRevision: $REVISION-lambda clusters: - name: $CLUSTER_NAME # Set this field to TRUE activeGateway: true istioOperatorSpec: profile: empty ...
- Verify that the active gateways for the new revision are created, which do not have the revision appended to the name. Note that gateways for the inactive revision that you previously ran also exist in the namespace, in the case that a rollback is required.
kubectl get all -n gloo-mesh-gateways
- To uninstall the previous installation, you can edit the
GatewayLifecycleManager
resource to remove the old revision's entry from theinstallations
list.kubectl edit GatewayLifecycleManager istio-ingressgateway -n gloo-mesh
If you manually deployed unmanaged Istio ingress gateways, patch the deployment with the anotated service account.
These steps use the post rendering feature supported in Helm 3.1 and later, along with Kustomize. These features patch the rendered manifest of the
istio-ingressgateway
deployment before it is applied to the cluster without the need to modify the Helm chart itself, because deployment patches cannot be added to theistio-ingressgateway
Helm chart directly.-
Save the following patch, which updates the ingress gateway deployment with the annotated service account before the deployment is applied to the cluster.
cat > sa-patch.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: # Change the name of the ingress gateway service account as needed name: istio-ingressgateway-1-17-service-account annotations: eks.amazonaws.com/role-arn: "arn:aws:iam::$ACCOUNT_ID:role/gloo-lambda-gateway-invoke" EOF
-
To use Kustomize files with Helm rendering, which requires
stdin/stdout
, create a shell script namedkustomize.sh
.cat > kustomize.sh <<EOF #!/bin/sh cat > base.yaml exec kubectl kustomize EOF chmod +x ./kustomize.sh
-
Create the
kustomization.yaml
file, which provides the patch input for Kustomize.cat > kustomization.yaml <<EOF resources: - base.yaml patchesStrategicMerge: - sa-patch.yaml EOF
-
Follow the guide to upgrade the ingress gateway. When you run the
helm upgrade
command for the ingress gateway, be sure to include the--post-renderer ./kustomize.sh
flag, such as the following:helm upgrade --install istio-ingressgateway-${REVISION} istio/gateway \ --version ${ISTIO_IMAGE} \ --create-namespace \ --namespace gloo-mesh-gateways \ --post-renderer ./kustomize.sh \ --wait \ -f ingress-gateway-values.yaml
- Perform a canary upgrade of your gateway proxy. When you update your values file to add a canary entry to the
- Verify that the service account is annotated with the IRSA.
kubectl describe serviceaccount istio-ingressgateway-1-17-service-account -n gloo-mesh-gateways
Example output:
Name: istio-ingressgateway-1-17-service-account Namespace: gloo-mesh-gateways Labels: app=istio-ingressgateway install.operator.istio.io/owning-resource=istio-ingressgateway-1-17 install.operator.istio.io/owning-resource-namespace=gm-iop-1-17 istio=ingressgateway istio.io/rev=1-17 operator.istio.io/component=IngressGateways operator.istio.io/managed=Reconcile operator.istio.io/version=1.16.0-solo release=istio revision=1-17 Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::931713665590:role/gloo-lambda-gateway-invoke Image pull secrets: <none> Mountable secrets: istio-ingressgateway-1-17-service-account-token-rwvq8 Tokens: istio-ingressgateway-1-17-service-account-token-rwvq8 Events: <none>
- Find the name of the service account for the ingress gateway. The service account might exist in another namespace, depending on where you deployed your gateway proxy.
In this getting started guide, the IRSA for the management server is used for all function discovery, and the IRSA for the gateway is used for all function invocation. In a more advanced or multitenant setup, you might create override IAM roles to use for discovering and invoking Lambda functions instead of the IRSAs you annotate the service accounts with. For more information, see Roles for invocation and discovery.
Create a Lambda function for testing
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
test-lambda
and click Create function. -
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; };
-
Click Deploy.
Set up routing to your function
To invoke the function from Gloo Gateway, provide your AWS account and Lambda details in the CloudProvider
and CloudResources
resources. Then, set up routing to your function by creating a RouteTable
.
CloudProvider
: Define your AWS details and IAM roles in aCloudProvider
CR. TheCloudProvider
CR serves as a centralized location for configuration settings for each cloud provider and the resources you want to use, such as AWS and AWS Lambda. You can also choose whether Gloo Gateway can automatically discover the Lambda functions in your account and region, or whether you want to manually list functions in aCloudResources
resource.CloudResources
: Details about the functions that Gloo Gateway can access are listed in theCloudResources
CR. If you enable enable automatic discovery of functions, Gloo creates aCloudResources
configuration that contains entries for each Lambda that it discovers. If you do not enable discovery, you can manually specify the the functions that Gloo Gateway can access in aCloudResources
CR. Each item in the list contains an internal function name to route requests to, the actual name of the Lambda in AWS, and the version of the function to call.RouteTable
: Create aRouteTable
CR to define a hostname and a specific path that your Lambda is available through. The route table ensures that Gloo Gateway directs all requests on the hostname and path to your function, and uses the correct IAM roles from yourCloudProvider
resource to invoke the function.
-
Define your AWS details and IAM roles in a
CloudProvider
resource. The configuration steps vary depending on whether you want Gloo Gateway to automatically discover the Lambda functions in your account and region, or you want to manually list functions in aCloudResources
resource.In multicluster setups, you must createCloudProvider
and anyCloudResources
resources in thegloo-mesh
namespace of the management cluster.- Define your AWS details in a
CloudProvider
resource. These settings enable automatic discovery of functions in your account and region, but filters the functions for the nametest-lambda
.kubectl apply -f - <<EOF apiVersion: infrastructure.gloo.solo.io/v2 kind: CloudProvider metadata: name: aws-provider namespace: gloo-mesh spec: aws: accountId: "$ACCOUNT_ID" region: $AWS_REGION stsEndpoint: $STS_ENDPOINT lambda: discovery: enabled: true filter: name: test-lambda latestOnly: true invokeRoleName: gloo-lambda-gateway-invoke EOF
- Verify that Gloo Gateway discovered the
test-lambda
function. Gloo automatically creates aCloudResources
configuration that contains entries for each Lambda that it discovers.kubectl get CloudResources -n gloo-mesh
- Define your AWS details in a
CloudProvider
resource.kubectl apply -f - <<EOF apiVersion: infrastructure.gloo.solo.io/v2 kind: CloudProvider metadata: name: aws-provider namespace: gloo-mesh spec: aws: accountId: "$ACCOUNT_ID" region: $AWS_REGION stsEndpoint: $STS_ENDPOINT lambda: invokeRoleName: gloo-lambda-gateway-invoke EOF
- Specify the test Lambda that you created in a
CloudResources
resource.kubectl apply -f - <<EOF apiVersion: infrastructure.gloo.solo.io/v2 kind: CloudResources metadata: name: aws-functions namespace: gloo-mesh spec: # Name of the CloudProvider resource provider: aws-provider aws: lambda: # Actual name of the function in AWS - lambdaFunctionName: test-lambda # Version of the function to call qualifier: $LATEST EOF
- Define your AWS details in a
-
Create a
RouteTable
resource to direct all requests on the/test-lambda
path to your Lambda function. Update the example values with your own details as needed, such as thevirtualGateways
reference details.kubectl apply -f - <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: test-lambda-route namespace: gloo-mesh spec: # Applies to any host; can indicate a specific domain, like example.com hosts: - '*' # Selects a virtual gateway you previously created. # Change name and namespace as needed. virtualGateways: - name: istio-ingressgateway namespace: bookinfo http: - name: test-lambda-route labels: route: lambda matchers: - uri: prefix: /test-lambda forwardTo: destinations: # Reference to the function in the CloudProvider resource - awsLambda: cloudProvider: name: aws-provider namespace: gloo-mesh cluster: $CLUSTER_NAME function: test-lambda EOF
-
Get the hostname of your ingress gateway to test the
/test-lambda
route.export INGRESS_GW_IP=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') echo $INGRESS_GW_IP
-
Send a request to the Lambda endpoint to verify that the request is successfully resolved by the gateway.
curl -vik https://${INGRESS_GW_IP}:443/test-lambda -H "host: www.example.com:443"
Example output:
Response from AWS Lambda. Here's the request you just sent me: {"headers":{":authority":"www.example.com",":method":"GET",":path":"/test-lambda",":scheme":"http","accept":"*/*","user-agent":"curl/7.79.1","x-envoy-decorator-operation":"dummy-route-o4bo-WppHSxD6Ox2.badHost.solo.io:8080/test-lambda*","x-envoy-internal":"true","x-envoy-peer-metadata":"ChQKDk<...>","x-envoy-peer-metadata-id":"router~192.168.47.140~istio-ingressgateway-1-17-68bdd78cc4-zqjx7.gloo-mesh-gateways~gloo-mesh-gateways.svc.cluster.local","x-forwarded-for":"192.168.90.112","x-forwarded-proto":"http","x-request-id":"40e70781-3da4-4cf1-8fd2-47b84858fffb"},"httpMethod":"GET","path":"/test-lambda","queryString":""}%
Note: Gloo Gateway uses a dummy route for the connection between Gloo Gateway and AWS Lambda, such as
dummy-route-o4bo-WppHSxD6Ox2.badHost.solo.io:8080/test-lambda*
in this example output. This route indicates that the connection is functioning as intended.
Next steps
Now that you've set up Gloo Gateway to invoke Lambda functions, check out the following pages to configure your own functions for Gloo Gateway invocation.
- Further configure AWS and Lambda settings in your
CloudProvider
andCloudResources
. - Define Lambda routing and apply route table filters based on Lambda function properties.
- Manage multitenancy by controlling which teams’ workloads can discover and invoke specific Lambda functions.
- Review default request and response payload formats, and transformations you can apply to the payload structure.