Skip to content

Configure AWS IAM permissions

Page as Markdown

Create IAM roles for Gloo Mesh Gateway service accounts to access, discover, and invoke Lambda functions.

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}: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 istio-ingress

    In this example output, istio-ingressgateway-main-service-account is the name of the ingress gateway service account:

    NAME                                        SECRETS   AGE
    default                                     1         45m
    istio-ingressgateway-main-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": {
            "Service": "ec2.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        },
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "${OIDC_PROVIDER}:sub": "system:serviceaccount:istio-ingress:istio-ingressgateway-main-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.

    If you manually deployed unmanaged Istio ingress gateways, patch the deployment with the annotated 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 the istio-ingressgateway Helm chart directly.

    1. 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-main-service-account
        annotations:
          eks.amazonaws.com/role-arn: "arn:aws:iam::$ACCOUNT_ID:role/gloo-lambda-gateway-invoke"
      EOF
    2. To use Kustomize files with Helm rendering, which requires stdin/stdout, create a shell script named kustomize.sh.

      cat > kustomize.sh <<EOF
      #!/bin/sh
      cat > base.yaml
      exec kubectl kustomize
      EOF
      chmod +x ./kustomize.sh
    3. Create the kustomization.yaml file, which provides the patch input for Kustomize.

      cat > kustomization.yaml <<EOF
      resources:
      - base.yaml
      patchesStrategicMerge:
      - sa-patch.yaml
      EOF
    4. 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} \
        --namespace istio-ingress \
        --post-renderer ./kustomize.sh \
        --wait \
        -f ingress-gateway-values.yaml

    Version 2.11 and earlier only: If you use Gloo-managed gateway proxies, follow the steps in the Istio lifecycle manager upgrade guide. In the istioOperatorSpec.components.ingressGateways.k8s section, add the following overlay to annotate the service account. 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.

    ...
    istioOperatorSpec:
      profile: empty
      hub: $REPO
      tag: $ISTIO_IMAGE
      components:
        ingressGateways:
        - name: istio-ingressgateway
          namespace: istio-ingress
          enabled: true
          label:
            istio: ingressgateway
            app: istio-ingressgateway
          k8s:
            overlays:
              - apiVersion: v1
                kind: ServiceAccount
                # Change the name of the ingress gateway service account as needed
                name: istio-ingressgateway-main-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

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

    kubectl describe serviceaccount istio-ingressgateway-main-service-account -n istio-ingress

    Example output:

    Name:                istio-ingressgateway-main-service-account
    Namespace:           istio-ingress
    Labels:              app=istio-ingressgateway
                         install.operator.istio.io/owning-resource=istio-ingressgateway-main
                         install.operator.istio.io/owning-resource-namespace=gm-iop-main
                         istio=ingressgateway
                         istio.io/rev=main
                         operator.istio.io/component=IngressGateways
                         operator.istio.io/managed=Reconcile
                         operator.istio.io/version=1.29.1-solo
                         release=istio
                         revision=main
    Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::931713665590:role/gloo-lambda-gateway-invoke
    Image pull secrets:  <none>
    Mountable secrets:   istio-ingressgateway-main-service-account-token-rwvq8
    Tokens:              istio-ingressgateway-main-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