Blue-Green Deployment Pattern: Safe Cutovers with Instant Rollback
When Blue-Green Actually Helps
Blue-green deployment reduces release risk by preparing the new environment completely before traffic moves.
🎯 System Scenario & Requirements
System Goal
Blue-green deployment reduces release risk by preparing the new environment completely before traffic moves.
Actors & Components
- Blue Environment
- Green Environment
- Load Balancer
- Database
- Blue Service
- Green Service
Functional Requirements
- TLDR: Blue-green deployment reduces release risk by preparing the new environment completely before traffic moves.
- It is most effective when rollback is a routing change, not a rebuild.
- TLDR : Blue-green is practical for SRE teams when three things are true: the green stack can be verified under production-like conditions, shared state changes are reversible, and operators can switch traffic back in on…
Constraints & Assumptions
- Blue-green is not the right answer when the risky part is state mutation rather than code rollout.
- Avoid or limit blue-green when: - the deployment includes destructive schema changes, - background workers or scheduled jobs cannot be safely duplicated, - environment duplication cost is too high for the workload, - re…
⚡ Execution Stages & Decision Trace
Stage 1 — How Blue-Green Works in Production
The production sequence should be boring and repeatable: 1.
Build and deploy the new version into the green environment.
Deep Dive
Scenario context
Blue-green deployment reduces release risk by preparing the new environment completely before traffic moves. It is most effective when rollback is a routing change, not a rebuild.
stateDiagram-v2
[*] --> GreenActive
GreenActive --> DeployBlue : build new release
DeployBlue --> TestBlue : deploy to blue env
TestBlue --> SwitchTraffic : parity and smoke OK
SwitchTraffic --> BlueActive : ingress flipped to blue
BlueActive --> GreenActive : rollback triggered
BlueActive --> GreenRetired : observation window passes
note right of GreenActive
blue serves 0%
green serves 100%
end note
note right of BlueActive
blue serves 100%
green on standby
end note
Observable outcome: 📊 Deployment States: Green-Active Through Blue-Active This state machine captures the full lifecycle of a blue-green deployment from the initial GreenActive baseline through blue build, test, traffic switch, and eventu…
Stage 4 — Concrete Config Example: Argo Rollouts Blue-Green
- Why this matters for operators: - previewService gives you a real path to test green before exposure.
- autoPromotionEnabled: false keeps the traffic switch explicit.
- scaleDownDelaySeconds preserves fast rollback for a short buffer window.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: payments-api
spec:
replicas: 8
strategy:
blueGreen:
activeService: payments-api-active
previewService: payments-api-preview
autoPromotionEnabled: false
scaleDownDelaySeconds: 300
prePromotionAnalysis:
templates:
- templateName: payments-smoke-check
selector:
matchLabels:
app: payments-api
template:
metadata:
labels:
app: payments-api
spec:
containers:
- nam
e: api
image: ghcr.io/abstractalgorithms/payments-api:2.7.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080
Observable outcome: - scaleDownDelaySeconds preserves fast rollback for a short buffer window.
Stage 5 — Real-World Applications: What to Instrument Before You Flip Traffic
- Blue-green is only safe if telemetry answers the rollback question quickly.
- What breaks first in many cutovers: 1.
- Cold caches or connection pools.
- Backward-incompatible schema assumptions.
Observable outcome: Backward-incompatible schema assumptions.
Stage 6 — Spring Boot with Environment Variables: Blue-Green Readiness Gate and Argo Rollouts Integration
- Spring Boot's externalized configuration model — environment variables, application.yml , and Spring Profiles — provides a lightweight blue-green readiness gate without requiring additional infrastructure.
- Argo Rollouts, Spinnaker, and Flux extend this gate into automated GitOps promotion pipelines.
- How it solves the problem: Before the traffic switch, operators need proof that the green environment is ready.
- A Spring Boot @ReadinessCheckComponent driven by an environment variable ( DEPLOYMENT SLOT=green ) and a dependency health check gives Argo Rollouts a deterministic HTTP target for the prePromotionAnalysis step — the sa…
// Feature toggle via environment variable — gates green readiness
@Component
public class BlueGreenReadinessCheck implements HealthIndicator {
// Set by deployment tooling: DEPLOYMENT_SLOT=green or blue
@Value("${DEPLOYMENT_SLOT:blue}")
private String deploymentSlot;
// Set true only after green smoke tests pass
@Value("${GREEN_READY:false}")
private boolean greenReady;
private final DataSource dataSource;
private final CacheManager cacheManager;
@Override
public Health health() {
// Blue is always ready (it's already live)
if ("blue".equalsIgnoreCase(deploymentSlot)) {
return Health.up().withDetail("slot", "blue").build();
}
// Green must pass all readiness gates before promotion
Map<String, Object> details = new LinkedHashMap<>();
details.put("slot", "green");
details.put("flagReady", greenReady);
if (!greenReady) {
return Health.down().withDetails(details)
.withDetail("reason", "GREEN_READY not set").build();
}
// Dependency checks: DB + cache must be reachable
try (Connection conn = dataSource.getConnection()) {
details.put("db", conn.isValid(1) ? "up" : "down");
} catch (SQLException ex) {
return Health.down().withDetails(details)
.withDetail("db", "unreachable").build();
}
Cache warmupCache = cacheManager.getCache("product-catalog");
if (warmupCache == null || warmupCache.getNativeCache() == null) {
return Health.down().withDetails(details)
.withDetail("cache", "not warmed").build();
}
return Health.up().withDetails(details).build();
}
}
// Controller: expose the readiness gate as an HTTP endpoint for Argo analysis
@RestController
@RequestMapping("/deployment")
public class DeploymentController {
@Value("${DEPLOYMENT_SLOT:blue}")
private String deploymentSlot;
// Argo Rollouts prePromotionAnalysis calls this endpoint
@GetMapping("/ready")
public ResponseEntity<Map<String, Object>> readiness() {
// Spring Boot Actuator /actuator/health already aggregates HealthIndicators
// This endpoint provides a simple JSON gate for the Argo AnalysisTemplate
return ResponseEntity.ok(Map.of(
"slot", deploymentSlot,
"ready", "green".equalsIgnoreCase(deploymentSlot)
));
}
// Operators flip GREEN_READY=true after smoke tests pass
@PostMapping("/promote")
public ResponseEntity<String> markGreenReady(
@RequestHeader("X-Deploy-Token") String token) {
if (!deployTokenService.validate(token)) {
return ResponseEntity.status(403).body("Invalid deploy token");
}
System.setProperty("GREEN_READY", "true");
return ResponseEntity.ok("Green slot marked ready for promotion");
}
}
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: payments-smoke-check
spec:
metrics:
- nam
e: readiness-gate
interval: 10s
successCondition: result.ready == true
failureLimit: 2
provider:
web:
url: http://payments-api-preview/deployment/ready
jsonPath: "{$.ready}"
Observable outcome: A Spring Boot @ReadinessCheckComponent driven by an environment variable ( DEPLOYMENT SLOT=green ) and a dependency health check gives Argo Rollouts a deterministic HTTP target for the prePromotionAnalysis step — the sa…
End-to-end outcome
Blue-green is a release pattern for systems where deployment risk is concentrated in the traffic switch, not in long-running data migration.
Alternatives considered
Decision Guide for SRE Reviews
If the rollback path requires manual database surgery, the system is not blue-green ready.
Failure and degraded modes
When Not to Use Blue-Green
- Detection: Blue-green is not the right answer when the risky part is state mutation rather than code rollout.
- User or operator impact: Blue-green is not the right answer when the risky part is state mutation rather than code rollout.
Trade-offs & Failure Modes: Pros, Cons, and Alternatives
- Detection: Trade-offs & Failure Modes: Pros, Cons, and Alternatives
- User or operator impact: Trade-offs & Failure Modes: Pros, Cons, and Alternatives
