Skip to content

Gitops

GitOps is an operational framework that uses Git as the single source of truth for infrastructure and application configurations. Changes are made through Git commits, and the system automatically syncs the desired state with the actual state.

┌─────────────────────────────────────────────────────────────────┐
│ GitOps Principles │
│ │
│ 1. Declarative │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ All infrastructure is declared in code │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 2. Versioned & Immutable │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Everything is versioned, no manual changes │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 3. Automated Pull │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ System pulls updates from Git automatically │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 4. Continuous Reconciliation │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ System ensures actual = desired state │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ GitOps Workflow │
│ │
│ Developer │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Git Commit (Infrastructure/Application Code) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Git Repository (Single Source of Truth) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ ArgoCD / Flux │───▶│ Cluster State │ │
│ │ (Controller) │ │ Reconciliation │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────────────┐ │
│ └────────────────▶│ Kubernetes/API │ │
│ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Terminal window
# Install ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Access UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Get admin password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/myapp.git
targetRevision: main
path: deploy/k8s
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
# Application with health checks
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
spec:
syncPolicy:
automated:
prune: true
selfHeal: true
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
resourceHooks:
- name: post-sync
hook:
template:
generate: |
apiVersion: batch/v1
kind: Job
metadata:
generateName: post-sync-
spec:
template:
spec:
containers:
- name: post-sync
image: alpine
command: ["/bin/sh", "-c"]
restartPolicy: Never
Terminal window
# Install Flux CLI
curl -s https://toolkit.fluxcd.io/install.sh | sudo bash
# Bootstrap Flux
flux bootstrap github \
--owner=myorg \
--repository=my-fleet-repo \
--path=clusters/production \
--personal
# GitRepository
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: myapp
namespace: flux-system
spec:
interval: 1m
url: https://github.com/myorg/myapp.git
ref:
branch: main
---
# HelmRepository
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: bitnami
namespace: flux-system
spec:
interval: 1h
url: https://charts.bitnami.com/bitnami
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: myapp
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: myapp
path: ./deploy
prune: true
validation: client
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: myapp
namespace: production
├── apps/
│ ├── myapp/
│ │ ├── base/
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ └── kustomization.yaml
│ │ └── overlays/
│ │ ├── development/
│ │ │ └── kustomization.yaml
│ │ └── production/
│ │ └── kustomization.yaml
├── infrastructure/
│ ├── base/
│ │ ├── namespaces.yaml
│ │ └── network-policies.yaml
│ └── clusters/
│ ├── dev-cluster/
│ └── prod-cluster/
└── README.md
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
commonLabels:
app.kubernetes.io/part-of: myapp
# overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 5
target:
kind: Deployment
# ArgoCD Application for each environment
# main branch -> production
# develop branch -> staging
# feature branches -> preview environments
# ArgoCD sync options
syncPolicy:
automated:
prune: true # Remove extraneous resources
selfHeal: true # Correct drift
allowEmpty: false
# ArgoCD Rollouts integration
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
spec:
replicas: 5
strategy:
canary:
canaryService: myapp-canary
stableService: myapp-stable
trafficRouting:
nginx:
stableIngress: myapp-ingress
steps:
- setWeight: 10
- pause: {duration: 10m}
- setWeight: 30
- pause: {duration: 10m}
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100
name: GitOps Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Update ArgoCD
uses: argoproj/argo-cd-actions@sync@v1
with:
app_name: myapp
argo_server: argocd.example.com
token: ${{ secrets.ARGO_TOKEN }}
Terminal window
# View application status
argocd app get myapp
# View application tree
argocd app tree myapp
# View sync status
argocd app sync myapp
# View resource diff
argocd app diff myapp

GitOps provides:

  • Single source of truth: Git as the source for all configurations
  • Drift detection: Automatically detect and correct drift
  • Audit trail: Complete history of changes
  • Self-healing: Automatic reconciliation
  • Faster deployments: Automated sync from Git

Key tools:

  • ArgoCD: GitOps continuous delivery for Kubernetes
  • Flux: GitOps toolkit for Kubernetes
  • Kustomize: Kubernetes native configuration management