How to set up multi-account EKS access with IAM roles and SSO
| Service | Amazon EKS |
|---|---|
| Cloud | Amazon Web Services (AWS) |
| Guide type | Procedure |
| Skill level | Intermediate to advanced |
| Time | 15 - 60 minutes depending on account size |
Engineers running Amazon EKS hit How to set up multi-account EKS access with IAM roles and SSO often enough that there is a stable fix pattern. This page captures it in the order AWS support would run it during a real incident.
What how to set up multi-account eks access with iam roles and sso actually involves on Amazon EKS
This task on EKS is one of the more searched operational topics on AWS in the last 12 months. The procedure below is the path that works in a current AWS account with default IAM and standard VPC config.
The rest of this page is the structured fix path. Start with diagnose, then remediation, then the automation options so you do not have to do this by hand the next time it surfaces. Verify and safety sections at the end are the discipline that keeps the fix from regressing in production.
Diagnose first, fix second
Reproduce the failure with the AWS CLI in --debug mode. The full SigV4 request payload it emits, plus the exact endpoint URL it resolved to, is what AWS Support uses to verify policy, region, or parameter issues without you having to share IAM credentials. Save the debug output to a file with aws ... --debug 2> debug.log and you can search it for the failed aws.request entry.
Check the AWS Health Dashboard at health.aws.amazon.com for ongoing service events in your region. About one in ten user-reported outages turn out to be region-scoped AWS service degradation already being tracked. AWS Health also exposes an API and EventBridge events, so you can wire a Lambda hook that pages on-call only when the failure correlates with an active AWS Health event in the same region and service.
Diff against last known good. The last config change you made is the cause about three quarters of the time, even when the change should not have mattered. Use AWS Config history (or your Terraform / CloudFormation drift report) to see the actual delta between the resource state when it worked and when it broke. The change you remember is often not the only change that happened.
Solution-focused remediation path
If you cannot reproduce the failure consistently, the cause is probably a race condition or a session-cache issue. Run the call with --profile set to a fresh STS session, in a different region you control, with a single concurrent request. If it works there but fails in your normal setup, the difference is the bug.
For IAM and STS issues, the timing matters. STS sessions can take up to 60 seconds to propagate after creation. The first call right after assume-role can fail with a permission error even when the policy is correct. Add a small retry with backoff before treating the first failure as definitive.
When the failure happens in production but not in dev, do not just compare the IAM policy. Compare the SCP / RCP at the OU level, the permission boundary on the role, and the resource-based policy on the target. One of those is almost always different between accounts. AWS Config conformance packs make this comparison routine.
Automate this fix so you do not do it twice
Codify the fix in Terraform or CloudFormation
When you reach for the console to fix the same issue twice, the third occurrence should be solved in IaC, not in the console. Terraform's terraform import and CloudFormation's resource importer let you adopt the existing resource into state without recreating it. Lock the corrected attribute behind a variable so the next operator does not have to rediscover the value. Add a moved {} block or CloudFormation resource refactor to keep the diff clean.
Automate the fix with Python and boto3
For anything you do more than twice, write a small Python script. The boto3 pattern below uses paginators (so it does not blow up on accounts with thousands of resources), explicit region binding, and a dry-run flag that defaults to True. Keep the script under 100 lines; if it grows beyond that, you are building a tool and should put it behind a Lambda with proper logging.
import boto3, sys
DRY_RUN = '--apply' not in sys.argv
client = boto3.client('eks', region_name='us-east-1')
paginator = client.get_paginator('describe_...')
for page in paginator.paginate(): for item in page.get('Items', []): if item.get('Status') == 'FAILED': if DRY_RUN: print(f'[dry-run] would fix {item["Id"]}') else: client.modify_...(ResourceId=item['Id']) print(f'fixed {item["Id"]}')Add a Systems Manager Automation runbook
For multi-step fixes that include a manual approval, use SSM Automation. Document the fix as a runbook with aws:approve steps where a human signs off and aws:executeAwsApi steps where the runbook calls the AWS API. Approvers are notified by SNS; the runbook execution shows up in CloudTrail with the approver's identity attached. This makes audit trails easy and stops production fixes from being one-person operations.
Common pitfalls and what to watch for
A subtle pitfall on Amazon EKS is that the AWS Console and the SDK can disagree about resource state during a configuration change. Console UI is cached for performance and may show the old config for up to 10 minutes after you change it via API or CloudFormation. Always confirm with describe-* CLI calls during a change window, not with screenshots from the Console.
The other pitfall: assuming that an automated remediation is correct because it succeeded. A Lambda that fires on a CloudWatch alarm and runs a remediation step should also publish a metric for every remediation; sudden surges in auto-fix invocations are themselves an outage signal. Otherwise you can hide a slow-burn regression behind a quiet remediation loop for weeks.
Verify the fix worked
- Reproduce the original symptom path. If it still surfaces in any account or region or IAM role, you have not fixed it.
- Watch for 24 to 48 hours. AWS metrics and policy systems can mask issues with cached health for 6 to 12 hours, especially CloudFront and Route 53.
- Run a smoke test under realistic load. Happy-path tests miss race conditions and IAM session-cache issues.
- Capture the new state in a runbook so the next person on call does not have to rediscover this. Push it to Confluence or your team wiki, not into Slack.
- If the fix involved a permission change, run IAM Access Analyzer one more time to confirm you did not open a separate hole while closing this one.
Safety, rollback, blast radius
- Test in a non-production account if your environment has Control Tower or AWS Organizations. The cost of one sandbox account is cheaper than one rollback meeting.
- Export the existing config before changing it. Most Amazon EKS resources support describe + export to JSON via CLI - capture that to source control before you start.
- Know your rollback path. Some Amazon EKS operations are one-way (region migration, account-level feature opt-in, KMS key deletion past pending window). Confirm reversibility on the AWS doc before you commit.
- Be aware of cross-service impact. IAM role changes ripple to every service trusting that role. KMS key changes break every workload depending on that key. VPC endpoint changes affect every VPC consumer of that endpoint.
- Maintenance window discipline: if the change touches DNS, certificate rotation, or anything that emits TLS handshakes, line up a window with stakeholder notification, not a heroic mid-day swap.
FAQ
aws eks describe-... first, then commit it before you change anything. A few operations are one-way (KMS key deletion past the pending window, region migration, account closure). Check the AWS doc for the specific API before you commit.aws CLI or SDK calls - those almost always still work.References
- docs.aws.amazon.com - official documentation for Amazon EKS
- AWS re:Post (formerly forums) - community Q&A with AWS-staff-verified answers
- AWS Health Dashboard at health.aws.amazon.com
- AWS Service Quotas console and AWS Well-Architected Tool
Related fixes
Related guides worth a look while you sort this one out:
- How to set up IRSA IAM Roles for Service Accounts on EKS
- DynamoDB Resource-based policies RBAC on tables multi-account access
- EFS Access Points for multi-tenant containers in ECS or EKS
- How to set up cluster-wide logging from EKS to CloudWatch
- How to set up EKS add-ons VPC CNI kube-proxy CoreDNS correctly
- How to set up GitOps on EKS with Argo CD or Flux