TL;DR
Learn how to implement GitOps practices for infrastructure management, continuous deployment, and automated operations using tools like ArgoCD and Flux
import { MermaidDiagram } from '@/components/mermaid-diagram'
Learn how to implement GitOps practices for infrastructure management, continuous deployment, and automated operations. This comprehensive guide covers principles, tools, and best practices.
graph TB
subgraph "Source Control"
Git["Git Repository"]
PR["Pull Request"]
Review["Code Review"]
end
subgraph "CI Pipeline"
Build["Build"]
Test["Test"]
Image["Image Build"]
end
subgraph "CD Pipeline"
ArgoCD["ArgoCD"]
Sync["Sync"]
Deploy["Deploy"]
end
Git --> PR
PR --> Review
Review --> Build
Build --> Test
Test --> Image
Image --> ArgoCD
ArgoCD --> Sync
Sync --> Deploy
style Git fill:#3b82f6,stroke:#2563eb,color:white
style PR fill:#3b82f6,stroke:#2563eb,color:white
style Review fill:#3b82f6,stroke:#2563eb,color:white
style Build fill:#f1f5f9,stroke:#64748b
style Test fill:#f1f5f9,stroke:#64748b
style Image fill:#f1f5f9,stroke:#64748b
style ArgoCD fill:#f1f5f9,stroke:#64748b
style Sync fill:#f1f5f9,stroke:#64748b
style Deploy fill:#f1f5f9,stroke:#64748b
/>
}
$1
GitOps principles include:
1. Declarative Configuration: Infrastructure as code
2. Version Control: Single source of truth
3. Automated Sync: Continuous reconciliation
4. Drift Detection: Automatic correction
5. Audit Trail: Complete history
$1
$1
Install and configure ArgoCD:
`` apiVersion: v1
kind: Namespace
metadata:
name: argocd
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: argocd
namespace: argocd
spec:
repo: https://argoproj.github.io/argo-helm
chart: argo-cd
version: 5.51.6
targetNamespace: argocd
valuesContent: |-
server:
extraArgs:
- --insecure
config:
repositories: |
- type: git
url: https://github.com/your-org/your-repo.git
username: git
password: configManagementPlugins: |
- name: kustomize
init:
command: ["/bin/sh", "-c"]
args: ["kustomize version"]
generate:
command: ["/bin/sh", "-c"]
args: ["kustomize build"]
redis:
enabled: true
dex:
enabled: true
repoServer:
serviceAccount:
create: true
name: argocd-repo-server
controller:
serviceAccount:
create: true
name: argocd-application-controller
applicationSet:
enabled: true
yaml
`argocd-install.yaml
$1
Define application using Kustomize:
` apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- configmap.yaml
- secret.yaml namePrefix: myapp-
nameSuffix: -prod commonLabels:
app: myapp
environment: production commonAnnotations:
maintainer: devops-team
contact: devops@example.com configMapGenerator:
- name: app-config
files:
- config/app.properties
literals:
- API_URL=https://api.example.com
- ENVIRONMENT=production secretGenerator:
- name: app-secrets
files:
- secrets/api-key.txt
literals:
- DB_PASSWORD=ENC[AES256_GCM,data:xxx,tag:yyy] images:
- name: myapp
newName: registry.example.com/myapp
newTag: v1.2.3 patches:
- path: patches/increase-replica-count.yaml
target:
kind: Deployment
name: myapp replacements:
- source:
kind: ConfigMap
name: app-config
fieldPath: data.API_URL
targets:
- select:
kind: Deployment
name: myapp
fieldPaths:
- spec.template.spec.containers.[name=myapp].env.[name=API_URL].value configurations:
- kustomizeconfig.yaml
yaml
`kustomization.yaml
$1
Define ArgoCD application:
` apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/your-repo.git
targetRevision: HEAD
path: k8s/overlays/production
kustomize:
images:
- registry.example.com/myapp:v1.2.3
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true
- ApplyOutOfSyncOnly=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
revisionHistoryLimit: 10
yaml
`application.yaml
$1
Configure GitHub Actions workflow:
` name: CI Pipeline on:
push:
branches: [ main ]
pull_request:
branches: [ main ] env:
REGISTRY: registry.example.com
IMAGE_NAME: myapp
KUSTOMIZE_VERSION: 5.1.1 jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Run linting
run: npm run lint
- name: Build application
run: npm run build
security-scan:
needs: build-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run SAST scan
uses: github/codeql-action/analyze@v2
- name: Run dependency scan
run: |
npm audit
trivy fs .
build-image:
needs: security-scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
update-manifests:
needs: build-image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Kustomize
run: |
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
- name: Update image tag
run: |
cd k8s/overlays/production
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
- name: Commit and push changes
run: |
git config --global user.name 'GitHub Actions'
git config --global user.email 'actions@github.com'
git add k8s/overlays/production/kustomization.yaml
git commit -m "Update image tag to ${{ github.sha }}"
git push
yaml
`.github/workflows/ci.yaml
graph TB
subgraph "Git Repository"
Code["Application Code"]
K8s["K8s Manifests"]
CI["CI Pipeline"]
end
subgraph "Container Registry"
Build["Image Build"]
Push["Image Push"]
Tag["Image Tag"]
end
subgraph "Kubernetes"
ArgoCD["ArgoCD"]
Watch["Watch Changes"]
Apply["Apply Changes"]
end
Code --> CI
CI --> Build
Build --> Push
Push --> Tag
K8s --> ArgoCD
ArgoCD --> Watch
Watch --> Apply
style Code fill:#3b82f6,stroke:#2563eb,color:white
style K8s fill:#3b82f6,stroke:#2563eb,color:white
style CI fill:#3b82f6,stroke:#2563eb,color:white
style Build fill:#f1f5f9,stroke:#64748b
style Push fill:#f1f5f9,stroke:#64748b
style Tag fill:#f1f5f9,stroke:#64748b
style ArgoCD fill:#f1f5f9,stroke:#64748b
style Watch fill:#f1f5f9,stroke:#64748b
style Apply fill:#f1f5f9,stroke:#64748b
`}
/>
$1
$1
$1
$1
$1
$1
Effective GitOps implementation requires:
1. Clear processes
2. Automation
3. Security controls
4. Monitoring
5. Documentation
Remember to:
$1
1. [ArgoCD Documentation](https://argo-cd.readthedocs.io/)
2. [Flux Documentation](https://fluxcd.io/docs/)
3. [GitOps Principles](https://www.weave.works/technologies/gitops/)
4. [Kubernetes Best Practices](https://kubernetes.io/docs/concepts/configuration/overview/)
5. [Container Security](https://docs.docker.com/develop/security-best-practices/)
Why This Matters
Understanding the business and technical context helps you make informed decisions rather than blindly following patterns.
Trade-offs to Consider
Every architectural decision involves trade-offs. Consider your specific requirements, team expertise, and scale when evaluating options.
When NOT to Use This
Knowing when a solution doesn't apply is as valuable as knowing when it does. Consider alternatives for your specific situation.
Decision Framework
Use this framework to evaluate whether this approach is right for your use case based on your specific constraints and requirements.