# 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`](https://docs.api7.ai/hub/traffic-split.md) plugin, which distributes traffic across multiple upstreams by weight.

tip

Blue-green deployment switches 100% of traffic at once. For gradual traffic shifting (e.g., 10% to new version), see [Canary Release](https://docs.api7.ai/api7-gateway/how-to-guides/traffic-management/canary-release.md).

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

* An API7 Enterprise instance is running.
* A Gateway Group is created and a Gateway instance is running.
* A [token from the Dashboard](https://docs.api7.ai/api7-gateway/reference/obtain-dashboard-token.md).

## Workflow Overview[​](#workflow-overview "Direct link to Workflow Overview")

<!-- -->

## Step 1: Prepare Upstreams[​](#step-1-prepare-upstreams "Direct link to Step 1: Prepare Upstreams")

Create a 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={gateway_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={gateway_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:

adc.yaml

```
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

    labels:

      docs-example: blue-green-service
```

Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:

```
adc diff -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=blue-green-service
```

Synchronize the reviewed configuration:

```
adc sync -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=blue-green-service
```

## Step 2: Switch Traffic to Green[​](#step-2-switch-traffic-to-green "Direct link to 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={gateway_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 |

adc.yaml

```
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

    labels:

      docs-example: blue-green-service
```

Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:

```
adc diff -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=blue-green-service
```

Synchronize the reviewed configuration:

```
adc sync -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=blue-green-service
```

## Step 3: Validate[​](#step-3-validate "Direct link to 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[​](#rollback "Direct link to 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={gateway_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[​](#cleanup "Direct link to Cleanup")

After the Green environment is verified and stable, you can:

1. Remove the `traffic-split` plugin from the route.
2. Update the service's default upstream to point to the Green nodes.
3. Decommission the old Blue environment.

## Conditional Blue-Green Switch[​](#conditional-blue-green-switch "Direct link to 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: green` are routed to the Green upstream.
* All other requests continue to the default (Blue) upstream.

## Next Steps[​](#next-steps "Direct link to Next Steps")

* [Canary Release](https://docs.api7.ai/api7-gateway/how-to-guides/traffic-management/canary-release.md): Gradually shift traffic between versions.
* [Health Check](https://docs.api7.ai/api7-gateway/how-to-guides/traffic-management/health-check.md): Monitor upstream health during deployments.
* [Fault Injection](https://docs.api7.ai/api7-gateway/how-to-guides/traffic-management/fault-injection.md): Test resilience during deployment transitions.
