DEV Community

What If You Need Two ArgoCD Instances in One EKS Cluster?

Cover Image

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
Enter fullscreen mode Exit fullscreen mode

And on top of that:

  • Single Sign-On
  • Fully automated provisioning
  • Infrastructure as Code
  • Minimal AWS cost

The Final Architecture

Architecture Diagram

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
Enter fullscreen mode Exit fullscreen mode

Both ArgoCD instances run inside the same EKS cluster.

The difference is that each lives in its own namespace.

argocd
argocd-managed
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Here's what it looked like in AWS.

Cognito User Pool showing app clients and ArgoCDAdmins group

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

I could use:

One ALB
Two Hostnames
Two ArgoCD Instances
Enter fullscreen mode Exit fullscreen mode

The ALB creates listener rules based on the hostname.

ALB listener rules showing host-based routing for both ArgoCD instances

And from Kubernetes:

kubectl get ingress showing both ingresses sharing the same ALB address

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

ArgoCD login page with Log in via Cognito button

Selecting the Cognito login option redirects users to the Hosted UI.

Cognito Hosted UI login form after redirect

After successful authentication, users land directly inside ArgoCD.

ArgoCD dashboard after successful SSO login showing admin user

ArgoCD dashboard after successful SSO login showing admin user

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
Enter fullscreen mode Exit fullscreen mode

I had accidentally pointed ArgoCD to a YAML file instead of a directory.

ArgoCD expects:

path: manifests/
Enter fullscreen mode Exit fullscreen mode

not:

path: manifests/app.yaml
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)