Configure AWS IAM permissions
Create IAM roles for Gloo 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 Gateway supports discovering and invoking AWS Lambda functions by using IRSAs. For more information, see the AWS documentation.
Note that if you completed the Get started guide, your AWS IAM permissions are already set up. You can proceed to providing AWS account and Lambda details in a CloudProvider
resource.
Before you begin
-
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.
Step 1: Save your AWS account details
Save your AWS account details to use in IAM resources in subsequent steps.
-
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:\/\///")
Step 2: Allow the management server to discover Lambda functions
Create an IRSA for the Gloo Gateway management server pods to assume to discover Lambda functions in your AWS account.
-
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
-
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
-
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
-
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" } ] }
-
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 ...
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.
-
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
-
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-19-service-account
is the name of the ingress gateway service account:NAME SECRETS AGE default 1 45m istio-ingressgateway-1-19-service-account 1 45m
-
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-19-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 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
-
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" } ] }
-
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-19-3-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-19-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-19-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-19-service-account -n gloo-mesh-gateways
Example output:
Name: istio-ingressgateway-1-19-service-account Namespace: gloo-mesh-gateways Labels: app=istio-ingressgateway install.operator.istio.io/owning-resource=istio-ingressgateway-1-19 install.operator.istio.io/owning-resource-namespace=gm-iop-1-19 istio=ingressgateway istio.io/rev=1-19 operator.istio.io/component=IngressGateways operator.istio.io/managed=Reconcile operator.istio.io/version=1.19.3-solo release=istio revision=1-19 Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::931713665590:role/gloo-lambda-gateway-invoke Image pull secrets: <none> Mountable secrets: istio-ingressgateway-1-19-service-account-token-rwvq8 Tokens: istio-ingressgateway-1-19-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 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:
- Assume the default IRSA that the Gloo Gateway service account uses for invocation.
- Assume a specific, override IAM role that you provide.
- Do not assume a role and instead use a resource-based invocation policy.
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 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.
Invoking Lambda functions by using a resource-based policy is supported only for ingress gateways that run Solo Istio version 1.17.3 and later.
-
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”).
-
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>
-
When you create your
CloudProvider
in the workspace for account B, do not specify thelambda.invokeRoleName
field. The workloads in the account B workspace can use the resource-based policy permisson to invoke the Lambda function in account A.
For more information about separating access by teams, see Use CloudProvider CRs for multitenancy.
Next steps
- Provide AWS account and Lambda details in a
CloudProvider
resource. - Manage multitenancy by controlling which teams’ workloads can discover and invoke specific Lambda functions.