---
title: Virtual networks · Cloudflare Zero Trust docs
description: Virtual networks allow you to connect private networks that have overlapping IP ranges without creating conflicts for users or services. For example, an organization may want to expose two distinct virtual private cloud (VPC) networks which they consider to be "production" and "staging". However, if the two private networks happened to receive the same RFC 1918 IP assignment, there may be two different resources with the same IP address. By creating two separate virtual networks, you can deterministically route traffic to duplicative private addresses like 10.128.0.1/32 staging and 10.128.0.1/32 production. These virtual networks will appear as user-selectable options within the WARP client GUI.
lastUpdated: 2025-04-22T19:38:59.000Z
source_url:
  html: https://patricia-pcx17224-json-post-em.preview.developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/cloudflared/tunnel-virtual-networks/index.md
  md: https://patricia-pcx17224-json-post-em.preview.developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/cloudflared/tunnel-virtual-networks/
---

Virtual networks allow you to connect private networks that have overlapping IP ranges without creating conflicts for users or services. For example, an organization may want to expose two distinct virtual private cloud (VPC) networks which they consider to be "production" and "staging". However, if the two private networks happened to receive the same RFC 1918 IP assignment, there may be two different resources with the same IP address. By creating two separate virtual networks, you can deterministically route traffic to duplicative private addresses like `10.128.0.1/32` staging and `10.128.0.1/32` production. These virtual networks will appear as user-selectable options within the WARP client GUI.

## Use cases

Here are a few scenarios where virtual networks may prove useful:

* Manage production and staging environments that use the same address space.
* Manage acquisitions or mergers between organizations that use the same address space.
* Allow IT professional services to access their customer's network for various administration and management purposes.
* Allow developers or homelab users to deterministically route traffic through their home network to enforce additional security controls.
* Guarantee additional segmentation (beyond just policy enforcement) between networks and resources for security reasons, while keeping all configuration within a single Cloudflare account.

## Prerequisites

* [Install `cloudflared`](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/) on each private network.
* [Deploy the WARP client](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/) on user devices.

## Create a virtual network

The following example demonstrates how to add two overlapping IP routes to Cloudflare (`10.128.0.1/32` staging and `10.128.0.1/32` production).

* Dashboard

  To route overlapping IPs over virtual networks:

  1. First, create two unique virtual networks:

     1. In [Zero Trust](https://one.dash.cloudflare.com/), go to **Settings** > **WARP Client**.
     2. Find the **Virtual networks** setting and select **Manage**.
     3. Select **Create virtual network**.
     4. Name your virtual network `staging-vnet` and select **Save**.
     5. Repeat Steps 1a-1d to create another virtual network called `production-vnet`.

  2. Next, create a Cloudflare Tunnel for each private network:

     1. Go to **Networks** > **Tunnels**.
     2. Select **Create a tunnel**.
     3. Name your tunnel `Staging tunnel` and select **Save tunnel**.
     4. Install the connector within your staging environment.
     5. In the **Private Network** tab, add `10.128.0.1/32`.
     6. Select **Additional settings**. Under **Virtual networks**, select *staging-vnet*.
     7. Save the tunnel.
     8. Repeat Steps 2a-2g to create another tunnel called `Production tunnel`. Be sure to install the connector within your production environment and assign the route to *production-vnet*.

  We now have two overlapping IP addresses routed over `staging-vnet` and `production-vnet` respectively. You can use the Cloudflare WARP client to [switch between virtual networks](#connect-to-a-virtual-network).

* Terraform (v5)

  To route overlapping IPs over virtual networks:

  1. Add the following permission to your [`cloudflare_api_token`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/api_token):

     * `Cloudflare Tunnel Write`

  2. Create two unique virtual networks:

     ```tf
     resource "cloudflare_zero_trust_tunnel_cloudflared_virtual_network" "staging_vnet" {
       account_id = var.cloudflare_account_id
       name       = "staging-vnet"
       comment    = "Staging virtual network"
       is_default = false
     }


     resource "cloudflare_zero_trust_tunnel_cloudflared_virtual_network" "production_vnet" {
       account_id = var.cloudflare_account_id
       name       = "production-vnet"
       comment    = "Production virtual network"
       is_default = false
     }
     ```

  3. Create a Cloudflare Tunnel for each private network:

     ```tf
     resource "cloudflare_zero_trust_tunnel_cloudflared" "staging_tunnel" {
       account_id = var.cloudflare_account_id
       name       = "Staging tunnel"
       config_src = "cloudflare"
     }


     resource "cloudflare_zero_trust_tunnel_cloudflared" "production_tunnel" {
       account_id = var.cloudflare_account_id
       name       = "Production tunnel"
       config_src = "cloudflare"
     }
     ```

  4. Route `10.128.0.1/32` through `Staging tunnel` and assign it to `staging-vnet`. Route `10.128.0.1/32` through `Production tunnel` and assign it to `production-vnet`.

     ```tf
     resource "cloudflare_zero_trust_tunnel_cloudflared_route" "staging_tunnel_route" {
       account_id         = var.cloudflare_account_id
       tunnel_id          = cloudflare_zero_trust_tunnel_cloudflared.staging_tunnel.id
       network            = "10.128.0.1/32"
       comment            = "Staging tunnel route"
       virtual_network_id = cloudflare_zero_trust_tunnel_cloudflared_virtual_network.staging_vnet.id
     }


     resource "cloudflare_zero_trust_tunnel_cloudflared_route" "production_tunnel_route" {
       account_id         = var.cloudflare_account_id
       tunnel_id          = cloudflare_zero_trust_tunnel_cloudflared.production_tunnel.id
       network            = "10.128.0.1/32"
       comment            = "Production tunnel route"
       virtual_network_id = cloudflare_zero_trust_tunnel_cloudflared_virtual_network.production_vnet.id
     }
     ```

  5. [Get the token](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/remote-tunnel-permissions/#get-the-tunnel-token) for each tunnel.

  6. Using the tunnel tokens, run `Staging tunnel` in your staging environment and run `Production tunnel` in your production environment. Refer to [Install and run the tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel-api/#4-install-and-run-the-tunnel).

* Locally-managed tunnels

  To route overlapping IPs over virtual networks for [locally-managed tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/):

  1. Create a tunnel for each private network:

     1. Within your staging environment, authenticate `cloudflared`:

        ```sh
        cloudflared login
        ```

     2. Create a tunnel to connect your staging network to Cloudflare.

        ```sh
        cloudflared tunnel create staging-tunnel
        ```

     3. Within your production environment, authenticate `cloudflared`:

        ```sh
        cloudflared login
        ```

     4. Create a tunnel to connect your production network to Cloudflare.

        ```sh
        cloudflared tunnel create production-tunnel
        ```

  The following steps may be executed from any `cloudflared` instance.

  1. Create two unique virtual networks.

     ```sh
     cloudflared tunnel vnet add staging-vnet
     cloudflared tunnel vnet add production-vnet
     ```

  2. Before moving on, run the following command to verify that your newly created virtual networks are listed correctly:

     ```sh
     cloudflared tunnel vnet list
     ```

  Default virtual network

  All accounts come pre-configured with a virtual network named `default`. You can choose a new default by typing `cloudflared tunnel vnet update --default <virtual-network-name>`.

  1. Configure your tunnels with the IP/CIDR range of your private networks, and assign the tunnels to their respective virtual networks.

     ```sh
     cloudflared tunnel route ip add --vnet staging-vnet 10.128.0.3/32 staging-tunnel
     cloudflared tunnel route ip add --vnet production-vnet 10.128.0.3/32 production-tunnel
     ```

  2. Verify that the IP routes are listed correctly:

     ```sh
     cloudflared tunnel route ip list
     ```

     We now have two overlapping IP addresses routed over `staging-vnet` and `production-vnet` respectively.

     1. Within your staging environment, create a [configuration file](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/configuration-file/) for `staging-tunnel`. The configuration file will be structured as follows:

        ```txt
        tunnel: <Tunnel-UUID>
        credentials-file: /root/.cloudflared/credentials-file.json
        warp-routing:
           enabled: true
        ```

     2. Run your tunnel.

        ```sh
        cloudflared tunnel run staging-tunnel
        ```

     3. Within your production environment, repeat Steps 6 and 7 for `production-tunnel`.

     You can use now the Cloudflare WARP client to [switch between virtual networks](#connect-to-a-virtual-network).

## Delete a virtual network

* Dashboard

  To delete a virtual network:

  1. In [Zero Trust](https://one.dash.cloudflare.com/), go to **Networks** > **Tunnels** and ensure that no IP routes are assigned to the virtual network you are trying to delete. If your virtual network is in use, delete the route or reassign it to a different virtual network.

  2. Next, go to **Settings** > **WARP Client**.

  3. Find the **Virtual networks** setting and select **Manage**.

  4. Select the three-dot menu for your virtual network and select **Delete**.

  You can optionally delete the tunnel associated with your virtual network.

* Locally-managed tunnels

  To delete a virtual network for [locally-managed tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/):

  1. Delete all IP routes in the virtual network. For example,

     ```sh
     cloudflared tunnel route ip delete --vnet staging-vnet 10.128.0.3/32
     ```

  2. (Optional) Delete the tunnel associated with the virtual network.

     ```sh
     cloudflared tunnel delete staging-tunnel
     ```

  3. Delete the virtual network.

     ```sh
     cloudflared tunnel vnet delete staging-vnet
     ```

  You can verify that the virtual network was successfully deleted by typing `cloudflared tunnel vnet list`.

## Connect to a virtual network

### Windows, macOS, and Linux

1. Open the WARP client.
2. Go to **Settings** > **Gateway with WARP** > **Virtual Networks**.
3. Choose the virtual network you want to connect to, for example `staging-vnet`.

When you visit `10.128.0.3/32`, WARP will route your request to the staging environment.

### iOS, Android, and ChromeOS

1. Launch the Cloudflare One Agent app.
2. Go to **Advanced** > **Connection options** > **Virtual networks**.
3. Choose the virtual network you want to connect to, for example `staging-vnet`.

When you visit `10.128.0.3/32`, WARP will route your request to the staging environment.
