> ## Documentation Index
> Fetch the complete documentation index at: https://ngrok.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Switch Traffic Between Blue-Green Deployments

> Test two production environments, either for monolithic or microservices architectures, side-by-side with a testing header and instant rollouts/rollbacks.

export const domain_0 = undefined

Blue-green deployments make your release processes safer and less prone to error by using an API gateway to switch production traffic between a live environment (`blue`) and a new version (`green`).
You can route specific traffic to the green environment for final tests, and once you make the switch to green, you can roll back to blue if you find issues.

ngrok makes blue-green deployments easier by helping you:

* Specify in your Traffic Policy which environments are currently live and testing, and switch between them freely for each new blue-green deployment.
* Allow requests with specific headers to access your testing environment.
* Handle both <Tooltip tip="Whole-environment deployments are ideal for monolithic-ish architectures where services are coupled and need to be updated together.">**whole-environment**</Tooltip> and <Tooltip tip="Scoped deployments work better when your services are entirely decoupled and you can deploy them independently.">**scoped (service-specific)**</Tooltip>.

In this example, the `blue` deployment is your live deployment, while `green` is where you're testing new features.
You can also add an `x-deployment-version` header to requests to route requests to the testing deployment manually.

## 1. Create endpoints for your services

Start internal [Agent Endpoints](/gateway/agent-endpoints/), replacing `$PORT` based on where your service listens, for each of your services on the systems where they run.
You can also use one of the [SDKs](/agent-sdks/#example-usage) or the [Kubernetes Operator](/getting-started/kubernetes/ingress/).

```bash theme={null}
ngrok http $PORT --url https://service-blue.internal
ngrok http $PORT --url https://service-green.internal
```

## 2. Reserve a domain

Navigate to the [**Domains** section](https://dashboard.ngrok.com/domains) of the ngrok dashboard and click **New +** to reserve a free static domain like {<code>{domain_0}</code> || `https://your-service.ngrok.app`} or a [custom domain](/gateway/custom-domains/) you already own.

We'll refer to this domain as `$NGROK_DOMAIN` from here on out.

## 3. Create a Cloud Endpoint

Navigate to the [**Endpoints** section](https://dashboard.ngrok.com/endpoints?sortBy=updatedAt\&orderBy=desc) of the ngrok dashboard, then click **New +** and **Cloud Endpoint**.

In the **URL** field, enter the domain you just reserved to finish creating your [Cloud Endpoint](/gateway/cloud-endpoints/).

## 4. Add routing to your blue environment with Traffic Policy

While viewing your new Cloud Endpoint in the dashboard, copy the policy below and paste it into the Traffic Policy editor, depending on how you architected your services and deploy them.

<Tabs>
  <Tab title="Single service/whole-environment">
    ```yaml theme={null}
    on_http_request:
      - actions:
          - type: set-vars
            config:
              vars:
                live: blue
                test: green

      - expressions:
          - "req.headers.exists_one(x, x == 'x-deployment-version')"
          - "req.headers['x-deployment-version'].join(',') == ${vars.test}"
        actions:
          - type: forward-internal
            config:
              url: https://service-${vars.test}.internal

      - actions:
          - type: forward-internal
            config:
              url: https://service-${vars.live}.internal
    ```

    **What's happening here?**
    This policy first assigns `blue`/`green` values to the appropriate environment.
    It then plumbs those values into the rest of the policy so that you don't have to manually change your headers or internal URLs each time you do a blue-green deployment.

    The policy then checks whether the `x-deployment-version` header exists and its value equals the current `test` variable.
    If both are `true`, it routes the request to your test environment.

    The policy then sends all other requests to your current live environment.
  </Tab>

  <Tab title="Microservices/scoped deployment">
    In this example, you have `auth` and `accounts` microservices at the `/api/auth` and `/api/accounts` paths, respectively.
    You're blue-green deploying just the auth service at two internal endpoints: `https://auth-blue.internal` and `https://auth-green.internal`.

    ```yaml theme={null}
    on_http_request:
      - actions:
          - type: set-vars
            config:
              vars:
                live: blue
                test: green

      - expressions:
          - "req.path.startsWith('/api/auth')"
          - "req.headers.exists_one(x, x == 'x-deployment-version')"
          - "req.headers['x-deployment-version'].join(',') == ${vars.test}"
        actions:
          - type: forward-internal
            config:
              url: https://auth-${vars.test}.internal

      - expressions:
          - "req.path.startsWith('/api/auth')"
        actions:
          - type: forward-internal
            config:
              url: https://auth-${vars.live}.internal

      - expressions:
          - "req.path.startsWith('/api/accounts')"
        actions:
          - type: forward-internal
            config:
              url: https://accounts.internal
    ```

    **What's happening here?**
    This policy first assigns `blue`/`green` values to the appropriate environment.
    It then plumbs those values into the rest of the policy so that you don't have to manually change your headers or internal URLs each time you do a blue-green deployment.

    The policy then checks whether the request is to the `/api/auth` path, contains the `x-deployment-version` header, and the header's value equals the current `test` variable.
    If all are `true`, it routes the request to the test deployment of *just* your auth service.

    Next, the policy checks whether the request is to the `/api/auth` path, but without the header, and routes it to the live version.

    Finally, it routes requests to the `/api/accounts` path to that service independent of your ongoing blue-green rollout.
  </Tab>
</Tabs>

## 5. Switch services or environments over

Edit your policy again to switch your environments and their states, where `green` becomes live and `blue` is your new testing environment.

```yaml theme={null}
on_http_request:
  - actions:
      - type: set-vars
        config:
          vars:
            live: green
            test: blue
```

If you need to roll back, change the variables back to their original state.

## What's next?

* View your [Traffic
  Inspector](https://dashboard.ngrok.com/traffic-inspector) to see how your blue and green environments are behaving, particularly after making the switch, to know exactly when and why to roll back.
* Learn how to do [canary deployments](/gateway/examples/canary-deployments) with custom traffic splitting as a lower-cost, but more complex, alternative to blue-green.
* Explore other common gateway setups, like [multiplexing to many
  services](/gateway/examples/multiplex) or shipping a [custom "maintenance mode"](/gateway/examples/maintenance-mode/) during an outage or planned downtime a blue-green deployment can't help with.
* Start automating your deployment strategies with the ngrok [API](/api/) or the [Kubernetes Operator](/k8s/).
