Skip to Content

Workload Identity Setup
Available in v1.26.11+

AWS IAM Roles for Service Accounts (IRSA) allows your ScaleOps pods to securely access AWS resources without storing IAM credentials in your cluster.

Prerequisites

  • EKS cluster with OIDC identity provider enabled
  • AWS CLI installed and configured
  • kubectl access to your EKS cluster

Step 1: Create IAM Policy

First, create the IAM policy for node integration permissions:

# Create the IAM policy aws iam create-policy \ --policy-name scaleops-node-integration-access-policy \ --policy-document '{ "Version": "2012-10-17", "Statement": [ { "Sid": "NodeIntegrationReadAccess", "Effect": "Allow", "Action": [ "athena:Get*", "athena:List*", "autoscaling:Describe*", "autoscaling:Get*", "autoscaling:UpdateAutoScalingGroup", "autoscaling:CreateAutoScalingGroup", "autoscaling:DeleteAutoScalingGroup", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup", "bedrock:Get*", "bedrock:List*", "ce:Describe*", "ce:Get*", "ce:List*", "cloudwatch:GetMetricData", "cloudwatch:GetMetricStatis", "cloudwatch:ListMetrics", "compute-optimizer:Describe*", "compute-optimizer:Get*", "dynamodb:Describe*", "dynamodb:List*", "ec2:CreateLaunchTemplate", "ec2:DeleteLaunchTemplate", "ec2:RunInstances", "ec2:Describe*", "ec2:Get*", "ec2:List*", "ecs:Describe*", "ecs:List*", "eks:Describe*", "eks:List*", "eks:UpdateNodegroupConfig", "eks:CreateNodegroup", "eks:DeleteNodegroup", "eks:TagResource", "elasticache:Describe*", "elasticache:List*", "elasticloadbalancing:Describe*", "glue:Get*", "glue:List*", "lambda:GetFunction", "lambda:GetFunctionConfiguration", "lambda:List*", "organizations:DescribeAccount", "organizations:DescribeOrganization", "rds:Describe*", "rds:List*", "s3:GetBucketLocation", "s3:GetBucketTagging", "s3:ListAllMyBuckets", "sagemaker:Describe*", "sagemaker:List*", "tag:GetResources", "tag:GetTagKeys", "tag:GetTagValues", "glue:Get*", "glue:List*" ], "Resource": "*" }, { "Sid": "SimulateIAM", "Effect": "Allow", "Action": [ "iam:SimulatePrincipalPolicy", "iam:GetRole", "iam:ListAttachedRolePolicies" ], "Resource": "*" }, { "Sid": "PassNodeRole", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "*", "Condition": { "StringEquals": { "iam:PassedToService": [ "eks.amazonaws.com", "ec2.amazonaws.com" ] } } } ] }' > /dev/null

Step 2: Create IAM Role for Each EKS Cluster

For each EKS cluster that needs node integration, create a separate IAM role with the appropriate trust policy.

# Get your EKS cluster OIDC issuer URL CLUSTER_ISSUER=$(aws eks describe-cluster --name <CLUSTER_NAME> --region <REGION> --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///") # Get your AWS account ID ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) # Create the IAM role ROLE_NAME="node-integration-workload-identity-role" aws iam create-role \ --role-name $ROLE_NAME \ --assume-role-policy-document "{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"Federated\": \"arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${CLUSTER_ISSUER}\" }, \"Action\": \"sts:AssumeRoleWithWebIdentity\", \"Condition\": { \"StringEquals\": { \"${CLUSTER_ISSUER}:sub\": [ \"system:serviceaccount:scaleops-system:scaleops-agent\", \"system:serviceaccount:scaleops-system:scaleops-dashboards\", \"system:serviceaccount:scaleops-system:scaleops-recommender\", \"system:serviceaccount:scaleops-system:scaleops-updater\" ], \"${CLUSTER_ISSUER}:aud\": \"sts.amazonaws.com\" } } } ] }" > /dev/null # Attach the policy to the role aws iam attach-role-policy \ --role-name $ROLE_NAME \ --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/scaleops-node-integration-access-policy > /dev/null

Step 3: Configure ScaleOps Helm Values

Grab the role ARN from the output of the above command.

ROLE_NAME="node-integration-workload-identity-role" aws iam get-role --role-name $ROLE_NAME --query "Role.Arn" --output text

For each cluster, configure the Helm values to use workload identity:

global: serviceAccount: annotations: eks.amazonaws.com/role-arn: "<ROLE_ARN>" cloudNodeIntegration: aws: enabled: true