Bring your own IP addresses with external subnets

This page describes how to create additional subnets in your organization's Data Network Segment to support your external networking requirements. You must add subnets to make sure your external services, such as egress network address translation (NAT) and external load balancers, have a sufficient number of IP addresses to support their networking requirements for connecting to external networks outside your organization.

There are several tasks outlined on this page, which are not intended to be completed in order:

For an overview of subnets and their concepts before you complete the tasks in this page, see Subnets and IP addresses.

This page is for network administrators within the platform administrator group and application developers within the application operator group, who are responsible for managing network traffic for their organization. For more information, see Audiences for GDC air-gapped documentation.

Before you begin

To get the permission that you need to create subnets, ask your Organization IAM Admin to grant you the Subnet Organization Admin (subnet-org-admin) IAM role. This role is not bound to a namespace.

Create a zonal branch subnet for external services

You can create a zonal external subnet from the zone's existing zonal root subnet to further subdivide IP addresses in your zonal Data Network Segment. You must create this subnet type in the platform namespace. If the parent zonal root subnet does not have enough IP addresses available, allocate another zonal subnet from the global IP address range first and then return to this procedure.

  • In a terminal window, create the new external subnet in the zonal management API server:

    kubectl -kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG apply -f - <<EOF apiVersion: ipam.gdc.goog/v1 kind: Subnet metadata:  labels:  ipam.gdc.goog/network-segment: data  name: SUBNET_NAME  namespace: platform spec:  ipv4Request:  prefixLength: CIDR_PREFIX_LENGTH  networkSpec:  enableGateway: true  enableVLANID: false  parentReference:  name: PARENT_SUBNET_NAME  namespace: platform  type: Branch EOF 

    Replace the following:

    • MANAGEMENT_API_SERVER_KUBECONFIG: the path to the kubeconfig file of your management API server. For more information, see Zonal management API server resources.

    • SUBNET_NAME: the name of your new network subnet.

    • CIDR_PREFIX_LENGTH: the CIDR prefix length of the new subnet that is dynamically allocated, such as 20. To statically set the CIDR, replace the prefixLength field with the cidr field, and then set the CIDR block, such as 10.0.10.0/27.

    • PARENT_SUBNET_NAME: the name of the parent subnet, such as data-external-zone0-cidr. The parent subnet is typically a zonal root subnet in the Data Network Segment.

    See the API reference documentation for the Subnet resource for more information.

    You can continue to subdivide your zonal subnets, or create a leaf subnet to allocate an individual IP address directly to an external service.

Create a leaf subnet for an individual service

You must create a leaf subnet to allocate a single IP address for your service. This leaf subnet must have the field value type: Leaf and must reside in the same project namespace as your external service, such as an external load balancer or egress NAT.

Your leaf subnet must be configured with a prefixLength value of 32, as it's intended to allocate a single IP address. The parentReference value references a previously allocated subnet, such as the parent zonal subnet you created in Create a zonal branch subnet for workloads.

  • In a terminal window, create the leaf subnet in the management API server:

    kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG apply -f - <<EOF apiVersion: ipam.gdc.goog/v1 kind: Subnet metadata:  labels:  ipam.gdc.goog/allocation-preference: default  ipam.gdc.goog/network-segment: data  name: SUBNET_NAME  namespace: PROJECT_NAMESPACE spec:  ipv4Request:  prefixLength: 32  parentReference:  name: PARENT_SUBNET  namespace: platform  type: Leaf EOF 

    Replace the following:

    • MANAGEMENT_API_SERVER_KUBECONFIG: the path to the kubeconfig file of your management API server. For more information, see Zonal management API server resources.
    • SUBNET_NAME: the name for the leaf subnet.
    • PROJECT_NAMESPACE: the project namespace corresponding to your project where your services are located.
    • PARENT_SUBNET: the name of the parent subnet that this leaf subnet will source its IP address from.

Your individual IP address is now available to be used by your external service. For more information on how to configure the IP address for your service, see the corresponding service documentation, such as Configure external load balancers.

Allocate zonal subnet from global IP address range

If your zone does not provide sufficient IP addresses for your external services from the existing zonal root subnet IP address range, you can allocate additional IP addresses from the global IP address root range.

Complete the following steps for the Data Network Segment in the platform namespace:

  1. In a terminal window, describe all of the Data Network Segment's root subnets and check their available CIDRs:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG describe subnets --namespace platform \  --label ipam.gdc.goog/network-segment=data,ipam.gdc.goog/usage=network-root-range 

    Replace GLOBAL_API_SERVER_KUBECONFIG with the path to the kubeconfig file of the global API server. For more information, see Global API server resources. The labels are constant and must remain the same.

    The output is similar to the following:

    Name: data-external-root-cidr Namespace: platform Labels: ipam.gdc.goog/allocation-preference=default ipam.gdc.goog/subnet-group=data-external-root-group ipam.gdc.goog/usage=network-root-range ipam.gdc.goog/network-segment=data Annotations: <none> API Version: ipam.global.gdc.goog/v1 Kind: Subnet Metadata: Creation Timestamp: 2025-06-18T23:05:38Z Finalizers: global-subnet-finalizer Generation: 1 Resource Version: 439434 UID: 5ed1c51a-b5ee-473e-a185-8e065a87ae8f Spec: ipv4Request: Cidr: 10.252.0.0/14 Propagation Strategy: None Type: Root Status: Children Refs: Name: data-external-zone1-root-cidr Namespace: platform Type: SingleSubnet Conditions: Last Transition Time: 2025-06-18T23:05:38Z Message: IP allocation finished successfully Observed Generation: 1 Reason: AllocationSucceeded Status: True Type: Ready ipv4Allocation: Available CIDRs: 10.254.0.0/15 10.253.0.0/16 Cidr: 10.252.0.0/14 Events: <none> 

    Note the Status.ipv4Allocation.Available CIDRs values as the available CIDRs, which will be referenced in the next step. In the previous output, the CIDR ranges 10.254.0.0/15 and 10.253.0.0/16 are available. There can be multiple subnets in your output depending on the number of root subnets you have, so note all the available CIDRs, and note from which subnet the available CIDR is from.

  2. Compare the largest available CIDR you noted from the previous step with the size of the CIDR you need to allocate to your zone. If the largest available CIDR is not large enough to allocate your new subnet, add a new network root range global subnet before you continue. Note the parent subnet from which you decide to get the CIDR for your new subnet.

    For example, if you require a /13 CIDR, but the available CIDRs only include /15 and /16, you must create a new network root range global subnet. If you require a /15 subnet, you can allocate a new zonal subnet from the existing /15 CIDR.

  3. Create the new subnet in the global API server:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG apply -f - <<EOF apiVersion: ipam.global.gdc.goog/v1 kind: Subnet metadata:  labels:  ipam.gdc.goog/network-segment: data  ipam.gdc.goog/usage: zone-network-root-range  name: SUBNET_NAME  namespace: platform spec:  ipv4Request:  prefixLength: CIDR_PREFIX_LENGTH  zone: ZONE_NAME  propagationStrategy: SingleZone  type: Branch  parentReference:  name: PARENT_SUBNET_NAME  namespace: ORG_NAME EOF 

    Replace the following:

    • GLOBAL_API_SERVER_KUBECONFIG: the path to the kubeconfig file of the global API server. For more information, see Global API server resources.
    • SUBNET_NAME: the name of the new subnet.
    • CIDR_PREFIX_LENGTH: the CIDR prefix length of the new subnet that is dynamically allocated, such as 20. To statically set the CIDR, replace the prefixLength field with the cidr field, and then set the CIDR block, such as 10.0.10.0/27.
    • ZONE_NAME: the zone for which to allocate the subnet, such as zone1.
    • PARENT_SUBNET_NAME: the name of the parent subnet, such as data-external-root-cidr, or the new network root range global subnet you created.
    • ORG_NAME: the name of the organization.

    See the API reference documentation for the global Subnet resource for more information.

  4. Verify the subnet is ready and available in the global API server by checking that its status Ready type is true:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG get subnet --namespace platform \  SUBNET_NAME --output jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 

    The output is similar to the following:

    status: conditions: - lastTransitionTime: "2025-06-06T07:28:48Z" message: IP allocation finished successfully observedGeneration: 1 reason: AllocationSucceeded status: "True" type: Ready 
  5. Verify the zonal subnet is created in the zonal management API server, and its status Ready type is true:

    kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG get subnet --namespace platform \  SUBNET_NAME --output jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 

    Replace MANAGEMENT_API_SERVER_KUBECONFIG with the path to the kubeconfig file of your management API server. For more information, see Zonal management API server resources.

    The output is similar to the following:

    status: conditions: - lastTransitionTime: "2025-06-06T07:29:34Z" message: IP allocation finished successfully observedGeneration: 1 reason: AllocationSucceeded status: "True" type: Ready 

    From this new zonal subnet, you can create more zonal child subnets or allocate an individual IP address directly to an external service.

Divide root global subnet without zone allocation

If you want to continue organizing your globally accessible IP address range from the global root subnet without allocating the IP addresses to your zonal external services, create a global subnet and don't define a propagation strategy in the Subnet custom resource.

Complete the following steps in the platform namespace to divide your global root subnet within the global scope only:

  1. In a terminal window, describe all of the Data Network Segment's root subnets and check their available CIDRs:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG describe subnets --namespace platform \  --label ipam.gdc.goog/network-segment=data,ipam.gdc.goog/usage=network-root-range 

    Replace GLOBAL_API_SERVER_KUBECONFIG with the path to the kubeconfig file of the global API server. For more information, see Global API server resources. The labels are constant and must remain the same.

    The output is similar to the following:

    Name: data-external-root-cidr Namespace: platform Labels: ipam.gdc.goog/allocation-preference=default ipam.gdc.goog/subnet-group=data-external-root-group ipam.gdc.goog/usage=network-root-range ipam.gdc.goog/network-segment=data Annotations: <none> API Version: ipam.global.gdc.goog/v1 Kind: Subnet Metadata: Creation Timestamp: 2025-06-18T23:05:38Z Finalizers: global-subnet-finalizer Generation: 1 Resource Version: 439434 UID: 5ed1c51a-b5ee-473e-a185-8e065a87ae8f Spec: ipv4Request: Cidr: 10.252.0.0/14 Propagation Strategy: None Type: Root Status: Children Refs: Name: data-external-zone1-root-cidr Namespace: platform Type: SingleSubnet Conditions: Last Transition Time: 2025-06-18T23:05:38Z Message: IP allocation finished successfully Observed Generation: 1 Reason: AllocationSucceeded Status: True Type: Ready ipv4Allocation: Available CIDRs: 10.254.0.0/15 10.253.0.0/16 Cidr: 10.252.0.0/14 Events: <none> 

    Note the Status.ipv4Allocation.Available CIDRs values as the available CIDRs, which will be referenced in the next step. In the previous output, the CIDR ranges 10.254.0.0/15 and 10.253.0.0/16 are available. There can be multiple subnets in your output depending on the number of root subnets you have, so note all the available CIDRs, and note from which subnet the available CIDR is from.

  2. Compare the largest available CIDR you noted from the previous step with the size of the CIDR you need to allocate to your new global subnet. If the largest available CIDR is not large enough to allocate your new subnet, add a new network root range global subnet before you continue. Note the parent subnet from which you decide to get the CIDR for your new subnet.

    For example, if you require a /13 CIDR, but the available CIDRs only include /15 and /16, you must create a new network root range global subnet. If you require a /15 subnet, you can allocate the new global subnet from the existing /15 CIDR.

  3. Create the new subnet in the global API server:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG apply -f - <<EOF apiVersion: ipam.global.gdc.goog/v1 kind: Subnet metadata:  labels:  ipam.gdc.goog/network-segment: data  ipam.gdc.goog/usage: zone-network-root-range  name: SUBNET_NAME  namespace: platform spec:  ipv4Request:  prefixLength: CIDR_PREFIX_LENGTH  propagationStrategy: None  type: Branch  parentReference:  name: PARENT_SUBNET_NAME  namespace: ORG_NAME EOF 

    Replace the following:

    • GLOBAL_API_SERVER_KUBECONFIG: the path to the kubeconfig file of the global API server. For more information, see Global API server resources.
    • SUBNET_NAME: the name of the new subnet.
    • CIDR_PREFIX_LENGTH: the CIDR prefix length of the new subnet that is dynamically allocated, such as 20. To statically set the CIDR, replace the prefixLength field with the cidr field, and then set the CIDR block, such as 10.0.10.0/27.
    • PARENT_SUBNET_NAME: the name of the parent subnet, such as data-external-root-cidr, or the new network root range global subnet you created.
    • ORG_NAME: the name of the organization.

    See the API reference documentation for the global Subnet resource for more information.

  4. Verify the subnet is ready and available in the global API server by checking that its status Ready type is true:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG get subnet --namespace platform \  SUBNET_NAME --output jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 

    The output is similar to the following:

    status: conditions: - lastTransitionTime: "2025-06-06T07:28:48Z" message: IP allocation finished successfully observedGeneration: 1 reason: AllocationSucceeded status: "True" type: Ready 

The new global subnet for your organization in the Data Network Segment is available. You can create a subnet for a particular zone from this new global parent subnet.

Add new network root range global subnet

Global subnets with the ipam.gdc.goog/usage: network-root-range label host the CIDR for all the zones of the network. If the CIDR is used up, you must create a new network root range subnet in the global API server. You can create multiple root global subnets, if needed.

To create a new network root range subnet, complete the following:

  • In a terminal window, create the new network root range global subnet for the Data Network Segment in the platform namespace:

    kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG apply -f - <<EOF apiVersion: ipam.global.gdc.goog/v1 kind: Subnet metadata:  labels:  ipam.gdc.goog/network-segment: data  ipam.gdc.goog/usage: network-root-range  name: SUBNET_NAME  namespace: platform spec:  ipv4Request:  cidr: NEW_CIDR  type: Root EOF 

    Replace the following:

    • GLOBAL_API_SERVER_KUBECONFIG: the path to the kubeconfig file of the global API server. For more information, see Global API server resources.
    • SUBNET_NAME: the name of the new subnet.
    • NEW_CIDR: the new CIDR for the subnet. This CIDR cannot overlap with any CIDR in all the existing subnets with the ipam.gdc.goog/usage: network-root-range label in the same global API server.

This new global root range subnet can be subdivided within the global API server or allocated to a specific zone.

What's next