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