Automated deployment pipeline using ArgoCD with progressive delivery
This project implements a complete GitOps workflow for Kubernetes deployments using ArgoCD. GitOps is a paradigm where Git serves as the single source of truth for declarative infrastructure and applications, with automated processes ensuring the live state matches the desired state in Git.
The pipeline includes automated testing, progressive delivery strategies (canary and blue-green deployments), automatic rollbacks, and comprehensive monitoring to ensure reliable application deployments.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitOps Deployment Flow β
β β
β βββββββββββββ ββββββββββββ ββββββββββββββββ β
β β DeveloperββββββββββΆβ Git βββββββββΆβ ArgoCD β β
β β Push β β Repositoryβ β Controller β β
β βββββββββββββ ββββββββββββ ββββββββ¬ββββββββ β
β β β
β β Sync β
β βΌ β
β βββββββββββββββββββ β
β β Kubernetes β β
β β Cluster β β
β β β β
β β βββββ βββββ β β
β β βPodβ βPodβ β β
β β βββββ βββββ β β
β βββββββββββββββββββ β
β β β
β β Monitor β
β βΌ β
β βββββββββββββββββββ β
β β Prometheus β β
β β + Grafana β β
β βββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Deploy ArgoCD to your Kubernetes cluster:
# Create ArgoCD namespace
kubectl create namespace argocd
# Install ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Wait for ArgoCD to be ready
kubectl wait --for=condition=available --timeout=300s deployment/argocd-server -n argocd
# Get initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# Port forward to access UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
Organize your Git repository following GitOps best practices:
gitops-repo/
βββ applications/
β βββ dev/
β β βββ app-deployment.yaml
β β βββ app-service.yaml
β β βββ kustomization.yaml
β βββ staging/
β β βββ app-deployment.yaml
β β βββ app-service.yaml
β β βββ kustomization.yaml
β βββ production/
β βββ app-deployment.yaml
β βββ app-service.yaml
β βββ rollout.yaml
β βββ kustomization.yaml
βββ argocd-apps/
β βββ dev-app.yaml
β βββ staging-app.yaml
β βββ production-app.yaml
βββ base/
βββ deployment.yaml
βββ service.yaml
βββ kustomization.yaml
Define an ArgoCD Application resource:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/gitops-repo.git
targetRevision: main
path: applications/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Implement canary deployments for safer releases:
# Install Argo Rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# Create a Rollout resource
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-app
namespace: production
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {duration: 2m}
- setWeight: 40
- pause: {duration: 2m}
- setWeight: 60
- pause: {duration: 2m}
- setWeight: 80
- pause: {duration: 2m}
canaryService: my-app-canary
stableService: my-app-stable
trafficRouting:
nginx:
stableIngress: my-app-ingress
revisionHistoryLimit: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: myapp:v2.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
Integrate automated tests before deployment:
name: GitOps CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run unit tests
run: |
npm install
npm test
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Run integration tests
run: |
docker-compose up -d
npm run test:integration
docker-compose down
- name: Security scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update image tag
run: |
sed -i "s|image:.*|image: myapp:${{ github.sha }}|g" applications/production/app-deployment.yaml
- name: Commit and push
run: |
git config user.name "GitHub Actions"
git config user.email "[email protected]"
git add applications/production/app-deployment.yaml
git commit -m "Update production image to ${{ github.sha }}"
git push
Configure health checks and Prometheus metrics:
# Application health checks
apiVersion: v1
kind: Service
metadata:
name: my-app
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-app
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Register multiple clusters with ArgoCD:
# Login to ArgoCD CLI
argocd login localhost:8080 --username admin --password
# Add external cluster
argocd cluster add production-cluster --name production
# List registered clusters
argocd cluster list
# Deploy app to specific cluster
kubectl apply -f - <
# ArgoCD RBAC Policy
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.csv: |
p, role:developers, applications, get, */*, allow
p, role:developers, applications, sync, */dev/*, allow
p, role:ops, applications, *, */*, allow
p, role:ops, clusters, *, *, allow
g, engineering-team, role:developers
g, ops-team, role:ops
Automatic and manual rollback capabilities:
# Manual rollback to previous version
argocd app rollback my-app-production
# Rollback to specific revision
argocd app rollback my-app-production 5
# Automatic rollback on failed health checks
apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
strategy:
canary:
analysis:
templates:
- templateName: success-rate
startingStep: 2
args:
- name: service-name
value: my-app-canary
trafficRouting:
nginx:
stableIngress: my-app
steps:
- setWeight: 20
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 5m}
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 1m
successCondition: result >= 0.95
failureLimit: 3
provider:
prometheus:
address: http://prometheus:9090
query: |
sum(rate(http_requests_total{service="{{args.service-name}}",status=~"2.."}[1m]))
/
sum(rate(http_requests_total{service="{{args.service-name}}"}[1m]))
This GitOps pipeline demonstrates modern deployment practices that prioritize reliability, speed, and developer experience. By treating Git as the single source of truth and automating the sync process, we achieve declarative, version-controlled, and auditable infrastructure management.
The integration of progressive delivery strategies and automated rollbacks ensures that deployments are both fast and safe, minimizing the risk of production incidents while maximizing deployment frequency.