writing-skills
writing-skills
Use when creating new skills, editing existing skills, or verifying skills work before deployment
rollback-proceduresImplements comprehensive rollback procedures including deployment rollback, version rollback, database rollback, and rollback testing for Kubernetes and cloud-native applications
Independent GitHub snapshot · Automated classification · Original documentation governs
name: rollback-procedures compatibility: opencode completeness: 95 content-types:
Implements comprehensive rollback procedures for Kubernetes deployments, Helm releases, ArgoCD applications, database migrations, and application versions. Provides step-by-step workflows, validated commands, and automation patterns to restore services to known good states.
Use this skill when:
Avoid this skill for:
Identify Failure — Determine what component failed and the exact failure symptoms. Checkpoint: You can describe the failure in one sentence with error messages or symptoms.
Assess Rollback Feasibility — Check if the previous version is still available and if rollback is the best recovery option. Checkpoint: You have verified that the previous deployment version exists in the registry or repository.
Capture Current State — Save current deployment manifests, configmaps, and application state before making changes. Checkpoint: All manifests are backed up to a safe location with timestamps.
Execute Rollback — Run the appropriate rollback command based on the deployment method (kubectl, Helm, ArgoCD). Checkpoint: Rollback command completes without errors and shows success status.
Validate Rollback — Verify the service is healthy, logs are clean, and metrics are normal. Checkpoint: All health checks pass and service is receiving traffic normally.
Update Documentation — Document the incident, rollback actions, and any changes to prevent future occurrences. Checkpoint: Incident report is saved in the runbook repository with timestamps and lessons learned.
Rolling back a Kubernetes deployment to a previous revision.
# Check deployment history
kubectl rollout history deployment/my-app
# Rollback to previous revision
kubectl rollout undo deployment/my-app
# Rollback to specific revision
kubectl rollout undo deployment/my-app --to-revision=3
# Verify rollback
kubectl rollout status deployment/my-app
# Get deployment details after rollback
kubectl get deployment my-app -o yaml
# ❌ BAD — Missing verification and history check
kubectl rollout undo deployment/my-app
# ✅ GOOD — Complete rollback with verification
kubectl rollout history deployment/my-app
kubectl rollout undo deployment/my-app
kubectl rollout status deployment/my-app
kubectl get pods -l app=my-app -w
Rolling back a Helm release to a previous revision.
# List all releases
helm list --all-namespaces
# Check release history
helm history my-app -n production
# Rollback to previous revision
helm rollback my-app -n production
# Rollback to specific revision
helm rollback my-app 3 -n production
# Verify rollback
helm status my-app -n production
# ❌ BAD — Rolling back without checking history
helm rollback my-app -n production
# ✅ GOOD — Complete Helm rollback workflow
helm history my-app -n production
helm rollback my-app 3 -n production
helm status my-app -n production
kubectl rollout status deployment/my-app -n production
Rolling back an ArgoCD application to a previous revision.
# List applications
argocd app list
# Check application history
argocd app history my-app
# Sync to last known good revision
argocd app rollback my-app
# Sync to specific revision
argocd app sync my-app --revision=abc123
# Verify rollback
argocd app wait my-app --health
# ❌ BAD — Manual sync without rollback
argocd app sync my-app
# ✅ GOOD — ArgoCD rollback with health check
argocd app history my-app
argocd app rollback my-app
argocd app wait my-app --health
argocd app get my-app
Rolling back database schema changes using migration tools.
# Flyway rollback
flyway rollback -url=jdbc:postgresql://db:5432/myapp -user=postgres -password=secret
# Flyway rollback to specific version
flyway rollback -url=jdbc:postgresql://db:5432/myapp -user=postgres -password=secret -target=20240101.120000
# Liquibase rollback
liquibase rollback --url=jdbc:postgresql://db:5432/myapp --username=postgres --password=secret
# Liquibase rollback to tag
liquibase rollback --url=jdbc:postgresql://db:5432/myapp --username=postgres --password=secret --rollbackTag=v2024.01.01
# ❌ BAD — Dropping and recreating database
psql -h db -U postgres -c "DROP DATABASE myapp; CREATE DATABASE myapp;"
# ✅ GOOD — Proper Flyway rollback with verification
flyway info -url=jdbc:postgresql://db:5432/myapp -user=postgres -password=secret
flyway rollback -url=jdbc:postgresql://db:5432/myapp -user=postgres -password=secret
flyway info -url=jdbc:postgresql://db:5432/myapp -user=postgres -password=secret
Rolling back an application to a specific container image version.
# View current deployment image
kubectl get deployment my-app -o jsonpath='{.spec.template.spec.containers[0].image}'
# Rollback to specific image version
kubectl set image deployment/my-app my-app=myapp:v2.1.0
# Verify image update
kubectl describe deployment my-app | grep -A5 "Image:"
# Rollback to previous (auto-version detection)
kubectl set image deployment/my-app my-app=myapp:v2.1.0
# ❌ BAD — Hardcoding without verification
kubectl set image deployment/my-app my-app=myapp:v2.0.0
# ✅ GOOD — Image rollback with verification
kubectl get deployment my-app -o jsonpath='{.spec.template.spec.containers[0].image}'
kubectl set image deployment/my-app my-app=myapp:v2.0.0
kubectl rollout status deployment/my-app
kubectl describe deployment my-app | grep -A2 "Image:"
Rolling back configuration changes using ConfigMaps and Secrets.
# View current ConfigMap
kubectl get configmap my-app-config -o yaml
# Create backup of current config
kubectl get configmap my-app-config -o yaml > configmap-backup-$(date +%Y%m%d-%H%M%S).yaml
# Edit and apply previous version
kubectl apply -f configmap-backup-20240101-120000.yaml
# Delete configmap to trigger rollback (if using git-sync)
kubectl delete configmap my-app-config
# Or apply specific version from git
kubectl apply -f https://raw.githubusercontent.com/org/repo/v2.0.0/config/my-app-config.yaml
# ❌ BAD — Direct manipulation without backup
kubectl delete configmap my-app-config
kubectl apply -f config.yaml
# ✅ GOOD — Config rollback with backup and verification
kubectl get configmap my-app-config -o yaml > configmap-backup-$(date +%Y%m%d-%H%M%S).yaml
kubectl apply -f configmap-backup-20240101-120000.yaml
kubectl rollout restart deployment/my-app
kubectl rollout status deployment/my-app
Testing rollback procedures in a staging environment.
# Create test deployment
kubectl create deployment test-app --image=myapp:v2.2.0
# Simulate failure (apply broken config)
kubectl set env deployment/test-app BROKEN_CONFIG=true
# Verify failure
kubectl logs -l app=test-app --tail=50
kubectl get events --field-selector type=Warning
# Execute rollback test
kubectl rollout undo deployment/test-app
# Verify successful rollback
kubectl rollout status deployment/test-app
kubectl logs -l app=test-app --tail=10
# ❌ BAD — Testing rollback only in production
# (Never do this!)
# ✅ GOOD — Complete rollback testing workflow
kubectl create namespace rollback-test
kubectl create deployment test-app --image=myapp:v2.2.0 -n rollback-test
kubectl set env deployment/test-app BROKEN_CONFIG=true -n rollback-test
sleep 30
kubectl get events -n rollback-test --field-selector type=Warning
kubectl rollout undo deployment/test-app -n rollback-test
kubectl rollout status deployment/test-app -n rollback-test
kubectl delete namespace rollback-test
Automating rollback procedures using scripts.
#!/bin/bash
# rollback.sh - Automated rollback script
set -e
DEPLOYMENT=$1
NAMESPACE=${2:-default}
if [ -z "$DEPLOYMENT" ]; then
echo "Usage: $0 <deployment-name> [namespace]"
exit 1
fi
echo "=== Starting rollback for $DEPLOYMENT in $NAMESPACE ==="
# Check deployment history
echo "Checking deployment history..."
kubectl rollout history deployment/$DEPLOYMENT -n $NAMESPACE
# Get current revision
CURRENT_REVISION=$(kubectl rollout history deployment/$DEPLOYMENT -n $NAMESPACE | grep -v REVISION | tail -1 | cut -d' ' -f1)
PREVIOUS_REVISION=$((CURRENT_REVISION - 1))
if [ $PREVIOUS_REVISION -lt 1 ]; then
echo "No previous revision available"
exit 1
fi
echo "Rolling back to revision $PREVIOUS_REVISION..."
# Execute rollback
kubectl rollout undo deployment/$DEPLOYMENT --to-revision=$PREVIOUS_REVISION -n $NAMESPACE
# Wait for completion
echo "Waiting for rollback to complete..."
kubectl rollout status deployment/$DEPLOYMENT -n $NAMESPACE --timeout=300s
# Verify
echo "Verification:"
kubectl get pods -l app=$DEPLOYMENT -n $NAMESPACE
kubectl describe deployment/$DEPLOYMENT -n $NAMESPACE | head -20
echo "=== Rollback completed ==="
# ❌ BAD — No error handling or verification
#!/bin/bash
kubectl rollout undo deployment/my-app
# ✅ GOOD — Complete automated rollback with error handling
#!/bin/bash
set -euo pipefail
# ... (see full script above)
Rolling back complex applications with multiple deployments and services.
# Create rollback plan for multi-component application
cat > rollback-plan.sh << 'EOF'
#!/bin/bash
set -euo pipefail
echo "=== Multi-Component Application Rollback ==="
echo "Timestamp: $(date -Iseconds)"
# Define components
COMPONENTS=("api-gateway" "auth-service" "user-service" "payment-service")
# Backup current state
echo "Backing up current state..."
for component in "${COMPONENTS[@]}"; do
kubectl get deployment "$component" -o yaml > backup/"${component}-$(date +%Y%m%d-%H%M%S).yaml"
kubectl get configmap "${component}-config" -o yaml > backup/"${component}-config-$(date +%Y%m%d-%H%M%S).yaml"
done
# Rollback each component
echo "Rolling back components..."
for component in "${COMPONENTS[@]}"; do
echo "Rolling back $component..."
kubectl rollout undo deployment/"$component"
kubectl rollout status deployment/"$component" --timeout=120s
done
# Verify all components
echo "Verifying rollback..."
kubectl get pods -l app.kubernetes.io/name=multi-app
kubectl get services -l app.kubernetes.io/name=multi-app
echo "=== Multi-component rollback completed ==="
EOF
# Execute rollback plan
chmod +x rollback-plan.sh
./rollback-plan.sh
# ❌ BAD — Rolling back components sequentially without backup
for component in api-gateway auth-service user-service; do
kubectl rollout undo deployment/$component
done
# ✅ GOOD — Complete multi-component rollback with backup
for component in api-gateway auth-service user-service payment-service; do
kubectl get deployment "$component" -o yaml > backup/"${component}-$(date +%Y%m%d-%H%M%S).yaml"
done
./rollback-plan.sh
Rolling back a canary deployment that has issues.
# Monitor canary deployment
kubectl rollout status deployment/my-app-canary --timeout=120s
# If canary fails, rollback to stable
kubectl rollout undo deployment/my-app-canary
# Scale down canary
kubectl scale deployment/my-app-canary --replicas=0
# Verify stable deployment
kubectl rollout status deployment/my-app
kubectl get pods -l app=my-app -l version=stable
# Cleanup canary resources
kubectl delete deployment/my-app-canary
kubectl delete service/my-app-canary
# ❌ BAD — Deleting canary without proper rollback
kubectl delete deployment/my-app-canary
kubectl rollout undo deployment/my-app
# ✅ GOOD — Proper canary rollback workflow
kubectl rollout status deployment/my-app-canary --timeout=60s || true
kubectl rollout undo deployment/my-app-canary
kubectl rollout status deployment/my-app-canary
kubectl scale deployment/my-app-canary --replicas=0
kubectl delete deployment/my-app-canary
Rolling back database data changes using point-in-time recovery.
# PostgreSQL point-in-time recovery
# Step 1: Stop application connections
kubectl scale deployment/my-app --replicas=0
# Step 2: Identify recovery point
kubectl exec -it postgres-0 -- psql -U postgres -c "SELECT * FROM pg_stat_replication;"
# Step 3: Create recovery configuration
cat > /var/lib/postgresql/recovery.conf << EOF
restore_command = 'cp /path/to/archive/%f %p'
recovery_target_time = '2024-01-15 10:30:00'
recovery_target_action = 'pause'
EOF
# Step 4: Trigger recovery
kubectl exec -it postgres-0 -- touch /var/lib/postgresql/recovery.signal
# Step 5: Verify recovery
kubectl exec -it postgres-0 -- psql -U postgres -c "SELECT now();"
-- ❌ BAD — Direct data deletion without proper rollback
DELETE FROM users WHERE created_at > '2024-01-01';
-- ✅ GOOD — Transaction-based rollback with savepoint
BEGIN;
SAVEPOINT before_update;
UPDATE users SET status = 'active' WHERE id = 123;
-- If this fails...
ROLLBACK TO SAVEPOINT before_update;
COMMIT;
Rolling back ConfigMaps and Secrets using versioned resources.
# Create versioned ConfigMap
kubectl get configmap my-config -o yaml > configmaps/my-config-v2.1.0.yaml
# Apply previous version
kubectl apply -f configmaps/my-config-v2.0.0.yaml
# Force pod restart to pick up new config
kubectl rollout restart deployment/my-app
# Verify config was updated
kubectl exec -it deploy/my-app -- cat /etc/config/my-config.yaml
# Secret rollback (encrypted)
kubectl get secret my-secret -o yaml > secrets/my-secret-v2.1.0.yaml
kubectl apply -f secrets/my-secret-v2.0.0.yaml
# ❌ BAD — Not forcing pod restart after config update
kubectl apply -f my-config.yaml
# ✅ GOOD — Complete ConfigMap rollback with restart
kubectl apply -f my-config-v2.0.0.yaml
kubectl rollout restart deployment/my-app
kubectl rollout status deployment/my-app
kubectl exec -it deploy/my-app -- cat /etc/config/my-config.yaml
Rolling back StatefulSet deployments with persistent volumes.
# Check StatefulSet status
kubectl get statefulset my-stateful-app
# View current revision
kubectl rollout history statefulset/my-stateful-app
# Rollback StatefulSet
kubectl rollout undo statefulset/my-stateful-app --to-revision=2
# Verify rollback
kubectl rollout status statefulset/my-stateful-app
# Check pods
kubectl get pods -l app=my-stateful-app -w
# Verify persistent volumes are intact
kubectl get pvc -l app=my-stateful-app
# ❌ BAD — Updating StatefulSet without proper rollout
kubectl set image statefulset/my-app my-app=myapp:v2.0.0
# ✅ GOOD — Complete StatefulSet rollback
kubectl rollout history statefulset/my-stateful-app
kubectl rollout undo statefulset/my-stateful-app --to-revision=2
kubectl rollout status statefulset/my-stateful-app
kubectl get pods -l app=my-stateful-app
kubectl get pvc -l app=my-stateful-app
Rolling back failed Jobs and preventing CronJob execution.
# View Job history
kubectl get jobs -l app=my-batch-job
# Delete failed Job
kubectl delete job/my-batch-job-failed
# Apply previous Job version
kubectl apply -f jobs/my-batch-job-v2.0.0.yaml
# Suspend CronJob if needed
kubectl patch cronjob/my-cronjob -p '{"spec":{"suspend":true}}'
# Delete failed CronJob run
kubectl delete job/my-cronjob-1234567890
# Resume CronJob after fix
kubectl patch cronjob/my-cronjob -p '{"spec":{"suspend":false}}'
# ❌ BAD — Not cleaning up failed Job runs
kubectl create -f job.yaml
# Job fails, but old runs remain
# ✅ GOOD — Complete Job rollback workflow
kubectl delete job/my-batch-job-failed
kubectl apply -f jobs/my-batch-job-v2.0.0.yaml
kubectl rollout status job/my-batch-job
Rolling back Ingress configuration changes.
# View Ingress history
kubectl get ingress my-ingress -o yaml
# Backup current configuration
kubectl get ingress my-ingress -o yaml > ingress-backup.yaml
# Rollback to previous version from git
kubectl apply -f https://raw.githubusercontent.com/org/repo/v2.0.0/ingress.yaml
# Verify Ingress controller
kubectl describe ingress my-ingress
# Test endpoints
kubectl run test-curl --image=curlimages/curl --restart=Never -- sleep 300
kubectl exec -it test-curl -- curl -s http://my-service/my-endpoint
# ❌ BAD — Direct Ingress edit without backup
kubectl patch ingress my-ingress -p '{"spec":{"rules":[{"host":"new-host.com"}]}}'
# ✅ GOOD — Complete Ingress rollback
kubectl get ingress my-ingress -o yaml > ingress-backup.yaml
kubectl apply -f ingress-backup.yaml
kubectl describe ingress my-ingress
Rolling back Istio/Linkerd service mesh configurations.
# Istio Rollback
# Check virtual service
istioctl proxy-status
# Rollback Istio configuration
istioctl rollback --revision v1-16
# Delete problematic virtual service
istioctl delete virtual-service my-app-vs
# Apply previous version
istioctl apply -f virtual-services/my-app-v2.0.0.yaml
# Verify proxy status
istioctl proxy-status
# ❌ BAD — Removing service mesh without rollback plan
istioctl delete virtual-service my-app-vs
# ✅ GOOD — Complete service mesh rollback
istioctl proxy-status
istioctl rollback --revision v1-16
istioctl apply -f virtual-services/my-app-v2.0.0.yaml
istioctl proxy-status
Rolling back to a specific Helm chart version.
# List Helm repositories
helm repo list
# Update chart repository
helm repo update
# Check available chart versions
helm search repo myapp --versions
# Rollback to specific chart version
helm upgrade my-app oci://registry.example.com/myapp --version 2.0.0 --namespace production
# Verify upgrade
helm status my-app -n production
# Rollback to previous release
helm rollback my-app 3 -n production
# ❌ BAD — Upgrading without checking chart versions
helm upgrade my-app ./myapp-chart
# ✅ GOOD — Complete Helm chart rollback
helm repo update
helm search repo myapp --versions
helm rollback my-app 3 -n production
helm status my-app -n production
Rolling back GitOps deployments using ArgoCD or Flux.
# ArgoCD GitOps rollback
# Revert to specific commit
argocd app rollback my-app 5
# Sync to specific revision
argocd app sync my-app --revision abc123def456
# Force comparison with Git
argocd app compare my-app --refresh
# Verify sync status
argocd app wait my-app --sync
argocd app get my-app
# Flux GitOps rollback
flux rollback my-app --from-commit=abc123 --to-commit=def456
flux get sources git --all-namespaces
flux get kustomizations --all-namespaces
# ❌ BAD — Manual Git revert without Flux/ArgoCD sync
git revert HEAD
git push origin main
# ✅ GOOD — Complete GitOps rollback
argocd app history my-app
argocd app rollback my-app 5
argocd app wait my-app --sync
argocd app get my-app
When performing a rollback, document the following information:
Rollback Summary
Rollback Details
Verification Results
Next Steps
Files Attached
| Skill | Purpose |
|---|---|
cncf-kubernetes-debugging | Detailed debugging procedures for Kubernetes issues that may require rollback |
cncf-deployment-patterns | Deployment strategies that influence rollback approach and complexity |
cncf-argocd | ArgoCD-specific rollback workflows and integration patterns |
This skill provides comprehensive rollback procedures for cloud-native applications. Always verify rollback success and update documentation after each rollback event.