Implement Blue-Green Deployment
Blue-green deployment is a release strategy that maintains two identical production environments (Blue and Green). At any time, only one environment serves live traffic. When a new version is ready, traffic is switched to the other environment, enabling instant rollback if issues arise.
API7 Gateway implements blue-green deployments using the traffic-split plugin, which distributes traffic across multiple upstreams by weight.
Blue-green deployment switches 100% of traffic at once. For gradual traffic shifting (e.g., 10% to new version), see Canary Release.
Prerequisites
- An API7 Enterprise instance is running.
- A Gateway Group is created and a Gateway instance is running.
- A token from the Dashboard.
Workflow Overview
Step 1: Prepare Upstreams
Create a published service whose default upstream represents the Blue environment. The Green environment will be defined inline in the traffic-split plugin when you switch traffic.
- Admin API
- ADC
Create the Blue service and route:
curl -k "https://localhost:7443/apisix/admin/services/blue-green-service?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "blue-green-service",
"upstream": {
"type": "roundrobin",
"scheme": "https",
"pass_host": "node",
"nodes": [
{
"host": "mock.api7.ai",
"port": 443,
"weight": 100
}
]
}
}'
curl -k "https://localhost:7443/apisix/admin/routes/blue-green-route?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "blue-green-route",
"methods": ["GET"],
"paths": ["/headers"],
"service_id": "blue-green-service"
}'
The default service upstream now represents the Blue environment.
Define the Blue service and route in your ADC configuration:
services:
- name: blue-green-service
upstream:
scheme: https
pass_host: node
nodes:
- host: mock.api7.ai
port: 443
weight: 100
routes:
- name: blue-green-route
uris:
- /headers
methods:
- GET
adc sync -f adc.yaml
Step 2: Switch Traffic to Green
Apply the traffic-split plugin to route 100% of traffic to the Green upstream.
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/routes/blue-green-route?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "blue-green-route",
"methods": ["GET"],
"paths": ["/headers"],
"service_id": "blue-green-service",
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"weight": 100,
"upstream": {
"type": "roundrobin",
"nodes": [
{
"host": "httpbin.org",
"port": 443,
"weight": 1
}
]
}
},
{
"weight": 0
}
]
}
]
}
}
}'
| Field | Description |
|---|---|
Inline upstream | The Green upstream to receive traffic |
weight: 100 (Green) | All traffic goes to Green |
weight: 0 (no upstream_id) | No traffic to the default (Blue) upstream |
services:
- name: blue-green-service
upstream:
scheme: https
pass_host: node
nodes:
- host: mock.api7.ai
port: 443
weight: 100
routes:
- name: blue-green-route
uris:
- /headers
methods:
- GET
plugins:
traffic-split:
rules:
- weighted_upstreams:
- upstream:
type: roundrobin
scheme: https
pass_host: node
nodes:
- host: httpbin.org
port: 443
weight: 1
weight: 100
- weight: 0
adc sync -f adc.yaml
Step 3: Validate
Send test requests to confirm all traffic reaches the Green environment:
# Verify responses come from the Green (v2) backend
for i in $(seq 1 10); do
curl -s "http://127.0.0.1:9080/headers" | grep 'X-Amzn-Trace-Id'
done
All responses should come from the Green upstream. In this example, httpbin.org responses include X-Amzn-Trace-Id, while the Blue upstream does not.
Rollback
To roll back to Blue, reverse the weights:
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/routes/blue-green-route?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "blue-green-route",
"methods": ["GET"],
"paths": ["/headers"],
"service_id": "blue-green-service",
"plugins": {
"traffic-split": {
"rules": [
{
"weighted_upstreams": [
{
"weight": 0,
"upstream": {
"type": "roundrobin",
"nodes": [
{
"host": "httpbin.org",
"port": 443,
"weight": 1
}
]
}
},
{
"weight": 100
}
]
}
]
}
}
}'
Update the traffic-split weights so the default upstream has weight 100 and the Green upstream has weight 0, or remove the plugin configuration entirely.
Cleanup
After the Green environment is verified and stable, you can:
- Remove the
traffic-splitplugin from the route. - Update the service's default upstream to point to the Green nodes.
- Decommission the old Blue environment.
Conditional Blue-Green Switch
You can also switch traffic conditionally — for example, based on a request header. This is useful for testing the Green environment with specific users before switching all traffic.
{
"rules": [
{
"match": [
{
"vars": [["http_x_env", "==", "green"]]
}
],
"weighted_upstreams": [
{
"weight": 100,
"upstream": {
"type": "roundrobin",
"scheme": "https",
"pass_host": "node",
"nodes": [
{
"host": "httpbin.org",
"port": 443,
"weight": 1
}
]
}
}
]
}
]
}
With this configuration:
- Requests with header
X-Env: greenare routed to the Green upstream. - All other requests continue to the default (Blue) upstream.
Next Steps
- Canary Release: Gradually shift traffic between versions.
- Health Check: Monitor upstream health during deployments.
- Fault Injection: Test resilience during deployment transitions.