DevOps Peach

GitOps with Argo CD · Argo CD at Scale · Lesson 3 of 4

Multiple clusters and AppProjects

One Argo CD can deploy to many clusters registered as Secrets; AppProjects set the guard rails — which repos, clusters, namespaces and resource kinds a team may use.

Practice interactively →

Register clusters

Argo CD always knows its own cluster as https://kubernetes.default.svc (name in-cluster). To add another one:

kubectl config get-contexts
argocd cluster add prod-sg-admin --name prod-sg --label env=prod
argocd cluster list

argocd cluster add uses your kubeconfig context once to create a ServiceAccount argocd-manager with a ClusterRole in the target cluster, then stores its token in a Secret in the argocd namespace labelled argocd.argoproj.io/secret-type: cluster. From then on Argo CD talks to that API server directly.

Topology Pros Cons
Hub and spoke – one Argo CD manages many clusters One UI, one place for RBAC and ApplicationSets The hub needs network access and credentials to every cluster; a single point of failure
One Argo CD per cluster Isolation, no inbound access needed More installs to upgrade and secure

For production clusters, prefer short-lived credentials where your platform supports them (for example IAM roles for EKS or workload identity), and grant argocd-manager less than cluster-admin if teams only deploy into some namespaces.

AppProjects: guard rails

Every Application belongs to an AppProject. The default project allows everything — fine for a lab, not for a shared platform.

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: shop
  namespace: argocd
spec:
  description: Shop team
  sourceRepos:
    - https://github.com/example-org/shop-config.git
  destinations:
    - { server: https://kubernetes.default.svc, namespace: 'shop-*' }
    - { name: prod-sg,                          namespace: 'shop-prod' }
  clusterResourceWhitelist: []            # no cluster-scoped objects (no ClusterRoles, no CRDs)
  namespaceResourceBlacklist:
    - { group: '', kind: ResourceQuota }
  roles:
    - name: ci-sync
      policies:
        - p, proj:shop:ci-sync, applications, sync, shop/*, allow
  syncWindows:
    - { kind: deny, schedule: '0 17 * * 5', duration: 63h, applications: ['*-prod'] }
Field Limits
sourceRepos Which repositories apps may use
destinations Which cluster + namespace pairs (wildcards allowed)
clusterResourceWhitelist Which cluster-scoped kinds may be created (empty = none)
namespaceResource(Black/White)list Which namespaced kinds are allowed
roles Project-scoped roles and tokens, for example for CI
syncWindows When syncs are allowed or denied

An Application that breaks a rule shows a condition such as "application destination is not permitted in project shop" and does not sync.

argocd proj create shop -d https://kubernetes.default.svc,shop-dev -s https://github.com/example-org/shop-config.git
argocd proj get shop
argocd proj role create-token shop ci-sync      # token for the CI pipeline

Pattern: one AppProject per team, team members get RBAC only on their project (module 4), and the platform team owns default.

Practice interactively →