Most ArgoCD tutorials start the same way:
Deploy ArgoCD.
Connect a Git repository.
Create an Application.
Done.
But what happens when multiple teams start sharing the same Kubernetes cluster?
Recently I was exploring a scenario where a single Amazon EKS cluster needed to support two different ArgoCD environments:
- A Custom ArgoCD instance for the Platform Team
- A Managed ArgoCD instance for Application Teams
The Custom ArgoCD would manage infrastructure components such as:
- cert-manager
- external-dns
- monitoring
- ingress controllers
While the Managed ArgoCD would be used by application teams to deploy:
- APIs
- frontends
- microservices
- business applications
The challenge was figuring out how to keep both environments isolated while still sharing the same EKS cluster, Cognito User Pool, and AWS Application Load Balancer.
At first, I thought:
Why not just use a single ArgoCD instance?
The more I thought about it, the more questions came up.
- How do we separate responsibilities?
- How do we avoid accidental changes?
- How do we provide SSO?
- How do we keep costs under control?
That led me down an interesting path:
Can we run two ArgoCD instances inside the same EKS cluster, authenticate both using Cognito SSO, and still share the same ALB?
Turns out we can.
This article walks through the architecture, challenges, lessons learned, and a few surprises along the way.
The Scenario
Imagine you have a Kubernetes cluster used by multiple teams.
The Platform Team owns:
- cert-manager
- external-dns
- monitoring
- ingress controllers
- cluster add-ons
The Application Teams own:
- APIs
- frontends
- microservices
- business applications
A single ArgoCD instance technically works.
But should both groups operate from the same GitOps control plane?
For smaller environments, probably yes.
For larger environments, things start getting messy.
Different permissions.
Different ownership boundaries.
Different operational responsibilities.
That was the motivation behind splitting ArgoCD into two instances.
The Goal
The architecture I wanted looked like this:
EKS Cluster
├── ArgoCD (Platform Team) - Custom argocd
│ ├── cert-manager
│ ├── external-dns
│ └── monitoring
│
└── ArgoCD (Application Teams) - Managed argocd
├── frontend
├── backend
└── business applications
And on top of that:
- Single Sign-On
- Fully automated provisioning
- Infrastructure as Code
- Minimal AWS cost
The Final Architecture
The final design consisted of:
Developer
|
| HTTPS
v
Shared AWS ALB
(group.name = argocd)
|
+---------------------+
| |
v v
argocd argocd2
Namespace: Namespace:
argocd argocd-managed
Platform Team Application Teams
| |
+----------+----------+
|
v
AWS Cognito User Pool
Both ArgoCD instances run inside the same EKS cluster.
The difference is that each lives in its own namespace.
argocd
argocd-managed
This gives logical separation without requiring another cluster.
Why Cognito?
Before choosing Cognito, I looked at AWS IAM Identity Center.
Identity Center is generally the preferred enterprise solution.
However, for this learning exercise I wanted everything automated using Terraform.
My ideal deployment process was:
terraform apply
and automatically create:
- User Pool
- App Clients
- Groups
- Users
- Passwords
without opening the AWS Console.
Cognito made that surprisingly easy.
Building the Authentication Layer
The first step was creating a Cognito User Pool.
Each ArgoCD instance gets its own App Client.
Visually, it looked like this:
Cognito User Pool
├── App Client
│ └── ArgoCD Platform
│
└── App Client
└── ArgoCD Managed
Here's what it looked like in AWS.
One thing I particularly liked was eliminating manual user creation.
Terraform creates:
- User Pool
- Domain
- App Clients
- Groups
- Admin User
Everything becomes Infrastructure as Code.
No temporary passwords.
No manual console work.
No forgotten setup steps.
Connecting ArgoCD to Cognito
ArgoCD supports OIDC natively.
That means Cognito can act as the identity provider.
The authentication flow becomes:
User
|
v
ArgoCD
|
v
Cognito Hosted UI
|
v
Authentication
|
v
OIDC Callback
|
v
ArgoCD Dashboard
Once logged in, ArgoCD reads the Cognito groups from the token and maps them to ArgoCD roles.
That means administrators are controlled centrally through Cognito instead of managing users inside ArgoCD itself.
The Shared ALB Experiment
This was probably the most interesting part.
Initially I considered creating two separate Application Load Balancers.
One for each ArgoCD instance.
That would work.
But it also means:
- More AWS resources
- More management
- More cost
Then I remembered the AWS Load Balancer Controller supports Ingress Groups.
That changed everything.
Instead of:
ALB #1 → ArgoCD
ALB #2 → ArgoCD Managed
I could use:
One ALB
Two Hostnames
Two ArgoCD Instances
The ALB creates listener rules based on the hostname.
And from Kubernetes:
Both ingress resources point to the same ALB.
The routing happens automatically based on the Host header.
A nice cost optimization with very little additional complexity.
The Problem Nobody Warned Me About
The first ArgoCD deployment worked perfectly.
The second one failed immediately.
The error looked something like this:
customresourcedefinitions.apiextensions.k8s.io already exists
At first it wasn't obvious.
Then it clicked.
ArgoCD installs CRDs.
CRDs are cluster-scoped resources.
The first installation already created them.
The second installation attempted to create them again.
Kubernetes refused.
The fix was simple:
crds:
install: false
Once I disabled CRD installation for the second ArgoCD instance, everything worked.
It was one of those issues that takes a while to understand but only seconds to fix.
The Login Experience
After deployment, the user experience was exactly what I wanted.
First, users see the ArgoCD login screen.
Selecting the Cognito login option redirects users to the Hosted UI.
After successful authentication, users land directly inside ArgoCD.
No local accounts.
No shared admin credentials.
No Kubernetes secret lookups.
Just SSO.
Another Small Gotcha
While testing Applications, I ran into this error:
app path is not a directory
I had accidentally pointed ArgoCD to a YAML file instead of a directory.
ArgoCD expects:
path: manifests/
not:
path: manifests/app.yaml
A small detail, but one that can waste a surprising amount of time when you're learning.
What I Learned
The most valuable lesson wasn't about Cognito.
It wasn't about Terraform.
It wasn't even about ArgoCD.
It was about ownership.
As environments grow, separating responsibilities becomes more important than simply making things work.
Running a Custom ArgoCD for platform operations and a Managed ArgoCD for application teams gave:
- Better operational boundaries
- Cleaner RBAC
- Clear ownership between teams
- Reduced risk of accidental changes
- Independent GitOps workflows
The platform team can safely manage infrastructure applications while application teams operate in their own ArgoCD environment without interfering with cluster-level services.
And because both instances share a single ALB, the cost impact remained minimal.
Would I Do This Again?
For a small team?
Probably not.
A single ArgoCD instance is easier to manage.
For organizations with dedicated platform teams and application teams?
Absolutely.
The pattern scales nicely, provides cleaner ownership boundaries, and integrates well with SSO.
Most importantly, the entire environment can be created with a single:
terraform apply
which is exactly what I wanted from the beginning.
If you've experimented with multiple ArgoCD instances or different GitOps multi-tenancy approaches, I'd love to hear how you've solved it.
Happy GitOps 🚀
GitHub Repository
https://github.com/jayakrishnayadav24/eks-argocd-cognito-sso








Top comments (0)