Skip to content

ArgoCD Advanced Features

Multi-Cluster Management

Add External Cluster

# List available contexts
kubectl config get-contexts

# Add cluster to ArgoCD
argocd cluster add <context-name>

# Add with custom name
argocd cluster add <context-name> --name production-cluster

# List registered clusters
argocd cluster list

Deploy to Multiple Clusters

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: multi-cluster-app
  namespace: argocd
spec:
  generators:
  - clusters:
      selector:
        matchLabels:
          environment: production
  template:
    metadata:
      name: '{{name}}-myapp'
    spec:
      project: default
      source:
        repoURL: https://github.com/user/repo.git
        targetRevision: HEAD
        path: k8s/
      destination:
        server: '{{server}}'
        namespace: myapp
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

RBAC (Role-Based Access Control)

Configure RBAC Policy

Edit argocd-rbac-cm ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.default: role:readonly
  policy.csv: |
    # Format: p, subject, resource, action, object, effect

    # Admin role - full access
    p, role:admin, applications, *, */*, allow
    p, role:admin, clusters, *, *, allow
    p, role:admin, repositories, *, *, allow
    p, role:admin, projects, *, *, allow

    # Developer role - can manage apps in dev project
    p, role:developer, applications, get, dev/*, allow
    p, role:developer, applications, sync, dev/*, allow
    p, role:developer, applications, create, dev/*, allow
    p, role:developer, applications, update, dev/*, allow
    p, role:developer, applications, delete, dev/*, allow

    # Viewer role - read-only access
    p, role:viewer, applications, get, */*, allow
    p, role:viewer, projects, get, *, allow

    # Assign roles to users/groups
    g, admin-group, role:admin
    g, dev-team, role:developer
    g, everyone, role:viewer

RBAC Examples

# Allow user to sync specific app
p, alice@example.com, applications, sync, default/myapp, allow

# Allow group to manage apps in project
p, role:devops, applications, *, myproject/*, allow
g, devops-team, role:devops

# Deny delete for production
p, role:developer, applications, delete, production/*, deny

SSO Integration

GitHub SSO

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  url: https://argocd.example.com
  dex.config: |
    connectors:
    - type: github
      id: github
      name: GitHub
      config:
        clientID: $GITHUB_CLIENT_ID
        clientSecret: $GITHUB_CLIENT_SECRET
        orgs:
        - name: my-organization
          teams:
          - devops
          - developers

Google SSO

dex.config: |
  connectors:
  - type: oidc
    id: google
    name: Google
    config:
      issuer: https://accounts.google.com
      clientID: $GOOGLE_CLIENT_ID
      clientSecret: $GOOGLE_CLIENT_SECRET
      hostedDomains:
      - example.com

LDAP/Active Directory

dex.config: |
  connectors:
  - type: ldap
    id: ldap
    name: LDAP
    config:
      host: ldap.example.com:636
      insecureNoSSL: false
      bindDN: cn=admin,dc=example,dc=com
      bindPW: $LDAP_PASSWORD
      userSearch:
        baseDN: ou=users,dc=example,dc=com
        filter: "(objectClass=person)"
        username: uid
        idAttr: uid
        emailAttr: mail
        nameAttr: cn
      groupSearch:
        baseDN: ou=groups,dc=example,dc=com
        filter: "(objectClass=groupOfNames)"
        userAttr: DN
        groupAttr: member
        nameAttr: cn

SAML 2.0

dex.config: |
  connectors:
  - type: saml
    id: saml
    name: SAML
    config:
      ssoURL: https://idp.example.com/sso
      caData: $IDP_CA_CERT
      redirectURI: https://argocd.example.com/api/dex/callback
      usernameAttr: email
      emailAttr: email
      groupsAttr: groups

Projects

Create Project

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: production
  namespace: argocd
spec:
  description: Production applications

  # Source repositories
  sourceRepos:
  - https://github.com/org/prod-apps.git
  - https://github.com/org/helm-charts.git

  # Destination clusters and namespaces
  destinations:
  - namespace: production
    server: https://kubernetes.default.svc
  - namespace: prod-*
    server: https://prod-cluster.example.com

  # Allowed cluster resources
  clusterResourceWhitelist:
  - group: ''
    kind: Namespace
  - group: 'rbac.authorization.k8s.io'
    kind: ClusterRole

  # Denied namespaced resources
  namespaceResourceBlacklist:
  - group: ''
    kind: ResourceQuota

  # Roles
  roles:
  - name: developer
    description: Developers
    policies:
    - p, proj:production:developer, applications, get, production/*, allow
    - p, proj:production:developer, applications, sync, production/*, allow
    groups:
    - dev-team

  - name: admin
    description: Admins
    policies:
    - p, proj:production:admin, applications, *, production/*, allow
    groups:
    - admin-team

Notifications

Install Notifications Controller

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/stable/manifests/install.yaml

Configure Slack Notifications

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  service.slack: |
    token: $slack-token

  template.app-deployed: |
    message: |
      Application {{.app.metadata.name}} is now running new version.
    slack:
      attachments: |
        [{
          "title": "{{ .app.metadata.name}}",
          "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "color": "#18be52",
          "fields": [
          {
            "title": "Sync Status",
            "value": "{{.app.status.sync.status}}",
            "short": true
          },
          {
            "title": "Repository",
            "value": "{{.app.spec.source.repoURL}}",
            "short": true
          }
          ]
        }]

  template.app-health-degraded: |
    message: |
      Application {{.app.metadata.name}} has degraded.
    slack:
      attachments: |
        [{
          "title": "{{ .app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "color": "#f4c030",
          "fields": [
          {
            "title": "Health Status",
            "value": "{{.app.status.health.status}}",
            "short": true
          }
          ]
        }]

  trigger.on-deployed: |
    - when: app.status.operationState.phase in ['Succeeded']
      send: [app-deployed]

  trigger.on-health-degraded: |
    - when: app.status.health.status == 'Degraded'
      send: [app-health-degraded]

Subscribe Application to Notifications

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  annotations:
    notifications.argoproj.io/subscribe.on-deployed.slack: my-channel
    notifications.argoproj.io/subscribe.on-health-degraded.slack: alerts-channel
spec:
  # ... application spec

Image Updater

Install Image Updater

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml

Configure Image Updater

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-image-updater-config
  namespace: argocd
data:
  registries.conf: |
    registries:
    - name: Docker Hub
      api_url: https://registry-1.docker.io
      prefix: docker.io
      credentials: secret:argocd/dockerhub-secret

    - name: GCR
      api_url: https://gcr.io
      prefix: gcr.io
      credentials: pullsecret:kube-system/gcr-secret

Enable Auto-Update for Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  annotations:
    argocd-image-updater.argoproj.io/image-list: myimage=myapp
    argocd-image-updater.argoproj.io/myimage.update-strategy: latest
    argocd-image-updater.argoproj.io/myimage.allow-tags: regexp:^v[0-9]+\.[0-9]+\.[0-9]+$
    argocd-image-updater.argoproj.io/write-back-method: git
spec:
  # ... application spec

Progressive Delivery with Rollouts

Install Argo Rollouts

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

Canary Deployment

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: myapp
spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {duration: 1m}
      - setWeight: 40
      - pause: {duration: 1m}
      - setWeight: 60
      - pause: {duration: 1m}
      - setWeight: 80
      - pause: {duration: 1m}
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2.0.0

Blue-Green Deployment

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: myapp
spec:
  replicas: 3
  strategy:
    blueGreen:
      activeService: myapp-active
      previewService: myapp-preview
      autoPromotionEnabled: false
      scaleDownDelaySeconds: 30
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2.0.0

Secrets Management

Sealed Secrets Integration

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: sealed-secrets
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/user/repo.git
    targetRevision: HEAD
    path: sealed-secrets/
  destination:
    server: https://kubernetes.default.svc
    namespace: kube-system

External Secrets Operator

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-secrets
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: SecretStore
  target:
    name: app-secrets
  data:
  - secretKey: database-password
    remoteRef:
      key: prod/database
      property: password

Vault Integration

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  repository.credentials: |
    - url: https://github.com/org
      passwordSecret:
        name: github-secret
        key: password
      usernameSecret:
        name: github-secret
        key: username

Monitoring and Observability

Prometheus Metrics

apiVersion: v1
kind: Service
metadata:
  name: argocd-metrics
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-metrics
spec:
  ports:
  - name: metrics
    port: 8082
    protocol: TCP
    targetPort: 8082
  selector:
    app.kubernetes.io/name: argocd-server

ServiceMonitor for Prometheus Operator

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: argocd-metrics
  namespace: argocd
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: argocd-metrics
  endpoints:
  - port: metrics
    interval: 30s

Grafana Dashboard

Import dashboard ID: 14584 (ArgoCD Overview)

Key metrics: - Application sync status - Sync duration - Repository fetch time - Controller queue size - API server requests

Disaster Recovery

Backup Strategy

# Backup ArgoCD applications
kubectl get applications -n argocd -o yaml > argocd-apps-backup.yaml

# Backup ArgoCD projects
kubectl get appprojects -n argocd -o yaml > argocd-projects-backup.yaml

# Backup ArgoCD settings
kubectl get configmaps -n argocd -o yaml > argocd-config-backup.yaml
kubectl get secrets -n argocd -o yaml > argocd-secrets-backup.yaml

# Backup to Git (recommended)
git add .
git commit -m "Backup ArgoCD configuration"
git push

Restore from Backup

# Restore applications
kubectl apply -f argocd-apps-backup.yaml

# Restore projects
kubectl apply -f argocd-projects-backup.yaml

# Restore configuration
kubectl apply -f argocd-config-backup.yaml
kubectl apply -f argocd-secrets-backup.yaml

Performance Tuning

Increase Controller Replicas

apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-application-controller
  namespace: argocd
spec:
  replicas: 3

Adjust Resource Limits

spec:
  template:
    spec:
      containers:
      - name: argocd-application-controller
        resources:
          requests:
            cpu: 1000m
            memory: 2Gi
          limits:
            cpu: 2000m
            memory: 4Gi

Enable Sharding

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
  namespace: argocd
data:
  application.controller.sharding.enabled: "true"
  application.controller.sharding.replicas: "3"

Best Practices

✅ Use Projects: Organize and restrict applications ✅ Implement RBAC: Fine-grained access control ✅ Enable SSO: Centralized authentication ✅ Set Up Notifications: Stay informed of changes ✅ Use Image Updater: Automate image updates ✅ Monitor Metrics: Track performance and health ✅ Regular Backups: Backup configurations to Git ✅ Multi-Cluster: Separate dev/staging/prod clusters ✅ Use Rollouts: Progressive delivery strategies ✅ Secrets Management: External secrets operators

Troubleshooting

Application Stuck in Progressing

# Check application status
argocd app get myapp

# Check sync operation
argocd app get myapp --show-operation

# Terminate stuck operation
argocd app terminate-op myapp

Sync Fails

# View sync errors
argocd app get myapp

# View detailed diff
argocd app diff myapp

# Force sync
argocd app sync myapp --force

Performance Issues

# Check controller logs
kubectl logs -n argocd deployment/argocd-application-controller

# Check metrics
kubectl top pods -n argocd

# Increase resources
kubectl edit deployment argocd-application-controller -n argocd

Next Steps

Continue to: - ArgoCD-Examples.md - Real-world examples and patterns