Blue/Green and Canary Deployments with Argo Rollouts: Architecture & Implementation
In-depth architectural breakdown and operational implementation for Blue/Green and Canary Deployments with Argo Rollouts: Architecture & Implementation.
Prerequisite knowledge: Deployments, Services, Ingress, readiness probes (Q47)
Question (Scenario-Based)
Your e-commerce platform releases features weekly. A bad release last quarter caused 30 minutes of downtime and lost $200K in revenue. Leadership now requires that all releases be validated against 5% of live traffic before full rollout, with automatic rollback if error rates exceed 1%. How do you implement this?
Quick Answer (30 sec revision)
Use Argo Rollouts with a canary strategy integrated with your ingress controller. Define analysis templates that query Prometheus for error rates, and configure automatic rollback thresholds. Traffic is shifted gradually (5% → 25% → 50% → 100%) with automated health analysis at each step.
Detailed Answer
️ Architecture Overview
┌─────────────────────────────────┐
│ Ingress Controller │
│ (nginx / Istio / Traefik) │
└──────────┬──────────────────┬────┘
│ │
95% weight 5% weight
│ │
┌──────────▼──────┐ ┌────────▼────────┐
│ Stable Service │ │ Canary Service │
│ (blue/current) │ │ (green/new) │
└──────────┬──────┘ └────────┬─────────┘
│ │
┌──────────▼──────┐ ┌────────▼─────────┐
│ Stable Pods │ │ Canary Pods │
│ (v1.0 - 9pods) │ │ (v2.0 - 1pod) │
└─────────────────┘ └──────────────────┘
│ │
┌──────────▼──────────────────▼─────────┐
│ Prometheus │
│ (error rate, latency, throughput) │
└───────────────────────────────────────-┘
│
┌──────────▼──────────────────────────────┐
│ Argo Rollouts Controller │
│ - Queries Prometheus every 60s │
│ - Promotes if error_rate < 1% │
│ - Aborts + rolls back if error_rate > 1%│
└─────────────────────────────────────────┘
️ Step-by-Step Implementation
Step 1: Install Argo Rollouts
# Install Argo Rollouts controller
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts \
-f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# Install kubectl plugin for visibility
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x kubectl-argo-rollouts-linux-amd64
mv kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
# Verify
kubectl argo rollouts version
Step 2: Define the Rollout Resource
# rollout-ecommerce.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: ecommerce-api
namespace: production
spec:
replicas: 10
selector:
matchLabels:
app: ecommerce-api
template:
metadata:
labels:
app: ecommerce-api
spec:
containers:
- name: ecommerce-api
image: registry.mycompany.com/ecommerce-api:v2.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
strategy:
canary:
# Reference to stable and canary services
stableService: ecommerce-api-stable
canaryService: ecommerce-api-canary
# Traffic management via NGINX ingress
trafficRouting:
nginx:
stableIngress: ecommerce-api-ingress
# Automated analysis at each step
analysis:
templates:
- templateName: error-rate-analysis
startingStep: 2 # Start analysis from step index 2
args:
- name: service-name
value: ecommerce-api-canary
# Canary progression steps
steps:
- setWeight: 5 # Step 0: Send 5% traffic to canary
- pause: {duration: 2m} # Step 1: Wait 2 minutes, observe manually
- setWeight: 10 # Step 2: Increase to 10%
- pause: {duration: 5m} # Step 3: Run analysis for 5 min
- setWeight: 25 # Step 4: Increase to 25%
- pause: {duration: 5m} # Step 5: Run analysis for 5 min
- setWeight: 50 # Step 6: Increase to 50%
- pause: {duration: 10m}# Step 7: Extended analysis at half traffic
- setWeight: 100 # Step 8: Full promotion
Step 3: Create Stable and Canary Services
# services.yaml
---
# Stable service (points to current/blue version)
apiVersion: v1
kind: Service
metadata:
name: ecommerce-api-stable
namespace: production
spec:
selector:
app: ecommerce-api
ports:
- port: 80
targetPort: 8080
---
# Canary service (points to new/green version)
# Argo Rollouts manages pod selectors automatically
apiVersion: v1
kind: Service
metadata:
name: ecommerce-api-canary
namespace: production
spec:
selector:
app: ecommerce-api
ports:
- port: 80
targetPort: 8080
Step 4: Define the Ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ecommerce-api-ingress
namespace: production
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: api.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ecommerce-api-stable # Argo manages canary split automatically
port:
number: 80
Step 5: Define the AnalysisTemplate (the heart of automated rollback)
# analysis-template.yaml
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: error-rate-analysis
namespace: production
spec:
args:
- name: service-name
metrics:
# Metric 1: HTTP Error Rate (primary rollback trigger)
- name: http-error-rate
interval: 60s # Query every 60 seconds
count: 5 # Run 5 times total (5 minutes of analysis)
failureLimit: 1 # Allow 1 failure before marking as Failed
# Success condition: error rate must be below 1%
successCondition: result[0] < 0.01
failureCondition: result[0] >= 0.01
provider:
prometheus:
address: http://prometheus.monitoring.svc.cluster.local:9090
query: |
sum(rate(http_requests_total{
service="{{args.service-name}}",
status=~"5.."
}[5m]))
/
sum(rate(http_requests_total{
service="{{args.service-name}}"
}[5m]))
# Metric 2: P99 Latency (secondary health signal)
- name: p99-latency
interval: 60s
count: 5
failureLimit: 2 # More tolerant for latency spikes
# P99 must be under 500ms
successCondition: result[0] < 0.5
failureCondition: result[0] >= 1.0 # Hard fail at 1 second
provider:
prometheus:
address: http://prometheus.monitoring.svc.cluster.local:9090
query: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket{
service="{{args.service-name}}"
}[5m])) by (le)
)
# Metric 3: Success Rate via Datadog (optional - multi-provider)
- name: success-rate-datadog
interval: 60s
count: 5
successCondition: result >= 99.0
provider:
datadog:
apiVersion: v1
interval: 5m
query: |
avg:trace.http.request.hits.by_http_status{
service:ecommerce-api,
http.status_code:2*
}.as_rate()
Step 6: Triggering and Monitoring a Release
# Trigger a new release by updating the image
kubectl argo rollouts set image ecommerce-api \
ecommerce-api=registry.mycompany.com/ecommerce-api:v2.1.0 \
-n production
# Watch the rollout progress in real-time
kubectl argo rollouts get rollout ecommerce-api \
-n production --watch
# Expected output:
# Name: ecommerce-api
# Namespace: production
# Status: ॥ Paused
# Strategy: Canary
# Step: 1/8
# SetWeight: 5
# ActualWeight: 5
# Images: registry.mycompany.com/ecommerce-api:v2.0.0 (stable)
# registry.mycompany.com/ecommerce-api:v2.1.0 (canary)
# Replicas:
# Desired: 10
# Current: 11
# Updated: 1
# Ready: 11
# Available: 11
# Manually promote (skip pause) if you're confident
kubectl argo rollouts promote ecommerce-api -n production
# Manually abort and roll back
kubectl argo rollouts abort ecommerce-api -n production
# Undo to previous version
kubectl argo rollouts undo ecommerce-api -n production
Step 7: Blue/Green Strategy (Alternative to Canary)
# For Blue/Green: swap entire traffic at once, but with preview testing
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: ecommerce-api-bluegreen
spec:
replicas: 10
strategy:
blueGreen:
activeService: ecommerce-api-active # Production traffic
previewService: ecommerce-api-preview # Internal test traffic only
# Automatically promote after preview passes analysis
autoPromotionEnabled: false # Require manual promotion
# Run analysis on the preview (green) environment
prePromotionAnalysis:
templates:
- templateName: error-rate-analysis
args:
- name: service-name
value: ecommerce-api-preview
# Keep old (blue) version alive for 5 minutes post-promotion
# Allows instant rollback if something slips through
scaleDownDelaySeconds: 300
postPromotionAnalysis:
templates:
- templateName: error-rate-analysis
args:
- name: service-name
value: ecommerce-api-active
️ Trade-offs & Alternatives
| Approach | Traffic Validation | Rollback Speed | Complexity | Cost | |---|---|---|---|---| | Canary (Argo) | Real traffic, gradual | Instant (weight reset) | Medium | Low (1 extra pod) | | Blue/Green (Argo) | Preview only | Instant (service swap) | Medium | High (2x replicas) | | Feature Flags | Per-user targeting | Instant (flag flip) | Low | Low | | Flagger + Linkerd | Real traffic + mTLS | Instant | High | Medium | | Manual canary | Real traffic | Slow (manual revert) | Low | Low |
️ Common Mistakes & Misconceptions
- "Argo Rollouts replaces Deployments." — It is a separate CRD. You migrate from Deployment to Rollout, but they coexist in the same cluster.
- "My canary gets exactly 5% of traffic." — With weight-based routing, traffic distribution is approximate at low replica counts. With 10 pods and 5% weight, you may have 0 or 1 canary pod, not a precise 5%.
- "Analysis failure always triggers rollback." — Only if
failureLimitis exceeded. Design your thresholds carefully — too strict causes false rollbacks during normal traffic spikes. - "Blue/Green means zero downtime by default." — It means zero application downtime. DNS propagation and connection draining during the service swap still need to be managed.
Key Takeaway
Argo Rollouts transforms deployments from a binary all-or-nothing event into a controlled, data-driven progression. The AnalysisTemplate is the critical component — it bridges your observability platform (Prometheus, Datadog) with your deployment controller, enabling truly automated progressive delivery. The combination of automated rollback and gradual traffic shifting gives you both safety and speed.
Self-Assessment Checklist
- [ ] Can you explain the difference between
stableServiceandcanaryServicein Argo Rollouts? - [ ] Can you write an AnalysisTemplate that queries Prometheus for error rate?
- [ ] Can you explain why exact traffic percentages are approximate with pod-count-based weighting?
- [ ] Can you describe when you'd choose Blue/Green over Canary?
Finished reading?
Mark as complete to claim your +20 XP and track progress.
