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 IRSAs. For more information, see the AWS documentation.

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.

Step 1: Save your AWS account details

Save your AWS account details to use in IAM resources in subsequent steps.

  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:\/\///")
      

Step 2: Allow the management server to discover Lambda functions

Create an IRSA for the Gloo Mesh Gateway management server pods to assume to discover Lambda functions in your AWS account.

  1. Create an IAM policy to allow access to the following Lambda actions.

      cat >policy.json <<EOF
    {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "lambda:ListFunctions",
                   "lambda:GetFunction",
               ],
               "Resource": "*"
           }
       ]
    }
    EOF
    
    aws iam create-policy --policy-name gloo-lambda-discover --policy-document file://policy.json 
      
  2. Create the following IAM role that contains your AWS account details and management server service account name.

      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
      
  3. Use the IAM role to associate the policy with the Kubernetes service account for the Gloo management server. This IAM role for the service account is known as an IRSA. The management server assumes this role to discover Lambda functions. For more information, see the AWS documentation.

      aws iam attach-role-policy --role-name gloo-lambda-mgmt-discover --policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/gloo-lambda-discover
      
  4. 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-discover",
                "PolicyArn": "arn:aws:iam::111122223333:policy/gloo-lambda-discover"
            }
        ]
    }
      
  5. Get the current Helm values for your Gloo installation.

      helm get values gloo-platform -n gloo-mesh -o yaml > gloo-gateway-single.yaml
      
  6. 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
      
  7. 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
    ...
      

Step 3: Allow the gateway proxy to invoke Lambda functions

Create an IRSA for the Gloo ingress gateway pods to assume to invoke Lambda functions in your AWS account.

  1. Create an IAM policy to allow access to the following Lambda actions.

      cat >policy.json <<EOF
    {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "lambda:InvokeFunction",
                   "lambda:InvokeAsync"
               ],
               "Resource": "*"
           }
       ]
    }
    EOF
    
    aws iam create-policy --policy-name gloo-lambda-invoke --policy-document file://policy.json
      
  2. 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-22-service-account is the name of the ingress gateway service account:

      NAME                                        SECRETS   AGE
    default                                     1         45m
    istio-ingressgateway-1-22-service-account   1         45m
      
  3. Create the following IAM role that contains your AWS account details and service account name. 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-22-service-account"
            }
          }
        }
      ]
    }
    EOF
    
    aws iam create-role --role-name gloo-lambda-gateway-invoke --assume-role-policy-document file://invoke-role.json
      
  4. Use the IAM role to associate the IAM policy with the service account for the ingress gateway. This IAM role for the service account is known as an IRSA. The gateway assumes this role to invoke Lambda functions. For more information, see the AWS documentation.

      aws iam attach-role-policy --role-name gloo-lambda-gateway-invoke --policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/gloo-lambda-invoke
      
  5. 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-invoke",
                "PolicyArn": "arn:aws:iam::111122223333:policy/gloo-lambda-invoke"
            }
        ]
    }
      
  6. 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.

  7. Verify that the service account is annotated with the IRSA.

      kubectl describe serviceaccount istio-ingressgateway-1-22-service-account -n gloo-mesh-gateways
      

    Example output:

      Name:                istio-ingressgateway-1-22-service-account
    Namespace:           gloo-mesh-gateways
    Labels:              app=istio-ingressgateway
                         install.operator.istio.io/owning-resource=istio-ingressgateway-1-22
                         install.operator.istio.io/owning-resource-namespace=gm-iop-1-22
                         istio=ingressgateway
                         istio.io/rev=1-22
                         operator.istio.io/component=IngressGateways
                         operator.istio.io/managed=Reconcile
                         operator.istio.io/version=1.22.3-patch0-solo
                         release=istio
                         revision=1-22
    Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::931713665590:role/gloo-lambda-gateway-invoke
    Image pull secrets:  <none>
    Mountable secrets:   istio-ingressgateway-1-22-service-account-token-rwvq8
    Tokens:              istio-ingressgateway-1-22-service-account-token-rwvq8
    Events:              <none>
      

Step 4: Decide how workloads can invoke functions

On the next page, you provide the details of your AWS account and Lambda functions to Gloo Mesh Gateway in a CloudProvider CR. When you create the CloudProvider, you choose how workloads in a workspace can invoke the Lambda functions in an AWS account.

Workloads can invoke functions in the following ways:

Default IRSA

If you want workloads to use the same IRSA that the gateway service account assumes, no further IAM resources are needed. When you create your CloudProvider, you specify that IRSA role name in the lambda.invokeRoleName field. For example, in this guide, the IRSA is named gloo-lambda-gateway-invoke.

Specific override IAM role

If you want workloads to use a specific IAM role that is different from the IRSA on the gateway deployment, create that IAM role, and specify that role name in the lambda.invokeRoleName field of your CloudProvider. For example, if you want a team’s workloads to only access a certain subset of all the Lambda functions that Gloo Mesh Gateway can invoke, you might specify an IAM role that grants permission to only that subset. For more information about separating access by teams, see Use CloudProvider CRs for multitenancy.

Resource-based invocation policy

If you do not want workloads to assume an IAM role at all, you can instead set up a resource-based invocation policy for a Lambda function for the workload pod to use. This setup is especially useful for cross-account function invocation, because the resource-based policy can give other accounts the permission to invoke the function, without requiring the other account to assume a role. Note that through the IRSA of the ingress gateway, the workload still has an identity in the account that the Lambda function is in. However, the workload does not assume this role for invocation.

  1. Get the ARN or name of the Lambda function that you want to invoke (in “account A”), and ID of the account where you want to invoke from (“account B”).

  2. For the Lambda function in account A, create a resource-based policy statement so that any identity in account B can invoke the function. In the following example, replace <account-A-lambda-arn> with the Lambda function’s ARN or name, and <account-B-id> with the second account’s ID.

      aws lambda add-permission \
    --statement-id test-cross-account \
    --action lambda:InvokeFunction \
    --output text \
    --function-name <account-A-lambda-name-or-arn> \
    --principal <account-B-id>
      
  3. When you create your CloudProvider in the workspace for account B, do not specify the lambda.invokeRoleName field. The workloads in the account B workspace can use the resource-based policy permission to invoke the Lambda function in account A.

For more information about separating access by teams, see Use CloudProvider CRs for multitenancy.

Next steps