In order to restrict what Flyte components are entitled to do in an AWS environment, this guide leverages the integration between Kubernetes Service Accounts and IAM Roles. In this way, Flyte’s control plane components and data plane Pods (where the actual workflows run) will use Kubernetes service accounts associated with a set of permissions defined in the IAM Role. Any changes in the scope of permissions or policies in the IAM Role, will be inherited by the Kubernetes resources providing centralized control over Authorization:
- Verify that an OIDC issuer was created as part of the EKS deployment process:
aws eks describe-cluster --region <region> --name <Name-EKS-Cluster> --query "cluster.identity.oidc.issuer" --output text
- Create the OIDC provider that will be associated with the EKS cluster:
eksctl utils associate-iam-oidc-provider --cluster <Name-EKS-Cluster> --approve
- From the AWS Management Console, verify that the OIDC provider has been created by going to IAM and then Identity providers. There should be a new provider entry has with the same issuer as the cluster’s.
In order to restrict the permissions enabled for Flyte (both the backend and the worker Pods) you will create a custom IAM Policy.
- Create a
flyte-IAM-policy.json
file with the following contents, inserting the name of your S3 bucket where indicated:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:DeleteObject*",
"s3:GetObject*",
"s3:ListBucket",
"s3:PutObject*"
],
"Resource": [
"arn:aws:s3:::<your-S3-bucket>",
"arn:aws:s3:::<your-S3-bucket>/*"
]
}
]
}
- Create the IAM policy:
aws iam create-policy --policy-name flyte-custom-policy --policy-document file://flyte-IAM-policy.json
Example output:
{
"Policy": {
"PolicyName": "fthw-test-2",
"PolicyId": "ANPAYS5I3UDGHFR7TZ4CD",
"Arn": "arn:aws:iam::<AWS-ACCOUNT>:policy/<policy-name>",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2023-11-30T17:32:17+00:00",
"UpdateDate": "2023-11-30T17:32:17+00:00"
}
}
(END)
- Take note of the policy ARN.
- Create the
flyte-system-role
IAM role that the backend components will use. You won't create a Kubernetes service account at this point; it will be created by running the Helm chart at the end of the process:
eksctl create iamserviceaccount --cluster=<Name-EKS-Cluster> --name=flyte-backend-flyte-binary --role-only --role-name=flyte-system-role --attach-policy-arn arn:aws:iam::<AWS-ACCOUNT>:policy/<policy-name> --approve --region <region-code> --namespace flyte
- Verify that the trust relationship between the IAM role and the OIDC provider has been created correctly:
aws iam get-role --role-name flyte-system-role --query Role.AssumeRolePolicyDocument
Example output:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWS-ACCOUNT>:oidc-provider/oidc.eks.<region-code>.amazonaws.com/id/<UUID-OIDC>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/<UUID-OIDC>:sub": "system:serviceaccount:flyte:flyte-backend-flyte-binary",
"oidc.eks.<region-code>.amazonaws.com/id/<UUID-OIDC>:aud": "sts.amazonaws.com"
}
}
}
]
}
- Create the role that the Task Pods will use to consume AWS resources:
eksctl create iamserviceaccount --cluster=<Name-EKS-Cluster> --name=default --role-only --role-name=flyte-workers-role --attach-policy-arn arn:aws:iam::<AWS-ACCOUNT>:policy/<policy-name> --approve --region <region-code> --namespace flyte
NOTE: as this role will be used by the
default
Service Account on eachproject-domain
namespace, you'll need to adjust the Role definition to make it work for any namespace:
- Go to the AWS Management Console > IAM > Roles
- Find your
flyte-workers-role
Role and go to the Trust relationships view - Click Edit Trust Policy
- You should have something like this:
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWS-ACCOUNT>:oidc-provider/oidc.eks.<AWS-REGION>.amazonaws.com/id/<UUID-OIDC>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.<AWS-REGION>.amazonaws.com/id/<UUID-OIDC>:aud": "sts.amazonaws.com",
"oidc.eks.us-east-1.amazonaws.com/id/<UUID-OIDC>:sub": "system:serviceaccount:flyte:default"
}
}
}
- You'll want to switch from the
StringEquals
condition operator toStringLike
in order to enable the use of a wildcard in the namespace position:
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWS-ACCOUNT>:oidc-provider/oidc.eks.<AWS-REGION>.amazonaws.com/id/66CBAF563FD1438BC98F1EF39FF8DACD"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.eks.<AWS-REGION>.amazonaws.com/id/66CBAF563FD1438BC98F1EF39FF8DACD:aud": "sts.amazonaws.com",
"oidc.eks.us-east-1.amazonaws.com/id/66CBAF563FD1438BC98F1EF39FF8DACD:sub": "system:serviceaccount:*:default"
}
}
- Save your changes