Skip to content

ashiq-ali/argocd-gitops-platform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

argocd-gitops-platform

Production-ready GitOps bootstrap using the ArgoCD App of Apps pattern. One command installs ArgoCD; from that point the cluster is fully GitOps-driven — every tool, every environment, every config change flows through Git.

License: MIT ArgoCD Kubernetes Helm


Architecture

Architecture Diagram

📐 Edit in Excalidraw — open the .excalidraw file at excalidraw.com to edit interactively.

  Git Repository
  ├── bootstrap/        ──► ArgoCD (root Application)
  │   └── root-app.yaml       │
  ├── platform/               │  manages
  │   ├── argocd/      ◄──────┤
  │   ├── cert-manager/ ◄─────┤  App of Apps
  │   └── ingress-nginx/ ◄────┘
  └── apps/
      ├── dev/          ──► dev cluster namespace
      ├── staging/      ──► staging cluster namespace
      └── prod/         ──► prod cluster namespace

  ArgoCD ──► Sync ──► Kubernetes API ──► Deployed Resources
         └──► Notifications ──► Slack / Email

Table of Contents


The App of Apps Pattern

Standard ArgoCD installations require someone to manually create each Application object. The App of Apps pattern solves this: you create one root Application that points to a directory of other Application manifests. ArgoCD then self-manages itself and every tool from Git.

kubectl apply -f bootstrap/root-app.yaml
# → ArgoCD syncs root-app.yaml
# → root-app discovers platform/ directory
# → platform apps deploy: ArgoCD itself, cert-manager, ingress-nginx
# → apps/ ApplicationSets create per-environment Applications
# Everything else is automated

This means:

  • New cluster? kubectl apply -f bootstrap/root-app.yaml and walk away
  • New environment? Add a directory under apps/ and push
  • New platform tool? Add an Application under platform/ and push

Repository Structure

argocd-gitops-platform/
├── bootstrap/
│   └── root-app.yaml              # The single apply that starts everything
├── platform/                      # Platform-level Applications
│   ├── argocd/
│   │   ├── application.yaml       # ArgoCD self-manages via GitOps
│   │   └── values.yaml            # ArgoCD Helm values (RBAC, ingress, etc.)
│   ├── cert-manager/
│   │   ├── application.yaml
│   │   └── values.yaml
│   └── ingress-nginx/
│       ├── application.yaml
│       └── values.yaml
├── apps/
│   ├── dev/
│   │   └── applicationset.yaml    # ApplicationSet generating dev Applications
│   ├── staging/
│   │   └── applicationset.yaml
│   └── prod/
│       └── applicationset.yaml
├── workloads/                     # Application Helm chart definitions
│   └── <app-name>/
│       ├── Chart.yaml
│       └── values/
│           ├── dev.yaml
│           ├── staging.yaml
│           └── prod.yaml
├── notifications/
│   └── slack-config.yaml          # Slack notification templates
├── rbac/
│   └── policy.csv                 # ArgoCD RBAC policy (multi-tenant)
└── scripts/
    └── bootstrap.sh               # Idempotent one-command cluster bootstrap

Prerequisites

Tool Version Install
kubectl ≥ 1.28 brew install kubectl
helm ≥ 3.12 brew install helm
argocd CLI ≥ 2.9 brew install argocd
A running K8s cluster GKE / EKS / kind / k3s

Bootstrap

# 1. Clone
git clone https://github.com/ashiq-ali/argocd-gitops-platform
cd argocd-gitops-platform

# 2. Fork this repo and update the repoURL in bootstrap/root-app.yaml
#    Change: repoURL: https://github.com/ashiq-ali/argocd-gitops-platform
#    To:     repoURL: https://github.com/<YOUR_ORG>/argocd-gitops-platform

# 3. Install ArgoCD (only needed the first time)
kubectl create namespace argocd
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd \
  --namespace argocd \
  --version 6.7.3 \
  --wait

# 4. Apply the root Application — this is the ONLY manual step
kubectl apply -f bootstrap/root-app.yaml

# 5. Wait for everything to sync
kubectl -n argocd get applications -w

# 6. Get the initial admin password
argocd admin initial-password -n argocd

# 7. Access the UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Open https://localhost:8080

Or use the idempotent bootstrap script:

./scripts/bootstrap.sh \
  --repo-url https://github.com/YOUR_ORG/argocd-gitops-platform \
  --cluster-name production

Platform Tools

Three platform tools are managed via GitOps from day 1:

ArgoCD (self-managed)

ArgoCD manages itself via platform/argocd/application.yaml. Upgrades happen through Git:

# Upgrade ArgoCD: edit the targetRevision in platform/argocd/values.yaml
git commit -m "chore: upgrade argocd to 2.11.0"
git push
# ArgoCD detects the change and self-upgrades

cert-manager

Automatically provisions TLS certificates from Let's Encrypt for all Ingress resources annotated with:

annotations:
  cert-manager.io/cluster-issuer: letsencrypt-prod

ingress-nginx

Handles external HTTP/HTTPS traffic. After bootstrap, create Ingress resources normally — they'll get a real IP/hostname from the cloud load balancer.


Multi-Environment Applications

Each environment uses an ApplicationSet to generate Applications from a directory structure:

# apps/dev/applicationset.yaml
spec:
  generators:
    - git:
        repoURL: https://github.com/YOUR_ORG/argocd-gitops-platform
        revision: main
        directories:
          - path: workloads/*
  template:
    spec:
      destination:
        namespace: '{{path.basename}}-dev'
      helm:
        valueFiles:
          - values/dev.yaml

To add a new application to all environments:

mkdir -p workloads/my-new-app/values
cat > workloads/my-new-app/Chart.yaml << EOF
apiVersion: v2
name: my-new-app
version: 0.1.0
dependencies:
  - name: my-new-app
    version: "1.0.0"
    repository: "https://charts.myorg.io"
EOF

cat > workloads/my-new-app/values/dev.yaml << EOF
my-new-app:
  replicaCount: 1
  image.tag: dev-latest
EOF

git add workloads/my-new-app
git commit -m "feat: add my-new-app to all environments"
git push
# ArgoCD picks it up within 3 minutes (default poll interval)

ApplicationSets

ApplicationSets automate Application creation across environments. This repo uses the Git Directory generator which creates one Application per subdirectory:

workloads/
├── api-service/      → Application: api-service-dev, api-service-staging, api-service-prod
├── worker/           → Application: worker-dev, worker-staging, worker-prod
└── frontend/         → Application: frontend-dev, frontend-staging, frontend-prod

Each ApplicationSet also sets automated sync and self-heal so drift is corrected automatically:

syncPolicy:
  automated:
    prune: true      # Remove resources deleted from Git
    selfHeal: true   # Revert manual kubectl changes

RBAC

Multi-tenant RBAC is defined in rbac/policy.csv:

# Platform team — admin on everything
p, role:platform-admin, applications, *, */*, allow
p, role:platform-admin, clusters, *, *, allow

# Dev team — read-only on prod, full on dev/staging
p, role:dev-team, applications, get, */*, allow
p, role:dev-team, applications, *, *-dev/*, allow
p, role:dev-team, applications, *, *-staging/*, allow

# Read-only (auditors)
p, role:read-only, applications, get, */*, allow
p, role:read-only, logs, get, */*, allow

# Group mappings (SSO via Okta/Google)
g, platform-team@company.com, role:platform-admin
g, dev-team@company.com, role:dev-team

Slack Notifications

Configure Slack alerts for sync events, health changes, and deployment completions:

# 1. Create a Slack webhook secret
kubectl create secret generic argocd-notifications-secret \
  -n argocd \
  --from-literal=slack-token=xoxb-YOUR-SLACK-BOT-TOKEN

# 2. Annotate Applications for notifications
kubectl annotate application my-app \
  notifications.argoproj.io/subscribe.on-sync-succeeded.slack=deployments-channel \
  notifications.argoproj.io/subscribe.on-health-degraded.slack=alerts-channel

Notification templates in notifications/slack-config.yaml include deployment summaries with app name, sync revision, and diff link.


Promoting Across Environments

The recommended promotion flow — no branch-per-environment:

# 1. Deploy to dev (automatic on merge to main)
git merge feature/my-change
git push origin main

# 2. Validate in dev, then promote to staging
# Edit workloads/my-app/values/staging.yaml
git commit -m "chore: promote my-app v1.2.3 to staging"
git push

# 3. After staging sign-off, promote to prod
# Edit workloads/my-app/values/prod.yaml
git commit -m "chore: promote my-app v1.2.3 to prod"
git push
# ArgoCD syncs within 3 minutes; Slack notification confirms

For urgent prod rollbacks:

# Revert the last commit
git revert HEAD
git push
# ArgoCD self-heals within seconds

Disaster Recovery

Full cluster recovery from scratch:

# New cluster, same Git repo
kubectl create namespace argocd
helm install argocd argo/argo-cd --namespace argocd --wait
kubectl apply -f bootstrap/root-app.yaml
# All platform tools and applications restore from Git automatically
# Recovery time: ~10 minutes for platform tools, then app pods come up

The only state outside Git is:

  • TLS certificates (cert-manager re-issues automatically)
  • Application secrets (restore from your secrets manager — External Secrets Operator recommended)

Troubleshooting

Application stuck in OutOfSync forever

argocd app diff my-app          # See what's different
argocd app sync my-app --force  # Force sync
# If still stuck, check for Helm rendering errors:
argocd app manifests my-app

ComparisonError: failed to load target state

Usually a Helm chart values error. Check:

argocd app logs my-app
helm template workloads/my-app --values workloads/my-app/values/dev.yaml

Notifications not arriving

kubectl logs -n argocd deployment/argocd-notifications-controller | grep -i slack
# Verify the token in the secret is valid

ArgoCD UI unreachable after upgrade

ArgoCD self-upgrade can briefly disrupt the UI. Wait 2 minutes and refresh. If still down:

kubectl rollout restart deployment/argocd-server -n argocd

Built to demonstrate production GitOps workflows from hands-on ArgoCD experience at Virgin Media O2.

About

Production-ready GitOps bootstrap using ArgoCD App of Apps pattern | Multi-environment | Slack notifications | RBAC

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages