Provisioning XPN

This page describes how to provision cross-project networking (XPN) for your projects. XPN allows you to share networks across different projects that belong to the same Cloud Organization. You provision an XPN host project that owns the network you want to share, and then associate service projects that will use the network.

To learn more about XPN, read XPN Overview.

XPN Beta limitations

  • Quota of 100 XPN host projects per Cloud Organization.
  • Quota of 100 service projects attached to any given XPN host project.
  • External load balancing is not supported across projects. This means that the frontend of a load balancer must exist in the same project as the backends, but the backend instances in service projects can be created in the shared network of the XPN host project.
  • GKE clusters in a service project associated with an XPN network are not supported.
  • GAE Flexible in a service project associated with an XPN network is not supported.
  • Deployment manager is limited to manage resources within a single project.


To provision XPN, specific administrators must configure XPN at the respective levels:

  • An Organization admin is the ultimate administrator of the root of the hierarchy where projects live (the Cloud Organization node). An Organization admin nominates an XPN admin.
  • A XPN admin is responsible for choosing the project that will host the shared resources and the service projects in the Organization that can use the XPN host project.
  • A Service project admin is the administrator of a service project that uses the XPN shared network.
XPN provisioning steps (click to enlarge)
XPN provisioning steps (click to enlarge)

Nominating XPN admins for the Organization

The Organization admin must run these commands.

The Organization admin nominates one or more XPN admins for the Organization. The XPN admin is responsible of setting a project as the XPN host project that will host the shared networking resources. More than one XPN host project can exist per Organization, but each service project can only be associated to a single XPN host project. The XPN admin role is granted by the Organization admin using a binding at the Organization level. You cannot bind the XPN admin role to a project.

Refer to the IAM documentation for more information. The Organization admin can grant XPN admin role at an Organization level to a user via the Google Cloud Platform Console.

You can also grant this permission using the gcloud command-line tool:

  1. Find your Organization ID.

    gcloud organizations list

  2. Apply XPN admin role to a member.

    gcloud organizations add-iam-policy-binding [ORG_ID] \
        --member 'user:[EMAIL_ADDRESS]' \
        --role "roles/compute.xpnAdmin"

Configuring and enabling an XPN host project

The XPN admin must run this command.

The nominated XPN admin either creates a new XPN host project or selects an already created project of which they are already an owner.

  1. Enable a project as the XPN host project that will share networking resources.

    gcloud beta compute xpn enable [XPN_HOST_PROJECT_ID]

  2. Confirm that the project is enabled.

    gcloud beta compute xpn organizations list-host-projects [ORG_ID]

When a project is enabled as an XPN host project, this project is automatically marked as being important and not easily deleted. GCP automatically creates a "lien," or lock, on projects designated as XPN host projects. This prevents the project from being deleted while it is still an XPN host project. However, the host project owner can still delete the lien and delete the project.

If a project is disabled as an XPN host project, then GCP removes the lien automatically. The lien protects against deleting the host project while it is a host project.

We strongly recommend that the Organization admin sets up an Org policy such that removing the lien requires Org admin permissions.

Protecting an XPN Host project against deletion

The steps in this section must be completed by the Organization policy admin. These steps only need to be done once. The Organization policy applies to existing and future XPN host projects.

In order to safeguard against outages from accidental project deletion, a lien is automatically placed on any project that is enabled as an XPN host project. A lien is basically a lock that prevents project deletion unless a project owner first removes the lien. The lien is automatically removed when the project is deprovisioned as an XPN host project.

However, by default, this lien can be removed by the XPN host project owner unless an organization-level policy is created to prevent it. You should create such a policy to ensure an additional level of insurance against outage.

The following script sets an organization policy so that only Organization owners or users with the organization-level resourcemanager.lienModifier role can delete the XPN host project lien.

You must have the roles/orgpolicy.policyAdmin role for your Organization.

  1. Copy the following script into a file called
  2. Determine your Organization ID.

    gcloud organizations list

  3. When you run it, pass in the Organization ID and either true or false as parameters. true activates the policy. false disables the policy. [ORG_ID] true

# A script which updates XPN project liens removal organization policy.
# When the policy is enforced, project owners will not be able to remove XPN liens from
# XPN host projects, only organization owners or users with resourcemanager.lienModifier
# role granted at organization level can.


function get_auth_code {
  local scope=''
  local auth_base_url=''
  local redirect_uri='urn:ietf:wg:oauth:2.0:oob'
  local auth_url="$auth_base_url?client_id=$client_id&scope=$scope&response_type=code&redirect_uri=$redirect_uri"

  echo "Please go to: $auth_url"
  echo "After accepting, enter the code you are given:"
  read auth_code

function get_creds_json {
  curl -s "" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "code=$1" \
      -d "client_id=$client_id" \
      -d "client_secret=$client_secret" \
      -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob" \
      -d "grant_type=authorization_code"

function get_access_token_json {
  curl -s "" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "refresh_token=$refresh_token" \
      -d "client_id=$client_id" \
      -d "client_secret=$client_secret" \
      -d "grant_type=refresh_token"

function set_org_policy {
  echo "Setting enforcement of constraint 'compute.restrictXpnProjectLienRemoval' to '${policy_value}' for organization ${organization_id}."
  echo "Response:"
  curl -s "${organization_id}:setOrgPolicy" \
      -X POST \
      -H "Authorization: Bearer $access_token" \
      -H "Content-Type: application/json" \
      -d "{policy:{constraint:\"constraints/compute.restrictXpnProjectLienRemoval\",boolean_policy:{enforced:${policy_value}}}}"

function parse_json {
  grep -e ':' "$1" \
    | sed -e 's/\s*//g' -e 's/"//g' -e 's/,//g' \
    | grep "$2" \
    | awk -F: '{print $2}'

function main {
  (( $# >= 2 )) || { echo "Usage: $(basename $0)  "; exit 1; }


  creds_json=$(get_creds_json $auth_code)
  [[ -n "$creds_json" ]] || { echo "Failed to get credentials json."; exit 2; }
  refresh_token=$(parse_json <(echo "$creds_json") "refresh_token")
  [[ -n "$refresh_token" ]] || { echo "Failed to parse refresh token in json."; exit 3; }
  access_token_json=$(get_access_token_json $refresh_token)
  [[ -n "$access_token_json" ]] || { echo "Failed to get access token json."; exit 4; }
  access_token=$(parse_json <(echo "$access_token_json") "access_token")
  [[ -n "$access_token" ]] || { echo "Failed to parse access token in json."; exit 5; }

main "$@"

Creating XPN networks and associating service projects

The XPN Admin can either create new networking resources in the XPN host project or share networking resources that already exist. Networking resources include the virtual networks/subnetworks to be shared and the associated routes, firewall rules, and VPNs. You can create networking resources via existing networking operations.

  1. Make project [XPN_SERVICE_PROJECT_ID] a service project of host project [XPN_HOST_PROJECT_ID].

    gcloud beta compute xpn associated-projects add [XPN_SERVICE_PROJECT_ID] \
    --host-project [XPN_HOST_PROJECT_ID]

  2. Confirm that the service project has been associated with the host project.

    gcloud beta compute xpn get-host-project [XPN_SERVICE_PROJECT_ID]]

Use IAM to give specific accounts permission to create instances and other resources in the shared networks. There are two different ways of doing this, depending on the control required in the use of subnetworks:

Applying the compute.networkUser role at XPN host project level

This command provide users of the service project with permission to use all the existing and future subnetworks in a XPN host project. This is done by providing all the required users/principals with the NetworkUser role at XPN host project level.

gcloud projects add-iam-policy-binding [XPN_HOST_PROJECT_ID] \
    --member "" \
    --role "roles/compute.networkUser"

If there are service accounts in the service projects that require NetworkUser permission in XPN host project, for example, service accounts to create instances in a Managed Instance Group associated to a XPN network, you will need to repeat the command above for the service account.

For more information about how Managed Instance Group with service accounts work in XPN, please refer to Managed Instance Groups with service accounts in XPN.

Applying the compute.networkUser role at subnetwork level

Provide users with permission to use specific subnetworks in a XPN host project. This is done by providing all the required users/principals with NetworkUser role for specific subnets.

  1. Get the current JSON permissions file:

    gcloud beta compute networks subnets get-iam-policy [SUBNET_NAME] \
        --project [XPN_HOST_PROJECT_ID] \
        --format json

  2. Save it to a file called my-subnet-policy.json.

  3. Add the following binding:

      "bindings": [
         "members": [
            "role": "roles/compute.networkUser"
      "etag": "[ETAG_STRING]"

  4. Use the updated file to set the new policy.

    gcloud beta compute networks subnets set-iam-policy [SUBNET_NAME] my-subnet-policy.json \
        --project [XPN_HOST_PROJECT_ID]

Similarly, if there are service accounts in the service projects that require NetworkUser permission in specific subnetworks in the XPN host project, you add the service account using the above steps.

For more information about how Managed Instance Group with service accounts Managed Instance Groups with service accounts in XPN.

The recommendation is to provide NetworkUser role for a group, not for individual users, so that if a new user is added in the group, that user will automatically have the NetworkUser role. Similarly, if you want ANY user in your domain to be able to use XPN networks and automatically grant such permission to any new user within the domain, you can use member "Domain".

Discovering subnets that can be used. Creating resources.

These steps should be completed by a Service project admin. Service project admins can be project owners, editors, or users that have been granted the compute.instanceAdmin role.

  1. Discover which subnets you can use.

    gcloud alpha compute networks subnets list-usable

  2. Creates instances or instances templates in the shared subnets.

    Existing commands can address resources in projects other than the current one via fully qualified resource URLs. The fully qualified resource URL includes the XPN host project of the network or subnetwork resource.

Creating an instance in a shared subnet

This command creates an instance in a shared subnet.

gcloud compute instances create vm1 \
    --project [XPN_SERVICE_PROJECT_ID] \
    --subnet projects/[XPN_HOST_PROJECT_ID]/regions/[REGION]/subnetworks/[SUBNET] \
    --zone [ZONE]

Creating an instance template in the shared network

This command creates the template for the whole shared network, but can only be used in subnetworks where the user is authorized.

gcloud compute instance-templates create [NAME] \
    --project [XPN_SERVICE_PROJECT_ID] \
    --network projects/[XPN_HOST_PROJECT_ID]/global/networks/[NETWORK]

This command creates a template for instances within a specific shared subnet only.

gcloud compute instance-templates create [NAME] \
    --project [XPN_SERVICE_PROJECT_ID] \
    --subnet projects/[XPN_HOST_PROJECT_ID]/regions/us-central1/subnetworks/[SUBNET]

Creating an Internal load balancer forwarding rule

Creates a forwarding rule associated to a shared network subnet for one subnet only. When you create the Internal load balancing forwarding rule, you must specify the shared subnet as a fully or partially qualified URL.

This command is only part of setting up an Internal load balancer. The rest of the instructions are the same the normal case for setting up an Internal load balancer.

gcloud compute forwarding-rules create [NAME] \
    --project [XPN_SERVICE_PROJECT_ID] \
    --load-balancing-scheme internal \
    --region \
    --ports PORT,[PORT,…] \
    --backend-service [BACKEND_SERVICE_NAME] \
    --subnet projects/[XPN_HOST_PROJECT_ID]/regions/[REGION]/subnetworks/[SUBNET] \
    [--address] \

Managed instance groups with service accounts in XPN

Managed instance groups use service accounts to perform actions like instance creation. See Managed Instance Groups and IAM for details.

The XPN Admin must grant the service account [XPN_SERVICE_PROJECT_NUMBER] the compute.networkUser role for the XPN host project or for specific XPN subnetworks. This is done by setting an IAM policy at the XPN project level that binds the service account with the with compute.networkUser role.

  1. Get the host project number.

    gcloud projects describe [XPN_SERVICE_PROJECT_ID]

  2. Grant the service account the compute.networkUser role.

    gcloud projects add-iam-policy-binding [XPN_HOST_PROJECT_ID] \
        --member "serviceAccount:[XPN_SERVICE_PROJECT_NUMBER]" \
        --role "roles/compute.networkUser"

More generally, any service accounts that are used in operations that require network use will need to be given compute.networkUser role in the XPN host project. Any and all of the IAM roles can be given to the service account.

gcloud projects add-iam-policy-binding [XPN_HOST_PROJECT_ID] \
    --member "user:[USER_ID]@[XPN_SERVICE_PROJECT_ID]" \
    --role "roles/compute.networkUser"

For information on how to apply IAM policies to service accounts, see granting roles to service accounts.

What's next

Send feedback about...

Compute Engine Documentation