Skip to main content

Overview

ArgoCD enables GitOps-based continuous delivery for MCP Server, automatically syncing Kubernetes resources from Git to multiple GKE clusters. Changes in Git trigger automated deployments with rollback capabilities.

Multi-Cluster

Manage dev, staging, prod from one ArgoCD instance

Auto-Sync

Git commits trigger automated deployments

Image Updater

Auto-update images from Artifact Registry

Workload Identity

Keyless authentication with GCP

GitOps Benefits

Git is the authoritative source for all deployments.
  • No manual kubectl apply
  • Full audit trail (Git history)
  • Easy rollback (git revert)
ArgoCD watches Git and auto-syncs to clusters.
  • Merge PR → Automatic deployment
  • Reduced manual errors
  • Consistent across environments
One ArgoCD instance manages all clusters.
  • Dev, staging, prod from single UI
  • ApplicationSets for environment parity
  • Centralized observability
ArgoCD Image Updater detects new images.
  • Monitors Artifact Registry
  • Creates PRs with new image tags
  • Semantic versioning support

Architecture

Flow:
  1. Developer pushes code → GitHub
  2. CI/CD builds image → Artifact Registry
  3. ArgoCD Image Updater detects new image
  4. Creates PR with updated image tag
  5. After PR merge, ArgoCD syncs to cluster

Quick Setup (15 minutes)

1

Run Setup Script

./deployments/argocd/setup-argocd-gcp.sh YOUR_PROJECT_ID
What it does:
  • Installs ArgoCD in argocd namespace
  • Installs ArgoCD Image Updater
  • Configures Workload Identity
  • Sets up GCP service account with registry access
2

Get ArgoCD Admin Password

kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d
Copy the password for login.
3

Access ArgoCD UI

  • Port Forward (Quick)
  • Ingress (Production)
kubectl port-forward svc/argocd-server -n argocd 8080:443
Open: https://localhost:8080Login:
  • Username: admin
  • Password: (from Step 2)
4

Add GKE Clusters

  • Using argocd CLI
  • Using Secrets (Declarative)
# Get cluster contexts
gcloud container clusters get-credentials mcp-dev-gke \
  --region us-central1 --project YOUR_PROJECT_ID
gcloud container clusters get-credentials mcp-staging-gke \
  --region us-central1 --project YOUR_PROJECT_ID
gcloud container clusters get-credentials production-mcp-server-langgraph-gke \
  --region us-central1 --project YOUR_PROJECT_ID

# Install argocd CLI
brew install argocd  # macOS
# or: curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64

# Login
argocd login localhost:8080 --username admin --password PASSWORD

# Add clusters
argocd cluster add gke_YOUR_PROJECT_ID_us-central1_mcp-dev-gke --name gcp-dev
argocd cluster add gke_YOUR_PROJECT_ID_us-central1_mcp-staging-gke --name gcp-staging
argocd cluster add gke_YOUR_PROJECT_ID_us-central1_production-mcp-server-langgraph-gke --name gcp-production
5

Deploy ApplicationSet

# Edit cluster endpoints in the file
vim deployments/argocd/gcp-multi-cluster-setup.yaml

# Apply ApplicationSet
kubectl apply -f deployments/argocd/gcp-multi-cluster-setup.yaml
Creates 3 Applications (dev, staging, prod) from one definition.
6

Verify Sync

# List applications
argocd app list

# Check sync status
argocd app get mcp-server-gcp-production

# View in UI
# https://localhost:8080
All apps should show Synced and Healthy

ApplicationSet for Multi-Environment

Configuration

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: mcp-server-gcp-environments
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - cluster: gcp-dev
            url: https://GCP_DEV_ENDPOINT
            namespace: mcp-dev
            overlay: dev-gke
            replicas: "1"

          - cluster: gcp-staging
            url: https://GCP_STAGING_ENDPOINT
            namespace: staging-mcp-server-langgraph
            overlay: staging-gke
            replicas: "2"

          - cluster: gcp-production
            url: https://GCP_PROD_ENDPOINT
            namespace: production-mcp-server-langgraph
            overlay: production-gke
            replicas: "3"

  template:
    metadata:
      name: 'mcp-server-{{cluster}}'
    spec:
      source:
        repoURL: https://github.com/vishnu2kmohan/mcp-server-langgraph
        targetRevision: main
        path: 'deployments/overlays/{{overlay}}'

      destination:
        server: '{{url}}'
        namespace: '{{namespace}}'

      syncPolicy:
        automated:
          prune: true      # Delete resources removed from Git
          selfHeal: true   # Revert manual changes

        retry:
          limit: 5
          backoff:
            duration: 5s
            maxDuration: 3m

Sync Policies


ArgoCD Image Updater

Purpose

Automatically update container image tags when new versions are pushed to Artifact Registry.

Configuration

1

Configure Registry Access

argocd-image-updater-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-image-updater-config
  namespace: argocd
data:
  registries.conf: |
    registries:
    - name: gcp-artifact-registry
      api_url: https://us-central1-docker.pkg.dev
      prefix: us-central1-docker.pkg.dev
      credentials: ext:/scripts/gcp-credentials.sh
      default: true
Workload Identity handles authentication automatically.
2

Annotate Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: mcp-server-production-gke
  namespace: argocd
  annotations:
    # Image to watch
    argocd-image-updater.argoproj.io/image-list: |
      mcp-server=us-central1-docker.pkg.dev/PROJECT_ID/mcp-production/mcp-server-langgraph

    # Update strategy: semver (respect semantic versioning)
    argocd-image-updater.argoproj.io/mcp-server.update-strategy: semver

    # Only allow stable versions (v1.2.3, not v1.2.3-beta)
    argocd-image-updater.argoproj.io/mcp-server.allow-tags: regexp:^v?[0-9]+\.[0-9]+\.[0-9]+$

    # Write changes back to Git
    argocd-image-updater.argoproj.io/write-back-method: git
    argocd-image-updater.argoproj.io/write-back-target: kustomization
3

Update Strategy Options

Workflow


Deployment Patterns

Progressive Delivery

1

1. Deploy to Dev (Automatic)

git push origin main
ArgoCD auto-syncs to dev cluster within 3 minutes.
2

2. Promote to Staging (Manual Sync)

# Option 1: argocd CLI
argocd app sync mcp-server-gcp-staging

# Option 2: UI
# Click "Sync" in ArgoCD UI for staging app
Validates in production-like environment.
3

3. Promote to Production (Approval Required)

  • Via GitHub Actions
  • Via ArgoCD Sync Waves
.github/workflows/promote-to-prod.yaml
name: Promote to Production
on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to promote'
        required: true

jobs:
  promote:
    runs-on: ubuntu-latest
    environment: production  # Requires approval
    steps:
      - uses: actions/checkout@v4

      - name: Update production overlay
        run: |
          cd deployments/overlays/production-gke
          kustomize edit set image \
            mcp-server=us-central1-docker.pkg.dev/PROJECT_ID/mcp-production/mcp-server-langgraph:${{ github.event.inputs.version }}

      - name: Commit and push
        run: |
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"
          git commit -am "Promote v${{ github.event.inputs.version }} to production"
          git push
Requires manual approval in GitHub.

Canary Deployment

Use Flagger with ArgoCD for automated canary analysis:
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: mcp-server-canary
  namespace: production-mcp-server-langgraph
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: production-mcp-server-langgraph
  progressDeadlineSeconds: 600
  service:
    port: 8000
  analysis:
    interval: 1m
    threshold: 5
    maxWeight: 50
    stepWeight: 10
    metrics:
    - name: request-success-rate
      thresholdRange:
        min: 99
      interval: 1m
    - name: request-duration
      thresholdRange:
        max: 500
      interval: 1m
Flow:
  1. ArgoCD syncs new version
  2. Flagger creates canary deployment (10% traffic)
  3. Monitors metrics for 1 minute
  4. If healthy, increases to 20%, 30%, … 100%
  5. If unhealthy, auto-rollback

Monitoring & Troubleshooting

Application Health

  • Via CLI
  • Via UI
# List all apps
argocd app list

# Get detailed status
argocd app get mcp-server-gcp-production

# View sync history
argocd app history mcp-server-gcp-production

# View logs
argocd app logs mcp-server-gcp-production

Common Issues

Symptom: Application shows “Progressing” for >10 minutesCauses:
  • Deployment rollout waiting for pods
  • Resource quota exceeded
  • Image pull errors
Solution:
# Check pod status
kubectl get pods -n production-mcp-server-langgraph

# View pod events
kubectl describe pod POD_NAME -n production-mcp-server-langgraph

# Check ArgoCD sync logs
argocd app logs mcp-server-gcp-production
Symptom: App shows “OutOfSync” with automated sync enabledCauses:
  • Manual kubectl changes (selfHeal disabled)
  • Ignored differences (e.g., replicas managed by HPA)
  • Sync failed due to error
Solution:
# Force sync
argocd app sync mcp-server-gcp-production --force

# View diff
argocd app diff mcp-server-gcp-production

# Ignore specific fields
argocd app set mcp-server-gcp-production \
  --ignore-difference group=apps,kind=Deployment,jsonPointers=/spec/replicas
Symptom: New images pushed to Artifact Registry, but no PR createdChecks:
# View Image Updater logs
kubectl logs -n argocd deployment/argocd-image-updater

# Check Workload Identity
kubectl describe sa argocd-image-updater -n argocd

# Verify GCP SA permissions
gcloud projects get-iam-policy PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:argocd-sa"
Common fix: Grant roles/artifactregistry.reader to GCP SA
Symptom: ArgoCD can’t connect to GKE clusterSolution:
# Re-add cluster
argocd cluster add CONTEXT_NAME --name gcp-production

# Update cluster secret with new endpoint/cert
kubectl edit secret gcp-production-cluster -n argocd

Security Best Practices

Enable RBAC for ArgoCD users
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    # Developers: read-only access
    p, role:developers, applications, get, */*, allow
    p, role:developers, applications, sync, dev/*, allow
    g, engineering@example.com, role:developers

    # DevOps: full access to staging/prod
    p, role:devops, applications, *, */*, allow
    p, role:devops, clusters, *, *, allow
    g, devops@example.com, role:devops
Use Workload Identity (no service account keys)
Already configured by setup script.
Enable audit logging
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  audit.log.enabled: "true"
  audit.log.maxsize: "100"  # MB
  audit.log.maxage: "30"    # days
Restrict allowed Git repos
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  repositories: |
    - url: https://github.com/vishnu2kmohan/mcp-server-langgraph
      name: mcp-server-langgraph
    # Deny all others


Next Steps

1

Install ArgoCD

./deployments/argocd/setup-argocd-gcp.sh PROJECT_ID
2

Add Clusters

argocd cluster add CONTEXT --name gcp-production
3

Deploy ApplicationSet

kubectl apply -f deployments/argocd/gcp-multi-cluster-setup.yaml
4

Configure Image Updater

Add annotations to Application for automatic image updates
5

Enable Monitoring