Overview

Amazon Web Services (AWS) offers the ability to associate an IAM role with a Kubernetes service account, also known as creating an IRSA. Gloo Mesh 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 Mesh Gateway service accounts (an IRSA)
  • Create a Lambda function for testing

Gloo resources:

  • Annotate Gloo Mesh Gateway service accounts with the IRSA
  • Provide AWS account and Lambda details in CloudProvider and CloudResources 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:

Figure: Gloo custom resources for AWS Lambda details
Figure: Gloo custom resources for AWS Lambda details
  1. 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.
  2. Gloo Mesh 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 Mesh Gateway assumes an IAM role to invoke the function.
  3. The Lambda function in your AWS account receives the request, and returns a response to Gloo Mesh Gateway.
  4. Gloo Mesh Gateway applies any transformations that you configured (such as AWS response transformations) to the response, and returns it to the client.

Before you begin

  1. Install Gloo Mesh Gateway. Your ingress gateway proxies must run a Solo distribution of Istio, and note that certain Lambda integration features, such as unwrapping Lambda responses in the same way as an AWS API Gateway, require Istio version 1.15.1 or later.

    • Install quickly with meshctl.
    • Customize your installation with Helm.
  2. Configure an HTTPS listener on your ingress gateway.

Configure AWS IAM resources

Save your AWS details, and create an IRSA for the Gloo Mesh Gateway deployment pods to use.

  1. Save the details of the AWS region and account that your Lambda functions are in.

      export AWS_REGION=<region>
    export ACCOUNT_ID=<account_id>
      
  2. 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
        
  3. Create an IAM OIDC provider for your EKS cluster that you plan to use for Gloo Mesh Gateway.

  4. 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:\/\///")
      
  5. 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 Mesh 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.

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

    1. 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
        
    2. 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
        
    3. 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"
              }
          ]
      }
        
    4. Get the current Helm values for your Gloo installation.
        helm get values gloo-platform -n gloo-mesh -o yaml > gloo-gateway-single.yaml
        
    5. Annotate the management server service account with the ARN of its IAM role.
        helm upgrade --install gloo-platform gloo-platform/gloo-platform \
      --namespace gloo-mesh \
      --version $GLOO_VERSION \
      --values gloo-gateway-single.yaml \
      --set glooMgmtServer.serviceAccount.extraAnnotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::$ACCOUNT_ID:role/gloo-lambda-mgmt-discover
        
    6. 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
      ...
        
  7. 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.

    1. 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-23-service-account is the name of the ingress gateway service account:
        NAME                                        SECRETS   AGE
      default                                     1         45m
      istio-ingressgateway-1-23-service-account   1         45m
        
    2. 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-23-service-account"
              }
            }
          }
        ]
      }
      EOF
      
      aws iam create-role --role-name gloo-lambda-gateway-invoke --assume-role-policy-document file://invoke-role.json
        
    3. 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
        
    4. 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"
              }
          ]
      }
        
    5. Annotate the ingress gateway service account with the ARN of its IAM role. These steps differ depending on whether you used the Gloo gateway lifecycle manager to install your gateways, or manually deployed an unmanaged ingress gateway with an Istio Helm chart.
    6. Verify that the service account is annotated with the IRSA.
        kubectl describe serviceaccount istio-ingressgateway-1-23-service-account -n gloo-mesh-gateways
        
      Example output:
        Name:                istio-ingressgateway-1-23-service-account
      Namespace:           gloo-mesh-gateways
      Labels:              app=istio-ingressgateway
                           install.operator.istio.io/owning-resource=istio-ingressgateway-1-23
                           install.operator.istio.io/owning-resource-namespace=gm-iop-1-23
                           istio=ingressgateway
                           istio.io/rev=1-23
                           operator.istio.io/component=IngressGateways
                           operator.istio.io/managed=Reconcile
                           operator.istio.io/version=1.23.2-patch1-solo
                           release=istio
                           revision=1-23
      Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::931713665590:role/gloo-lambda-gateway-invoke
      Image pull secrets:  <none>
      Mountable secrets:   istio-ingressgateway-1-23-service-account-token-rwvq8
      Tokens:              istio-ingressgateway-1-23-service-account-token-rwvq8
      Events:              <none>
        

Create a Lambda function for testing

Create an AWS Lambda function to test Gloo Mesh Gateway routing.

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

  2. Click the Create Function button.

  3. Name the function test-lambda 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.

Set up routing to your function

To invoke the function from Gloo Mesh 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 a CloudProvider CR. The CloudProvider 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 Mesh Gateway can automatically discover the Lambda functions in your account and region, or whether you want to manually list functions in a CloudResources resource.
  • CloudResources: Details about the functions that Gloo Mesh Gateway can access are listed in the CloudResources CR. If you enable automatic discovery of functions, Gloo creates a CloudResources configuration that contains entries for each Lambda that it discovers. If you do not enable discovery, you can manually specify the functions that Gloo Mesh Gateway can access in a CloudResources 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 a RouteTable CR to define a hostname and a specific path that your Lambda is available through. The route table ensures that Gloo Mesh Gateway directs all requests on the hostname and path to your function, and uses the correct IAM roles from your CloudProvider resource to invoke the function.

Figure: Gloo custom resources for AWS Lambda details
Figure: Gloo custom resources for AWS Lambda details

  1. Define your AWS details and IAM roles in a CloudProvider resource. The configuration steps vary depending on whether you want Gloo Mesh Gateway to automatically discover the Lambda functions in your account and region, or you want to manually list functions in a CloudResources resource.

  2. 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 the virtualGateways 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
      
  3. 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
      
  4. 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.blackhole.solo.unused: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-23-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 Mesh Gateway uses a dummy route for the connection between Gloo Mesh Gateway and AWS Lambda, such as dummy-route.blackhole.solo.unused: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 Mesh Gateway to invoke Lambda functions, check out the following pages to configure your own functions for Gloo Mesh Gateway invocation.