GitOps Workflows with ArgoCD

Comprehensive guide for implementing GitOps workflows using ArgoCD

GitOps Workflows with ArgoCD

This guide covers implementing GitOps workflows using ArgoCD, including repository structure, CI/CD integration, and best practices.

Architecture Overview

GitOps Workflow with ArgoCD

The architecture diagram above shows:

  • Development: Backend (Python), Frontend (React), and Services (Spring Boot)
  • Version Control: Application and Configuration repositories in GitHub
  • Continuous Integration: Jenkins for building and testing applications
  • GitOps Engine: ArgoCD with its core components (Repo Server, App Controller, API Server, Dex SSO)
  • Kubernetes Production: Control plane, workloads (Deployments, StatefulSets, Pods), networking, and storage
  • Monitoring & Observability: Prometheus, Grafana, and CloudWatch integration

The workflow follows these steps:

  1. Developers commit code to the Application Repository
  2. Jenkins builds, tests, and creates container images
  3. Updated manifests are committed to the Config Repository
  4. ArgoCD detects changes and synchronizes the cluster state
  5. Applications are deployed to Kubernetes with proper networking and storage
  6. Monitoring tools collect metrics and logs for observability

Video Tutorial

Learn more about GitOps workflows with ArgoCD in this comprehensive video tutorial:

View Source Code

GitOps Repository Structure

1. Monorepo Structure

.
├── apps/
│   ├── app1/
│   │   ├── base/
│   │   │   ├── deployment.yaml
│   │   │   ├── service.yaml
│   │   │   └── kustomization.yaml
│   │   └── overlays/
│   │       ├── dev/
│   │       ├── staging/
│   │       └── prod/
│   └── app2/
│       ├── base/
│       └── overlays/
├── infrastructure/
│   ├── monitoring/
│   ├── logging/
│   └── security/
└── platform/
    ├── namespaces/
    ├── rbac/
    └── quotas/

2. Multi-repo Structure

app-repo/
├── src/
├── tests/
└── kubernetes/
    ├── base/
    └── overlays/

config-repo/
├── apps/
├── infrastructure/
└── platform/

CI/CD Integration

1. GitHub Actions Integration

name: CI
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Build and Test
      run: |
        make test
        make build
        
    - name: Update Kubernetes manifests
      run: |
        cd kubernetes/overlays/dev
        kustomize edit set image app=${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
        
    - name: Commit changes
      run: |
        git config --local user.email "action@github.com"
        git config --local user.name "GitHub Action"
        git commit -am "Update image tag to ${{ github.sha }}"
        git push

2. GitLab CI Integration

stages:
  - test
  - build
  - deploy

test:
  stage: test
  script:
    - make test

build:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

deploy:
  stage: deploy
  script:
    - cd kubernetes/overlays/dev
    - kustomize edit set image app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - git commit -am "Update image tag"
    - git push origin main

Environment Management

1. Application Sets

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: env-apps
spec:
  generators:
  - matrix:
      generators:
      - list:
          elements:
          - env: dev
          - env: staging
          - env: prod
      - git:
          repoURL: https://github.com/org/apps.git
          revision: HEAD
          directories:
          - path: apps/*
  template:
    metadata:
      name: '{{path.basename}}-{{env}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/org/apps.git
        targetRevision: HEAD
        path: '{{path}}/overlays/{{env}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}-{{env}}'

2. Environment-specific Configurations

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: dev-
namespace: dev
patchesStrategicMerge:
- deployment-patch.yaml
configMapGenerator:
- name: app-config
  files:
  - config.yaml

Promotion Workflows

1. Manual Promotion

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: promotion-app
spec:
  source:
    repoURL: https://github.com/org/app.git
    targetRevision: v1.0.0
    path: kubernetes/overlays/staging
  destination:
    server: https://kubernetes.default.svc
    namespace: staging
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

2. Automated Promotion

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: promotion-apps
spec:
  generators:
  - git:
      repoURL: https://github.com/org/app.git
      revision: HEAD
      directories:
      - path: releases/*
  template:
    metadata:
      name: '{{path.basename}}'
    spec:
      source:
        repoURL: https://github.com/org/app.git
        targetRevision: HEAD
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'

Pull Request Workflows

1. Preview Environments

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: pr-{{number}}-preview
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/org/app.git
    targetRevision: refs/pull/{{number}}/head
    path: kubernetes/overlays/preview
  destination:
    server: https://kubernetes.default.svc
    namespace: pr-{{number}}

2. Automated Testing

apiVersion: batch/v1
kind: Job
metadata:
  name: pr-test
  annotations:
    argocd.argoproj.io/hook: Sync
spec:
  template:
    spec:
      containers:
      - name: test
        image: test-runner:latest
        command: ["./run-tests.sh"]
      restartPolicy: Never

Drift Detection and Reconciliation

1. Drift Detection

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  resource.compareoptions: |
    ignoreAggregatedRoles: true
    ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
      - /spec/replicas

2. Auto-healing Configuration

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: self-healing-app
spec:
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

Version Control Strategies

1. Git Tags

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: versioned-app
spec:
  source:
    repoURL: https://github.com/org/app.git
    targetRevision: v1.0.0
    path: kubernetes

2. Release Branches

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: release-apps
spec:
  generators:
  - git:
      repoURL: https://github.com/org/app.git
      revision: HEAD
      branches:
      - release-*
  template:
    metadata:
      name: '{{branch}}-app'
    spec:
      source:
        repoURL: https://github.com/org/app.git
        targetRevision: '{{branch}}'
        path: kubernetes

Best Practices Checklist

  1. Use declarative configurations
  2. Implement environment parity
  3. Automate promotions
  4. Enable drift detection
  5. Configure auto-healing
  6. Implement PR workflows
  7. Version control strategy
  8. Security controls
  9. Monitoring
  10. Documentation

Security Considerations

1. Repository Security

apiVersion: v1
kind: Secret
metadata:
  name: repo-creds
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/org/app.git
  password: <token>
  username: git

2. RBAC Controls

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    p, role:developer, applications, sync, */*, allow
    p, role:developer, applications, get, */*, allow
    g, org:developers, role:developer

Conclusion

Implementing GitOps workflows with ArgoCD provides a robust and secure way to manage Kubernetes deployments. Regular reviews and updates of workflows ensure optimal operation.

Additional Resources