Configure static external IP addresses

You can assign static external IP addresses to your virtual machine (VM) andbare metal instances. You can also change, list, and release static IP addressesfor your instances. To reserve a static external IP address, seeReserve a static external IP address.

External IP addresses can bestatic or ephemeral.If an instance requires a fixed external IP address that does not change, do thefollowing:

  1. Obtain a static external IP address. You can reserve new external IPaddresses or promote existing ephemeral external IP addresses.
  2. Assign the reserved IP address to an existing instance, or assign it whencreating a new instance.

If you require a static IP address on your internal Compute Enginenetwork, see insteadReserve a static internal IP address.

For information about reserving a static external IP address or creating aglobal external IP address, seeReserve a static external IP address.

Before you begin

Required roles

To get the permissions that you need to configure and manage static IP addresses, ask your administrator to grant you the following IAM roles on your project:

For more information about granting roles, seeManage access to projects, folders, and organizations.

These predefined roles contain the permissions required to configure and manage static IP addresses. To see the exact permissions that are required, expand theRequired permissions section:

Required permissions

The following permissions are required to configure and manage static IP addresses:

  • compute.instances.update on the instance
  • compute.instances.updateNetworkInterface on the instance
  • compute.instances.addAccessConfig on the instance
  • compute.instances.deleteAccessConfig on the instance
  • compute.networks.list on the network
  • compute.subnetworks.use on the subnet
  • compute.subnetworks.list on the subnet
  • To create instances:
    • compute.instances.create on the project
    • To use a custom image to create the VM:compute.images.useReadOnly on the image
    • To use a snapshot to create the VM:compute.snapshots.useReadOnly on the snapshot
    • To use an instance template to create the VM:compute.instanceTemplates.useReadOnly on the instance template
    • To assign alegacy network to the VM:compute.networks.use on the project
    • To specify a static IP address for the VM:compute.addresses.use on the project
    • To assign an external IP address to the VM when using a legacy network:compute.networks.useExternalIp on the project
    • To specify a subnet for the VM:compute.subnetworks.use on the project or on the chosen subnet
    • To assign an external IP address to the VM when using a VPC network:compute.subnetworks.useExternalIp on the project or on the chosen subnet
    • To set VM instance metadata for the VM:compute.instances.setMetadata on the project
    • To set tags for the VM:compute.instances.setTags on the VM
    • To set labels for the VM:compute.instances.setLabels on the VM
    • To set a service account for the VM to use:compute.instances.setServiceAccount on the VM
    • To create a new disk for the VM:compute.disks.create on the project
    • To attach an existing disk in read-only or read-write mode:compute.disks.use on the disk
    • To attach an existing disk in read-only mode:compute.disks.useReadOnly on the disk

You might also be able to get these permissions withcustom roles or otherpredefined roles.

Limitations

  • Only one resource at a time can use a static external IP address.

  • There is no way to check whether an IP address is static or ephemeral afterit has been assigned to a resource. You can compare the IP address againstthe list of static external IP addresses reserved to that project. Use thegcloud compute addresses list sub-commandto see a list of static external IP addresses available to theproject.

  • Each VM can have multiple network interfaces,and each interface can have the following IP addresses assignedaccording to itsstack type:

    • IPv4-only interfaces:
      • An internal IPv4 address (required)
      • An external IPv4 address (optional)
    • Dual-stack (IPv4 and IPv6) interfaces:
      • An internal IPv4 address (required)
      • An external IPv4 address (optional)
      • A/96 IPv6 address range, either internal or external, but not both (required)
    • IPv6-only interfaces:
      • A/96 IPv6 address range, either internal or external, but not both (required)
  • You can't unassign or change the external IPv6 address of a VM with anIPv6-only network interface. You can, however, promote an ephemeral externalIP address of a resource to a static external IP address so that the addressremains reserved even after the resource is deleted.

  • You cannot change the name of a static IP address.

Note: Network interfaces can receive traffic from multiple forwarding rules, which might serve other external IP addresses. Any number of external IP addresses can reference a network interface through these forwarding rules, but each network interface can be assigned only one external IPv4 address and one external/96 IPv6 address range.

For more information about load balancing and forwarding rules, read theload balancing documentation.

View available static external IP addresses

To list static external IP addresses that you have reserved for yourproject, follow these steps.

Console

  1. In the Google Cloud console, go to theIP addresses page.

    Go to IP addresses

  2. ClickExternal IP addresses.

gcloud

Use thegcloud compute addresses list command:

  • To list all IP addresses, use the following command:

    gcloud compute addresses list
  • To list all global IP addresses, use the following command:

    gcloud compute addresses list --global
  • To list all regional IP addresses in a given region, use the followingcommand:

    gcloud compute addresses list \    --regions=REGION

    ReplaceREGION with the region that you want tolist addresses for. You can list addresses of multiple regions byspecifying comma-separated region names:

    gcloud compute addresses list \    --regions=REGION1,REGION2,..REGION_n_

API

  • To list regional IPv4 or IPv6 addresses, call theaddresses.list method:

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/addresses

    Replace the following:

    • PROJECT_ID: the project ID for this request
    • REGION: the name of the region for thisrequest
  • To list all addresses in all regions, call theaddresses.aggregatedList method:

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/aggregated/addresses
  • To list global IPv4 or IPv6 addresses, call theglobalAddresses.list method:

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses

    Replace the following:

    PROJECT_ID: the project ID for this request

Go

import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1""google.golang.org/api/iterator""cloud.google.com/go/compute/apiv1/computepb")// listRegionalExternal retrieves list external IP addresses in Google Cloud Platform region.funclistRegionalExternal(wio.Writer,projectID,regionstring)([]*computepb.Address,error){// projectID := "your_project_id"// region := "europe-west3"ctx:=context.Background()// Create the service client.addressesClient,err:=compute.NewAddressesRESTClient(ctx)iferr!=nil{returnnil,err}deferaddressesClient.Close()// Build the request.req:=&computepb.ListAddressesRequest{Project:projectID,Region:region,}// List the addresses.it:=addressesClient.List(ctx,req)// Iterate over the results.varaddresses[]*computepb.Addressfor{address,err:=it.Next()iferr==iterator.Done{break}iferr!=nil{returnnil,err}addresses=append(addresses,address)}// Print the addresses.fmt.Fprint(w,"Fetched addresses: \n")for_,address:=rangeaddresses{fmt.Fprintf(w,"%s\n",*address.Name)}returnaddresses,nil}// listGlobalExternal retrieves list external global IP addresses in Google Cloud Platform.funclistGlobalExternal(wio.Writer,projectIDstring)([]*computepb.Address,error){// projectID := "your_project_id"ctx:=context.Background()// Create the service client.addressesClient,err:=compute.NewGlobalAddressesRESTClient(ctx)iferr!=nil{returnnil,err}deferaddressesClient.Close()// Build the request.req:=&computepb.ListGlobalAddressesRequest{Project:projectID,}// List the addresses.it:=addressesClient.List(ctx,req)// Iterate over the results.varaddresses[]*computepb.Addressfor{address,err:=it.Next()iferr==iterator.Done{break}iferr!=nil{returnnil,err}addresses=append(addresses,address)}// Print the addresses.fmt.Fprint(w,"Fetched addresses: \n")for_,address:=rangeaddresses{fmt.Fprintf(w,"%s\n",*address.Name)}returnaddresses,nil}

Java

importcom.google.cloud.compute.v1.Address;importcom.google.cloud.compute.v1.AddressesClient;importcom.google.cloud.compute.v1.GlobalAddressesClient;importcom.google.cloud.compute.v1.ListAddressesRequest;importcom.google.cloud.compute.v1.ListGlobalAddressesRequest;importcom.google.common.collect.Lists;importjava.io.IOException;importjava.util.List;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeoutException;publicclassListStaticExternalIp{publicstaticvoidmain(String[]args)throwsIOException,ExecutionException,InterruptedException,TimeoutException{// TODO(developer): Replace these variables before running the sample.// Project ID or project number of the Google Cloud project you want to use.StringprojectId="your-project-id";// Region where the VM and IP is located.Stringregion="your-region-id";listStaticExternalIp(projectId,region);}// Lists all static external IP addresses, either regional or global.publicstaticList<Address>listStaticExternalIp(StringprojectId,Stringregion)throwsIOException{// Use regional client if a region is specifiedif(region!=null){// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.try(AddressesClientclient=AddressesClient.create()){ListAddressesRequestrequest=ListAddressesRequest.newBuilder().setProject(projectId).setRegion(region).build();returnLists.newArrayList(client.list(request).iterateAll());}}else{// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.try(GlobalAddressesClientclient=GlobalAddressesClient.create()){ListGlobalAddressesRequestrequest=ListGlobalAddressesRequest.newBuilder().setProject(projectId).build();returnLists.newArrayList(client.list(request).iterateAll());}}}}

Python

fromtypingimportList,Optionalfromgoogle.cloud.compute_v1.services.addresses.clientimportAddressesClientfromgoogle.cloud.compute_v1.services.global_addressesimportGlobalAddressesClientfromgoogle.cloud.compute_v1.typesimportAddressdeflist_static_ip_addresses(project_id:str,region:Optional[str]=None)->List[Address]:"""    Lists all static external IP addresses, either regional or global.    Args:    project_id (str): project ID.    region (Optional[str]): The region of the IP addresses if regional. None if global.    Returns:    List[Address]: A list of Address objects containing details about the requested IPs.    """ifregion:# Use regional client if a region is specifiedclient=AddressesClient()addresses_iterator=client.list(project=project_id,region=region)else:# Use global client if no region is specifiedclient=GlobalAddressesClient()addresses_iterator=client.list(project=project_id)returnlist(addresses_iterator)# Convert the iterator to a list to return

Configure static external IP addresses

The following sections describe how to configure static external IP addressesfor your instances.

Create an instance that uses a static external IP address

After you havereserved a static external IP address,you can assign it to an instance.

Console

  1. In the Google Cloud console, go to theCreate an instance page.

    Go to Create an instance

  2. To assign a static external IP address to the instance, do the following:

    1. In the navigation menu, clickNetworking.

    2. In theNetwork interfaces section, specify the network interfacesthat you want for the instance by using the following options:

      • To add a network interface, clickAdd a network interface. Then,in theNetwork list, select a network.

      • To delete a network interface, clickDelete.

    3. Select one of the following options:

      • To assign a static external IPv4 address, do the following:

        1. Expand a network interface.
        2. Select the IP address from theExternal IPv4 address list.
      • To assign a static external IPv6 address, do the following:

        1. Expand a network interface that contains a subnet with anexternal IPv6 address range.
        2. Select that subnet from theSubnetwork list.
        3. ForIP stack type, selectIPv4 and IPv6 (dual-stack) orIPv6 (single-stack).
        4. Select the newly reserved external IPv6 address from theExternal IPv6 address list. Alternatively, selectReserve static external IPv6 address and reserve a newstatic external IPv6 address.
        5. ForNetwork Service Tier, selectPremium.
    4. To finish modifying the network interface, clickDone.

  3. Continue with the instance creation process.

gcloud

You can create an instance and assign a static regional external IP addressthat you have already reserved.

  • To assign a static external IPv4 address, do the following:

    gcloud compute instances createINSTANCE_NAME \    --zone=ZONE \    --address=IPV4_ADDRESS
  • To assign a static external IPv6 address, do the following:

    gcloud compute instances createINSTANCE_NAME \    --zone=ZONE \    --subnet=SUBNET \    --stack-type=STACK_TYPE \    --external-ipv6-address=IPV6_ADDRESS \    --external-ipv6-prefix-length=96 \    --ipv6-network-tier=PREMIUM

    Replace the following:

    • INSTANCE_NAME: the name of the compute instance.
    • ZONE: the zone to create the instance in
    • IPV4_ADDRESS: the IPv4 address to assign to the instance. Use the reserved static external IP address, not the address name.
    • SUBNET: a subnet that contains external IPv6addresses
    • STACK_TYPE: the stack type for the instance,eitherIPV4_IPV6 (dual-stack) orIPV6_ONLY
    • IPV6_ADDRESS: the IPv6 address to assign to the instance. Use the reserved static external IP address, not the address name.

Terraform

You can use thegoogle_compute_instance resourceto assign an external IP address.

resource "google_compute_instance" "default" {  name         = "dns-proxy-nfs"  machine_type = "n1-standard-1"  zone         = "us-central1-a"  boot_disk {    initialize_params {      image = "ubuntu-1404-trusty-v20160627"    }  }  network_interface {    network = "default"    access_config {      nat_ip = google_compute_address.default.address    }  }}

REST

  • To assign a static external IPv4 address to a new compute instance,do the following:

    In your request tocreate a new instance,explicitly provide thenetworkInterfaces[].accessConfigs[].natIPproperty and the external IPv4 address that you want to use, for example:

    {  "name": "INSTANCE_NAME",  "machineType": "zones/ZONE/machineTypes/MACHINE_TYPE",  "networkInterfaces": [{      "accessConfigs": [{        "type": "ONE_TO_ONE_NAT",        "name": "External NAT",        "natIP": "IPV4_ADDRESS"      }],      "network": "global/networks/default"  }],  "disks": [{      "autoDelete": "true",        "boot": "true",        "type": "PERSISTENT",        "initializeParams": {            "sourceImage": "SOURCE_IMAGE"         }  }]}

    Replace the following:

    • INSTANCE_NAME: the name of the computeinstance
    • ZONE: the zone to create the instance in
    • MACHINE_TYPE: Optional: a full or partialURL of the machine type resource to use when creating the instance,in the format:zones/ZONE/machineTypes/MACHINE_TYPE
    • IPV4_ADDRESS: the IPv4 address to assignto the instance. Use the reserved static external IP address,not the address name.
    • SOURCE_IMAGE: a specific version of a publicimage, such asprojects/debian-cloud/global/images/debian-10-buster-v20200309or an image family, such asprojects/debian-cloud/global/images/family/debian-10
  • To assign a static external IPv6 address to a new instance, do thefollowing:

    In your request tocreate a new instance,explicitly provide thenetworkInterfaces[].ipv6AccessConfigs[].externalIpv6property and the external IPv6 address that you want to use, for example:

    {  "name": "INSTANCE_NAME",  "machineType": "zones/ZONE/machineTypes/MACHINE_TYPE",  "networkInterfaces": [{          "ipv6AccessConfigs": [{         "externalIpv6": "IPV6_ADDRESS",         "externalIpv6PrefixLength": 96,         "name": "external-ipv6-access-config",         "networkTier": "PREMIUM",         "type": "DIRECT_IPV6"          }],      "stackType": "STACK_TYPE",      "subnetwork":"SUBNETWORK"  }],  "disks": [{      "autoDelete": "true",      "boot": "true",      "mode": "READ_WRITE",      "type": "PERSISTENT",      "initializeParams": {          "sourceImage": "SOURCE_IMAGE"      },  }],}

    Replace the following:

    • INSTANCE_NAME: the name of the computeinstance
    • ZONE: the zone to create the instance in
    • MACHINE_TYPE: Optional: a full or partial URLof the machine type resource to use when creating the instance, inthe format:zones/ZONE/machineTypes/MACHINE_TYPE
    • IPV6_ADDRESS: the IPv6 address to assign tothe instance. Use the reserved static external IP address,not the address name.
    • STACK_TYPE: the stack type for the instance, eitherIPV4_IPV6 (dual-stack) orIPV6_ONLY
    • SUBNET: a subnet that contains external IPv6addresses
    • SOURCE_IMAGE: a specific version of a publicimage, such as"projects/debian-cloud/global/images/debian-10-buster-v20200309"or an image family, such as"projects/debian-cloud/global/images/family/debian-10"

Go

// assignStaticExternalToNewVM creates a new VM instance and assigns a static external IP address to it.// NOTE: ip address is expected to exist and be located in the same region as new VMfuncassignStaticExternalToNewVM(wio.Writer,projectID,zone,instanceName,ipAddressstring)error{// projectID := "your_project_id"// zone := "europe-central2-b"// instanceName := "your_instance_name"// ipAddress := 301.222.11.123ctx:=context.Background()instancesClient,err:=compute.NewInstancesRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewInstancesRESTClient: %w",err)}deferinstancesClient.Close()imagesClient,err:=compute.NewImagesRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewImagesRESTClient: %w",err)}deferimagesClient.Close()// List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details.newestDebianReq:=&computepb.GetFromFamilyImageRequest{Project:"debian-cloud",Family:"debian-12",}newestDebian,err:=imagesClient.GetFromFamily(ctx,newestDebianReq)iferr!=nil{returnfmt.Errorf("unable to get image from family: %w",err)}req:=&computepb.InsertInstanceRequest{Project:projectID,Zone:zone,InstanceResource:&computepb.Instance{Name:proto.String(instanceName),Disks:[]*computepb.AttachedDisk{{InitializeParams:&computepb.AttachedDiskInitializeParams{DiskSizeGb:proto.Int64(10),SourceImage:newestDebian.SelfLink,DiskType:proto.String(fmt.Sprintf("zones/%s/diskTypes/pd-standard",zone)),},AutoDelete:proto.Bool(true),Boot:proto.Bool(true),Type:proto.String(computepb.AttachedDisk_PERSISTENT.String()),},},MachineType:proto.String(fmt.Sprintf("zones/%s/machineTypes/n1-standard-1",zone)),NetworkInterfaces:[]*computepb.NetworkInterface{{AccessConfigs:[]*computepb.AccessConfig{{Type:proto.String(computepb.AccessConfig_ONE_TO_ONE_NAT.String()),Name:proto.String("External NAT"),NetworkTier:proto.String(computepb.AccessConfig_PREMIUM.String()),NatIP:proto.String(ipAddress),},},},},},}op,err:=instancesClient.Insert(ctx,req)iferr!=nil{returnfmt.Errorf("unable to create instance: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Static address %s assigned to new VM",ipAddress)returnnil}

Java

importcom.google.cloud.compute.v1.AccessConfig;importcom.google.cloud.compute.v1.AccessConfig.Type;importcom.google.cloud.compute.v1.Address.NetworkTier;importcom.google.cloud.compute.v1.AttachedDisk;importcom.google.cloud.compute.v1.AttachedDiskInitializeParams;importcom.google.cloud.compute.v1.GetInstanceRequest;importcom.google.cloud.compute.v1.ImagesClient;importcom.google.cloud.compute.v1.InsertInstanceRequest;importcom.google.cloud.compute.v1.Instance;importcom.google.cloud.compute.v1.InstancesClient;importcom.google.cloud.compute.v1.NetworkInterface;importjava.io.IOException;importjava.util.UUID;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassAssignStaticExternalNewVmAddress{publicstaticvoidmain(String[]args)throwsIOException,ExecutionException,InterruptedException,TimeoutException{// TODO(developer): Replace these variables before running the sample.// Project ID or project number of the Google Cloud project you want to use.StringprojectId="your-project-id";// Instance ID of the Google Cloud project you want to use.StringinstanceId="your-instance-id";// Name of the zone to create the instance in. For example: "us-west3-b"Stringzone="your-zone-id";// machine type of the VM being created. This value uses the// following format: "zones/{zone}/machineTypes/{type_name}".// For example: "zones/europe-west3-c/machineTypes/f1-micro"StringmachineType=String.format("zones/%s/machineTypes/{your-machineType-id}",zone);// boolean flag indicating if the instance should have an external IPv4 address assigned.booleanexternalAccess=true;// external IPv4 address to be assigned to this instance. If you specify// an external IP address, it must live in the same region as the zone of the instance.// This setting requires `external_access` to be set to True to work.StringexternalIpv4="your-externalIpv4-id";assignStaticExternalNewVmAddress(projectId,instanceId,zone,externalAccess,machineType,externalIpv4);}// Create a new VM instance with assigned static external IP address.publicstaticInstanceassignStaticExternalNewVmAddress(StringprojectId,StringinstanceName,Stringzone,booleanexternalAccess,StringmachineType,StringexternalIpv4)throwsIOException,ExecutionException,InterruptedException,TimeoutException{StringsourceImage;// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.try(ImagesClientimagesClient=ImagesClient.create()){sourceImage=imagesClient.getFromFamily("debian-cloud","debian-11").getSelfLink();}AttachedDiskattachedDisk=buildAttachedDisk(sourceImage,zone);returncreateInstance(projectId,instanceName,zone,attachedDisk,machineType,externalAccess,externalIpv4);}privatestaticAttachedDiskbuildAttachedDisk(StringsourceImage,Stringzone){AttachedDiskInitializeParamsinitializeParams=AttachedDiskInitializeParams.newBuilder().setSourceImage(sourceImage).setDiskSizeGb(10).setDiskType(String.format("zones/%s/diskTypes/pd-standard",zone)).build();returnAttachedDisk.newBuilder().setInitializeParams(initializeParams)// Remember to set auto_delete to True if you want the disk to be deleted// when you delete your VM instance..setAutoDelete(true).setBoot(true).build();}// Send an instance creation request to the Compute Engine API and wait for it to complete.privatestaticInstancecreateInstance(StringprojectId,StringinstanceName,Stringzone,AttachedDiskdisks,StringmachineType,booleanexternalAccess,StringexternalIpv4)throwsIOException,ExecutionException,InterruptedException,TimeoutException{// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.try(InstancesClientclient=InstancesClient.create()){InstanceinstanceResource=buildInstanceResource(instanceName,disks,machineType,externalAccess,externalIpv4);InsertInstanceRequestbuild=InsertInstanceRequest.newBuilder().setProject(projectId).setRequestId(UUID.randomUUID().toString()).setZone(zone).setInstanceResource(instanceResource).build();client.insertCallable().futureCall(build).get(60,TimeUnit.SECONDS);GetInstanceRequestgetInstanceRequest=GetInstanceRequest.newBuilder().setInstance(instanceName).setProject(projectId).setZone(zone).build();returnclient.get(getInstanceRequest);}}privatestaticInstancebuildInstanceResource(StringinstanceName,AttachedDiskdisk,StringmachineType,booleanexternalAccess,StringexternalIpv4){NetworkInterfacenetworkInterface=networkInterface(externalAccess,externalIpv4);returnInstance.newBuilder().setName(instanceName).addDisks(disk).setMachineType(machineType).addNetworkInterfaces(networkInterface).build();}privatestaticNetworkInterfacenetworkInterface(booleanexternalAccess,StringexternalIpv4){NetworkInterface.Builderbuild=NetworkInterface.newBuilder().setNetwork("global/networks/default");if(externalAccess){AccessConfig.BuilderaccessConfig=AccessConfig.newBuilder().setType(Type.ONE_TO_ONE_NAT.name()).setName("External NAT").setNetworkTier(NetworkTier.PREMIUM.name());if(externalIpv4!=null){accessConfig.setNatIP(externalIpv4);}build.addAccessConfigs(accessConfig.build());}returnbuild.build();}}

Python

from__future__importannotationsimportreimportsysfromtypingimportAnyimportwarningsfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defget_image_from_family(project:str,family:str)->compute_v1.Image:"""    Retrieve the newest image that is part of a given family in a project.    Args:        project: project ID or project number of the Cloud project you want to get image from.        family: name of the image family you want to get image from.    Returns:        An Image object.    """image_client=compute_v1.ImagesClient()# List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-detailsnewest_image=image_client.get_from_family(project=project,family=family)returnnewest_imagedefdisk_from_image(disk_type:str,disk_size_gb:int,boot:bool,source_image:str,auto_delete:bool=True,)->compute_v1.AttachedDisk:"""    Create an AttachedDisk object to be used in VM instance creation. Uses an image as the    source for the new disk.    Args:         disk_type: the type of disk you want to create. This value uses the following format:            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".            For example: "zones/us-west3-b/diskTypes/pd-ssd"        disk_size_gb: size of the new disk in gigabytes        boot: boolean flag indicating whether this disk should be used as a boot disk of an instance        source_image: source image to use when creating this disk. You must have read access to this disk. This can be one            of the publicly available images or an image from one of your projects.            This value uses the following format: "projects/{project_name}/global/images/{image_name}"        auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it    Returns:        AttachedDisk object configured to be created using the specified image.    """boot_disk=compute_v1.AttachedDisk()initialize_params=compute_v1.AttachedDiskInitializeParams()initialize_params.source_image=source_imageinitialize_params.disk_size_gb=disk_size_gbinitialize_params.disk_type=disk_typeboot_disk.initialize_params=initialize_params# Remember to set auto_delete to True if you want the disk to be deleted when you delete# your VM instance.boot_disk.auto_delete=auto_deleteboot_disk.boot=bootreturnboot_diskdefwait_for_extended_operation(operation:ExtendedOperation,verbose_name:str="operation",timeout:int=300)->Any:"""    Waits for the extended (long-running) operation to complete.    If the operation is successful, it will return its result.    If the operation ends with an error, an exception will be raised.    If there were any warnings during the execution of the operation    they will be printed to sys.stderr.    Args:        operation: a long-running operation you want to wait on.        verbose_name: (optional) a more verbose name of the operation,            used only during error and warning reporting.        timeout: how long (in seconds) to wait for operation to finish.            If None, wait indefinitely.    Returns:        Whatever the operation.result() returns.    Raises:        This method will raise the exception received from `operation.exception()`        or RuntimeError if there is no exception set, but there is an `error_code`        set for the `operation`.        In case of an operation taking longer than `timeout` seconds to complete,        a `concurrent.futures.TimeoutError` will be raised.    """result=operation.result(timeout=timeout)ifoperation.error_code:print(f"Error during{verbose_name}: [Code:{operation.error_code}]:{operation.error_message}",file=sys.stderr,flush=True,)print(f"Operation ID:{operation.name}",file=sys.stderr,flush=True)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefcreate_instance(project_id:str,zone:str,instance_name:str,disks:list[compute_v1.AttachedDisk],machine_type:str="n1-standard-1",network_link:str="global/networks/default",subnetwork_link:str=None,internal_ip:str=None,external_access:bool=False,external_ipv4:str=None,accelerators:list[compute_v1.AcceleratorConfig]=None,preemptible:bool=False,spot:bool=False,instance_termination_action:str="STOP",custom_hostname:str=None,delete_protection:bool=False,)->compute_v1.Instance:"""    Send an instance creation request to the Compute Engine API and wait for it to complete.    Args:        project_id: project ID or project number of the Cloud project you want to use.        zone: name of the zone to create the instance in. For example: "us-west3-b"        instance_name: name of the new virtual machine (VM) instance.        disks: a list of compute_v1.AttachedDisk objects describing the disks            you want to attach to your new instance.        machine_type: machine type of the VM being created. This value uses the            following format: "zones/{zone}/machineTypes/{type_name}".            For example: "zones/europe-west3-c/machineTypes/f1-micro"        network_link: name of the network you want the new instance to use.            For example: "global/networks/default" represents the network            named "default", which is created automatically for each project.        subnetwork_link: name of the subnetwork you want the new instance to use.            This value uses the following format:            "regions/{region}/subnetworks/{subnetwork_name}"        internal_ip: internal IP address you want to assign to the new instance.            By default, a free address from the pool of available internal IP addresses of            used subnet will be used.        external_access: boolean flag indicating if the instance should have an external IPv4            address assigned.        external_ipv4: external IPv4 address to be assigned to this instance. If you specify            an external IP address, it must live in the same region as the zone of the instance.            This setting requires `external_access` to be set to True to work.        accelerators: a list of AcceleratorConfig objects describing the accelerators that will            be attached to the new instance.        preemptible: boolean value indicating if the new instance should be preemptible            or not. Preemptible VMs have been deprecated and you should now use Spot VMs.        spot: boolean value indicating if the new instance should be a Spot VM or not.        instance_termination_action: What action should be taken once a Spot VM is terminated.            Possible values: "STOP", "DELETE"        custom_hostname: Custom hostname of the new VM instance.            Custom hostnames must conform to RFC 1035 requirements for valid hostnames.        delete_protection: boolean value indicating if the new virtual machine should be            protected against deletion or not.    Returns:        Instance object.    """instance_client=compute_v1.InstancesClient()# Use the network interface provided in the network_link argument.network_interface=compute_v1.NetworkInterface()network_interface.network=network_linkifsubnetwork_link:network_interface.subnetwork=subnetwork_linkifinternal_ip:network_interface.network_i_p=internal_ipifexternal_access:access=compute_v1.AccessConfig()access.type_=compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.nameaccess.name="External NAT"access.network_tier=access.NetworkTier.PREMIUM.nameifexternal_ipv4:access.nat_i_p=external_ipv4network_interface.access_configs=[access]# Collect information into the Instance object.instance=compute_v1.Instance()instance.network_interfaces=[network_interface]instance.name=instance_nameinstance.disks=disksifre.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$",machine_type):instance.machine_type=machine_typeelse:instance.machine_type=f"zones/{zone}/machineTypes/{machine_type}"instance.scheduling=compute_v1.Scheduling()ifaccelerators:instance.guest_accelerators=acceleratorsinstance.scheduling.on_host_maintenance=(compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name)ifpreemptible:# Set the preemptible settingwarnings.warn("Preemptible VMs are being replaced by Spot VMs.",DeprecationWarning)instance.scheduling=compute_v1.Scheduling()instance.scheduling.preemptible=Trueifspot:# Set the Spot VM settinginstance.scheduling.provisioning_model=(compute_v1.Scheduling.ProvisioningModel.SPOT.name)instance.scheduling.instance_termination_action=instance_termination_actionifcustom_hostnameisnotNone:# Set the custom hostname for the instanceinstance.hostname=custom_hostnameifdelete_protection:# Set the delete protection bitinstance.deletion_protection=True# Prepare the request to insert an instance.request=compute_v1.InsertInstanceRequest()request.zone=zonerequest.project=project_idrequest.instance_resource=instance# Wait for the create operation to complete.print(f"Creating the{instance_name} instance in{zone}...")operation=instance_client.insert(request=request)wait_for_extended_operation(operation,"instance creation")print(f"Instance{instance_name} created.")returninstance_client.get(project=project_id,zone=zone,instance=instance_name)defassign_static_external_ip_to_new_vm(project_id:str,zone:str,instance_name:str,ip_address:str)->compute_v1.Instance:"""    Create a new VM instance with assigned static external IP address.    Args:        project_id (str): project ID or project number of the Cloud project you want to use.        zone (str): name of the zone to create the instance in. For example: "us-west3-b"        instance_name (str): name of the new virtual machine (VM) instance.        ip_address(str): external address to be assigned to this instance. It must live in the same        region as the zone of the instance and be precreated before function called.    Returns:        Instance object.    """newest_debian=get_image_from_family(project="debian-cloud",family="debian-12")disk_type=f"zones/{zone}/diskTypes/pd-standard"disks=[disk_from_image(disk_type,10,True,newest_debian.self_link,True)]instance=create_instance(project_id,zone,instance_name,disks,external_ipv4=ip_address,external_access=True,)returninstance

Change or assign an external IP address to an existing instance

You can change or assign an external IP address, either ephemeral or static, toan existing IPv4-only or dual-stack instance. This procedure is not supportedfor IPv6-only instances.

A compute instance can have multiple interfaces. A single-stack interfacecan have one external IP address. A dual-stack interface can have one externalIPv4 address and one external IPv6 address. If the instance already has anexternal IP address, you mustremove that address first. Thenyou can assign a new external IP address to the existing instance.

Note: If you need to update the IP address of a forwarding rule, seeChange the IP address of a forwarding rule.

Console

  1. In the Google Cloud console, go to theVM instances page.

    Go to VM instances

  2. Click the name of the instance that you want to assign an external IPto. TheInstance details page displays.

  3. From theInstance details page, complete the following steps:

    1. ClickEdit.
    2. ExpandNetwork interfaces.
    3. Select the required external IP address to assign to the instance.If the instance is IPv4-only and you want to assign an IPv6 address,you must first change the stack type to dual-stack.
      1. ForExternal IPv4 address, selecteitherEphemeral or a static external IPv4 address.
      2. ForExternal IPv6 address, selecteitherEphemeral (Automatic),Ephemeral (Custom), or astatic external IPv6 address.
    4. ClickDone.
  4. ClickSave.

gcloud

  1. Optional: Reserve a static external IP address.

    If you want to assign a static external IP address, you must reserve anaddress and make sure that the address is not in use byanother resource. If necessary, follow the instructions toreserve a new static external IP address or tounassign a static external IP address.

    If you intend to use an ephemeral external IP address, you can skip thisstep, and Compute Engine randomly assigns an ephemeralexternal IP address.

  2. Remove any existing IP address assignment, as described inUnassign a static external IP address.

  3. Assign the new external IP address.

    • To assign an IPv4 address, use theinstances add-access-config sub-command:

      Note: Don't replaceIP_ADDRESS with the name of the static IPaddress. You must use the actual IP address.
      gcloud compute instances add-access-configINSTANCE_NAME \  --access-config-name="ACCESS_CONFIG_NAME" --address=IP_ADDRESS

      Replace the following:

      • INSTANCE_NAME: the name of the instance.
      • ACCESS_CONFIG_NAME: the name to call thisaccess config. Make sure to include the full name between quotes.
      • IP_ADDRESS: the IP address to add.

      If you want Compute Engine to assign an ephemeral externalIP address rather than using a static external IP address, omit the--addressIP_ADDRESS property:

      gcloud compute instances add-access-configINSTANCE_NAME \  --access-config-name="ACCESS_CONFIG_NAME"
    • To change an instance to dual-stack and assign it an IPv6 address, usetheinstance network-interfaces update sub-command:

      gcloud compute instances network-interfaces updateINSTANCE_NAME \  --network-interface=NIC \  --ipv6-network-tier=PREMIUM \  --stack-type=STACK_TYPE \  --external-ipv6-address=IPV6_ADDRESS \  --external-ipv6-prefix-length=96 \  --zone=ZONE

      Replace the following:

      • INSTANCE_NAME: the name of the instance.
      • NIC: the name of the network interface.
      • STACK_TYPE: the stack type for the instance,which must beIPV4_IPV6. You can't change the stack type toIPV6_ONLY.
      • IPV6_ADDRESS: the IPv6 address to assignto the instance. Specify the first IPv6 address in the/96 range.
      • ZONE: the zone of the instance.

REST

You can change the external IPv4 or IPv6 address of an instance by adding anew access configuration for that instance.

  1. Remove any existing IP address assignment, as described inUnassign a static external IP address.

  2. Delete the existing access configuration by making aPOST request to theinstances.deleteAccessConfig method.

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/deleteAccessConfig
  3. Add a new access configuration to the network interface of the instanceby making aPOST request to theinstances.addAccessConfig method.

Go

import("context""fmt""io""google.golang.org/protobuf/proto"compute"cloud.google.com/go/compute/apiv1""cloud.google.com/go/compute/apiv1/computepb")// assignStaticAddressToExistingVM assigns a static external IP address to an existing VM instance.// Note: VM and assigned IP must be in the same region.funcassignStaticAddressToExistingVM(wio.Writer,projectID,zone,instanceName,IPAddress,networkInterfaceNamestring)error{// projectID := "your_project_id"// zone := "europe-central2-b"// instanceName := "your_instance_name"// IPAddress := "34.111.222.333"// networkInterfaceName := "nic0"ctx:=context.Background()instancesClient,err:=compute.NewInstancesRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewInstancesRESTClient: %w",err)}deferinstancesClient.Close()reqGet:=&computepb.GetInstanceRequest{Project:projectID,Zone:zone,Instance:instanceName,}instance,err:=instancesClient.Get(ctx,reqGet)iferr!=nil{returnfmt.Errorf("could not get instance: %w",err)}varnetworkInterface*computepb.NetworkInterfacefor_,ni:=rangeinstance.NetworkInterfaces{if*ni.Name==networkInterfaceName{networkInterface=nibreak}}ifnetworkInterface==nil{returnfmt.Errorf("No network interface named '%s' found on instance %s",networkInterfaceName,instanceName)}varaccessConfig*computepb.AccessConfigfor_,ac:=rangenetworkInterface.AccessConfigs{if*ac.Type==computepb.AccessConfig_ONE_TO_ONE_NAT.String(){accessConfig=acbreak}}ifaccessConfig!=nil{// network interface is immutable - deletion stage is required in case of any assigned ip (static or ephemeral).reqDelete:=&computepb.DeleteAccessConfigInstanceRequest{Project:projectID,Zone:zone,Instance:instanceName,AccessConfig:*accessConfig.Name,NetworkInterface:networkInterfaceName,}opDelete,err:=instancesClient.DeleteAccessConfig(ctx,reqDelete)iferr!=nil{returnfmt.Errorf("unable to delete access config: %w",err)}iferr=opDelete.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}}reqAdd:=&computepb.AddAccessConfigInstanceRequest{Project:projectID,Zone:zone,Instance:instanceName,AccessConfigResource:&computepb.AccessConfig{NatIP:&IPAddress,Type:proto.String(computepb.AccessConfig_ONE_TO_ONE_NAT.String()),},NetworkInterface:networkInterfaceName,}opAdd,err:=instancesClient.AddAccessConfig(ctx,reqAdd)iferr!=nil{returnfmt.Errorf("unable to add access config: %w",err)}iferr=opAdd.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Static address %s assigned to the instance %s\n",IPAddress,instanceName)returnnil}

Java

importcom.google.cloud.compute.v1.AccessConfig;importcom.google.cloud.compute.v1.AccessConfig.Type;importcom.google.cloud.compute.v1.Instance;importcom.google.cloud.compute.v1.InstancesClient;importcom.google.cloud.compute.v1.NetworkInterface;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassAssignStaticExistingVm{publicstaticvoidmain(String[]args)throwsIOException,ExecutionException,InterruptedException,TimeoutException{// TODO(developer): Replace these variables before running the sample.// Project ID or project number of the Google Cloud project you want to use.StringprojectId="your-project-id";// Instance ID of the Google Cloud project you want to use.StringinstanceId="your-instance-id";// Name of the zone to create the instance in. For example: "us-west3-b"Stringzone="your-zone-id";// Name of the network interface to assign.StringnetInterfaceName="your-netInterfaceName-id";assignStaticExistingVmAddress(projectId,instanceId,zone,netInterfaceName);}// Updates or creates an access configuration for a VM instance to assign a static external IP.// As network interface is immutable - deletion stage is required// in case of any assigned ip (static or ephemeral).// VM and ip address must be created before calling this function.// IMPORTANT: VM and assigned IP must be in the same region.publicstaticInstanceassignStaticExistingVmAddress(StringprojectId,StringinstanceId,Stringzone,StringnetInterfaceName)throwsIOException,ExecutionException,InterruptedException,TimeoutException{// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.try(InstancesClientclient=InstancesClient.create()){Instanceinstance=client.get(projectId,zone,instanceId);NetworkInterfacenetworkInterface=null;for(NetworkInterfacenetInterface:instance.getNetworkInterfacesList()){if(netInterface.getName().equals(netInterfaceName)){networkInterface=netInterface;break;}}if(networkInterface==null){thrownewIllegalArgumentException(String.format("No '{network_interface_name}' variable found on instance %s.",instanceId));}AccessConfigaccessConfig=null;for(AccessConfigconfig:networkInterface.getAccessConfigsList()){if(config.getType().equals(Type.ONE_TO_ONE_NAT.name())){accessConfig=config;break;}}if(accessConfig!=null){// Delete the existing access configuration firstclient.deleteAccessConfigAsync(projectId,zone,instanceId,accessConfig.getName(),netInterfaceName).get(30,TimeUnit.SECONDS);}// Add a new access configuration with the new IPAccessConfignewAccessConfig=AccessConfig.newBuilder()// Leave this field undefined to use an IP from a shared ephemeral IP address pool// .setNatIP(ipAddress).setType(Type.ONE_TO_ONE_NAT.name()).setName("external-nat").build();client.addAccessConfigAsync(projectId,zone,instanceId,netInterfaceName,newAccessConfig).get(30,TimeUnit.SECONDS);// return updated instancereturnclient.get(projectId,zone,instanceId);}}}

Python

importuuidfromgoogle.cloud.compute_v1importInstancesClientfromgoogle.cloud.compute_v1.typesimportAccessConfigfromgoogle.cloud.compute_v1.typesimportAddAccessConfigInstanceRequestfromgoogle.cloud.compute_v1.typesimportDeleteAccessConfigInstanceRequestdefassign_static_ip_to_existing_vm(project_id:str,zone:str,instance_name:str,ip_address:str,network_interface_name:str="nic0",):"""    Updates or creates an access configuration for a VM instance to assign a static external IP.    As network interface is immutable - deletion stage is required in case of any assigned ip (static or ephemeral).    VM and ip address must be created before calling this function.    IMPORTANT: VM and assigned IP must be in the same region.    Args:        project_id (str): Project ID.        zone (str): Zone where the VM is located.        instance_name (str): Name of the VM instance.        ip_address (str): New static external IP address to assign to the VM.        network_interface_name (str): Name of the network interface to assign.    Returns:        google.cloud.compute_v1.types.Instance: Updated instance object.    """client=InstancesClient()instance=client.get(project=project_id,zone=zone,instance=instance_name)network_interface=next((niforniininstance.network_interfacesifni.name==network_interface_name),None,)ifnetwork_interfaceisNone:raiseValueError(f"No network interface named '{network_interface_name}' found on instance{instance_name}.")access_config=next((acforacinnetwork_interface.access_configsifac.type_=="ONE_TO_ONE_NAT"),None,)ifaccess_config:# Delete the existing access configuration firstdelete_request=DeleteAccessConfigInstanceRequest(project=project_id,zone=zone,instance=instance_name,access_config=access_config.name,network_interface=network_interface_name,request_id=str(uuid.uuid4()),)delete_operation=client.delete_access_config(delete_request)delete_operation.result()# Add a new access configuration with the new IPadd_request=AddAccessConfigInstanceRequest(project=project_id,zone=zone,instance=instance_name,network_interface="nic0",access_config_resource=AccessConfig(nat_i_p=ip_address,type_="ONE_TO_ONE_NAT",name="external-nat"),request_id=str(uuid.uuid4()),)add_operation=client.add_access_config(add_request)add_operation.result()updated_instance=client.get(project=project_id,zone=zone,instance=instance_name)returnupdated_instance

Restrict external IP addresses to specific instances

For certain workloads, you might have essential requirements that includesecurity and network restrictions. For example, you might want to restrictexternal IP addresses so that only specific compute instances can use them. Thisoption can help to prevent data exfiltration ormaintain network isolation. Using anOrganization Policy,you can restrict external IP addresses to specific instances withconstraints to control use of external IP addresses for your instances within anorganization or a project.

Caution: Restricting external IPs to specific instances can prevent existingGKE clusters and managed instance groups (MIGs) fromadding new instances. If a GKE cluster or a MIG isconfigured to create instances that have external IP addresses, autohealingand autoscaling actions fail.

The constraint for controlling external IP address on instances is:

constraints/compute.vmExternalIpAccess

To use the constraint, you specify a policy with anallowedList of instancesthat can have external IP addresses. If you don't specify a policy, all externalIP addresses are allowed for all instances. When the policy is in place, onlythe instances that are listed in theallowedValues list can be assigned anexternal IP address, either ephemeral or static, and otherCompute Engine instances in the organization or project that are notexplicitly defined in the policy are prohibited from using external IPaddresses.

Instances are identified in the allow and deny lists using the instance's URI:

projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME

Specifications for restricting external IP addresses

  • You can apply thislist constraintonly to instances.
  • You cannot apply the constraint retroactively. All instances that haveexternal IP addresses before you enable the policy retain their external IPaddresses.
  • This constraint accepts either anallowedList or adeniedList but not bothin the same policy.
  • It is up to you or an administrator with the required permissions to manageand maintain the instance lifecycle and integrity. The constraint onlyverifies the instance's URI, and it does not prevent the instances in theallowlist from being altered, deleted, or recreated.

Permissions needed for restricting external IP addresses

To set a constraint on either the project or the organization level, you musthave been granted theorgpolicy.policyAdmin role on the organization.

Set the policy constraint at the organization level

Note: The length of each string used for each instance URI cannot exceed200 characters.

Console

  1. Go to theOrganizational Policies page.

    Go to Organizational Policies

  2. If necessary, select the required organization from the projectdrop-down menu.
  3. ClickDefine allowed external IPs for VM instances.
  4. ClickEdit to edit the external IP policy. If you can't access theEdit tool, you don't have the correctpermissions.
  5. SelectCustomize to set the org policy for specific instances.

    Customize option on the edit organization policy page.

  6. Select the requiredPolicy enforcement andPolicy type.

  7. ForPolicy values, selectCustom.

  8. Enter a URI for an instance. The URI must be in the following format:

    projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME
  9. ClickNew policy value and enter URIs for instances as needed.

  10. ClickSave to apply the constraint.

gcloud

To set a constraint for external IP access, you first need your organizationID. You can find the organization ID by running theorganizations list command andlooking for the numeric ID in the response:

gcloud organizations list

The gcloud CLI returns a list of organizations in the followingformat:

DISPLAY_NAME               IDexample-organization1      29252605212example-organization2      1234567890

Use thegcloud resource-manager org-policies set-policy commandto set the policy. You need to provide your policy as a JSON file.Create a JSON file in the following format:

{"constraint": "constraints/compute.vmExternalIpAccess","listPolicy": {  "allowedValues": [     "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME",     "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME",     "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME"  ] }}

Replace the following:

  • PROJECT_ID: the project ID for this request,such asexample-project. Note that this is different than setting uporganization policies, which require the organization numeric ID.
  • ZONE: the zone of the instance
  • INSTANCE_NAME: the name of the instance

Alternatively, you can specify adeniedValues list to indicate instancesthat you explicitly want to prohibit from having an external IP address.Any instance not on the list would implicitly be allowed to have anexternal IP address. You can only specify eitherallowedValues ordeniedValues but not both.

Then, pass in the file with your request:

gcloud resource-manager org-policies set-policyMY_POLICY.JSON --organization=ORGANIZATION_ID

ReplaceORGANIZATION_ID with the numeric ID of theorganization.

If you don't want any instances to have external IP access, you can set apolicy withallValues set toDENY:

{  "constraint": "constraints/compute.vmExternalIpAccess",  "listPolicy": {    "allValues": "DENY"  }}

REST

Use thesetOrgPolicy() APIto define your constraint. The instances in theallowedValue list youspecify are allowed to have external IP addresses. Alternatively, you canspecify adeniedValues list to express instances that you explicitlywant to prohibit from having an external IP address. Any instance not on thelist would implicitly be allowed to have an external IP address. You canonly specify eitherallowedValues ordeniedValues but not both.

For example, the following is a request to apply thecompute.vmExternalIpAccess constraint to an organization where instancesfrom certain projects within the organization are allowed to haveexternal IP addresses:

POST https://cloudresourcemanager.googleapis.com/v1/organizations/ORGANIZATION_ID:setOrgPolicy

whereORGANIZATION_ID is the numeric ID of theorganization.

Now, in your request body, provide the policy for this constraint:

{  "policy": {    "constraint": "constraints/compute.vmExternalIpAccess",    "listPolicy": {      "allowedValues": [        "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME",        "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME",        "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME"        ]      }    } }

If you don't want any instances to have external IP access, you can set apolicy withallValues set toDENY:

{  "policy": {    "constraint": "constraints/compute.vmExternalIpAccess",    "listPolicy": {      "allValues": "DENY"      }    } }

Set the policy at the project level

Setting a policy at the project level overrides the policy at the organizationlevel. For example, if the organization level hasexample-vm-1 on theallowedValues list but the policy at the project level has the same instanceon thedeniedValues list, the instance wouldn't be allowed to have anexternal IP address.

Console

Follow the same process documented underSet a policy constraint at the organization level butchoose your project from the project selector instead of theorganization.

Project selector.

gcloud

Use thegcloud resource-manager org-policies set-policy commandto set the policy. You need to provide your policy as a JSON file. Create aJSON file in the following format:

{ "constraint": "constraints/compute.vmExternalIpAccess", "listPolicy": {  "allowedValues": [   "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME"  ] }}

Replace the following:

  • PROJECT_ID: the project ID for this request,such asexample-project. Note that this is different than setting uporganization policies, which require the organization numeric ID.
  • ZONE: the zone of the instance.
  • INSTANCE_NAME: the name of the instance.

Alternatively, you can specify adeniedValues list of instances that youexplicitly want to prohibit from having an external IP address. Any instancenot on the list would implicitly be allowed to have an external IP address.You can only specify eitherallowedValues ordeniedValues but not both.

Then, pass in the file with your request:

gcloud resource-manager org-policies set-policyMY_POLICY.JSON --project=example-project

REST

Use thesetOrgPolicy APIto define your constraint. The instances in theallowedValue list youspecify are allowed to have external IP addresses. Alternatively, you canspecify adeniedValues list to express instances that you explicitly wantto prohibit from having an external IP address. Any instance not on thelist is implicitly allowed to have an external IP address. You can specifyonlyallowedValues ordeniedValues but not both.

For example, the following is a request to set thecompute.vmExternalIpAccess constraint on a project to allow specificinstances to have external IP addresses:

POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setOrgPolicy

ReplacePROJECT_ID with the project ID for thisrequest.

The request body contains the policy for this constraint:

{  "policy": {    "constraint": "constraints/compute.vmExternalIpAccess",    "listPolicy": {      "allowedValues": [        "projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME"      ]    }  }}

Best practices for restricting external IP addresses

  • Avoid using thedeniedValues list with this constraint. If you definevalues in thedeniedValues list, it means that only the instances in thedeniedValues list are restricted from using external IP addresses. Thiscould be a security concern if you want control over exactly which instancescan have external IP addresses. If you want to remove certain instances fromtheallowedValues list, update the existing policy to remove the instancesfrom theallowedList rather than putting the instances into thedeniedValues list at a lower hierarchy.

  • If you want to set a policy over a large part of the resource hierarchy butexempt certain projects, restore the default policy by usingthesetOrgPolicy method by specifying therestoreDefaultobject to allow all instances in the projects to be associated with externalIP addresses. The current policies for projects are not affectedby the default setting.

  • Use the org policy together with IAM roles to better controlyour environment. This policy applies to only instances but if you want tobetter control and restrict external IP addresses on network devices, you cangrant thecompute.networkAdmin role to the appropriate parties.

  • Any services and products that are running on Compute Enginewithin the organization or project with the policy enabled are subject to thisorg policy. Specifically, services such as Google Kubernetes Engine,Dataflow, Dataproc, and Cloud SQL are affected by thispolicy. If this is an issue,Google recommends that you set up other services and products in a differentproject that does not have the organization policy applied, and useShared VPC, if needed.

Manage static external IP addresses

The following sections describe how to manage static external IP addressesfor your instances.

Determine if an internal IP address is ephemeral or static

Static and ephemeral internal IP addresses behave and appear the same in mostcontexts. However, with static internal IP addresses, you can use the same IPaddress for the same resource even if you delete and re-create the resource.In general, an ephemeral IP address is released if you stop or delete theresource.

To determine if an address is static or ephemeral, do the following:

  1. In the Google Cloud console, go to theIP addresses page.

    Go to IP addresses

  2. Find the address in the list and check theType column for the type ofIP address.

Unassign a static external IP address

Unassigning an IP address removes it from the resource but keeps the IP addressreserved. After the IP address is unassigned, you can reassign the IP address toanother resource. This procedure is supported for dual-stack instances, but notIPv6-only instances.

Note: You are charged at a higher rate for unassigned static external IPaddresses than you are for static and ephemeral external IP addresses that arein use. For more information, seeExternal IP address pricing.

You can also unassign the IPv4 or IPv6 address bydeleting the instance.

Console

  1. In the Google Cloud console, go to theIP addresses page.

    Go to IP addresses

  2. ClickExternal IP addresses.

  3. Select the static IP address that you want to unassign.

  4. ClickView actions and select theReassign to another resource option.

  5. From theAttach to drop-down list, selectNone.

  6. ClickOK.

gcloud

  1. Check if a static IP address is in use by using thegcloud compute addresses list command:

    gcloud compute addresses list

    The output is similar to the following:

    NAME                      REGION    ADDRESS                  STATUSexample-address-ipv4REGION    198.51.100.1             RESERVEDexample-address-new-ipv4REGION    203.0.113.1              IN_USEexample-address-ipv6REGION    2001:db8:1:1:1:1:1:1     RESERVEDexample-address-new-ipv6REGION    2001:db8:4:4:4:4:4:4     IN_USE
    • If the IP address is not in use, the status isRESERVED.
    • If the IP address is in use, the status isIN_USE.
  2. Retrieve the name of the instance that is using the IP address:

    gcloud compute addresses describeADDRESS_NAME \  --region=REGION

    Replace the following:

    • ADDRESS_NAME: the name of the IPv6 addressresource.
    • REGION: the region of the IPv6 addressresource.

    The output is similar to the following:

    address:IP_ADDRESSaddressType: EXTERNAL...region: https://www.googleapis.com/compute/v1/projects/PROJECT/regions/REGIONselfLink: https://www.googleapis.com/compute/v1/projects/PROJECT/regions/REGION/addresses/ADDRESS_NAMEstatus: IN_USEsubnetwork: https://www.googleapis.com/compute/v1/projects/PROJECT/regions/REGION/subnetworks/SUBNETusers:- https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/instances/INSTANCE_NAME

    Theusers field displays the name of the instance that is using the IPaddress.

  3. Unassign the IP address from the instance.

  4. Check that your static external IP address is now available and marked asRESERVED instead ofIN_USE.

    gcloud compute addresses list \  --filter="ADDRESS_NAME AND region=REGION"

    Replace the following:

    • ADDRESS_NAME: the name of the IP addressresource.
    • REGION: the region of the IP address resource.

Now that your static external IP address is available, you can choose toassign it to another instance.

REST

To unassign a static external IPv4 or IPv6 address, perform the followingsteps:

  • For IPv4 addresses, delete the access configuration attached to theinstance that's using the address.

    1. To check the access configuration details of a instance, make aGET request to theinstances.get method.

      GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME
    2. Delete the existing access configuration by making aPOST request to theinstances.deleteAccessConfig method.

      POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/deleteAccessConfig

      Replace the following:

      • PROJECT_ID: the project ID for thisrequest
      • ZONE: the zone where the instance islocated
      • INSTANCE_NAME: the name of the instance
  • For IPv6 addresses, update the stack type of the networkinterface for the instance where the IPv6 address is attached.

    1. Make aPATCH request to theinstances.updateNetworkInterface method.

    2. In the request body, update the value of thestackType field toIPV4_ONLY.

      For example:

      PATCH https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/updateNetworkInterface{  "networkInterfaces": [{    ...    "stackType" : "IPV4_ONLY"    ...    }]}

Java

importcom.google.cloud.compute.v1.AccessConfig;importcom.google.cloud.compute.v1.AccessConfig.Type;importcom.google.cloud.compute.v1.Instance;importcom.google.cloud.compute.v1.InstancesClient;importcom.google.cloud.compute.v1.NetworkInterface;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassUnassignStaticIpAddress{publicstaticvoidmain(String[]args)throwsIOException,ExecutionException,InterruptedException,TimeoutException{// TODO(developer): Replace these variables before running the sample.// Project ID or project number of the Google Cloud project you want to use.StringprojectId="your-project-id";// Instance ID of the Google Cloud project you want to use.StringinstanceId="your-instance-id";// Name of the zone to create the instance in. For example: "us-west3-b"Stringzone="your-zone";// Name of the network interface to assign.StringnetInterfaceName="your-netInterfaceName";unassignStaticIpAddress(projectId,instanceId,zone,netInterfaceName);}publicstaticInstanceunassignStaticIpAddress(StringprojectId,StringinstanceId,Stringzone,StringnetInterfaceName)throwsIOException,ExecutionException,InterruptedException,TimeoutException{// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.try(InstancesClientclient=InstancesClient.create()){Instanceinstance=client.get(projectId,zone,instanceId);NetworkInterfacenetworkInterface=null;for(NetworkInterfacenetIterface:instance.getNetworkInterfacesList()){if(netIterface.getName().equals(netInterfaceName)){networkInterface=netIterface;break;}}if(networkInterface==null){thrownewIllegalArgumentException(String.format("No '{network_interface_name}' variable found on instance %s.",instanceId));}AccessConfigaccessConfig=null;for(AccessConfigconfig:networkInterface.getAccessConfigsList()){if(config.getType().equals(Type.ONE_TO_ONE_NAT.name())){accessConfig=config;break;}}if(accessConfig!=null){// Delete the existing access configuration firstclient.deleteAccessConfigAsync(projectId,zone,instanceId,accessConfig.getName(),netInterfaceName).get(30,TimeUnit.SECONDS);}// return updated instancereturnclient.get(projectId,zone,instanceId);}}}

Python

importuuidfromgoogle.cloud.compute_v1importInstancesClientfromgoogle.cloud.compute_v1.typesimportDeleteAccessConfigInstanceRequestdefunassign_static_ip_from_existing_vm(project_id:str,zone:str,instance_name:str,network_interface_name:str="nic0",):"""    Updates access configuration for a VM instance to unassign a static external IP.    VM (and IP address in case of static IP assigned) must be created before calling this function.    Args:        project_id (str): Project ID.        zone (str): Zone where the VM is located.        instance_name (str): Name of the VM instance.        network_interface_name (str): Name of the network interface to unassign.    """client=InstancesClient()instance=client.get(project=project_id,zone=zone,instance=instance_name)network_interface=next((niforniininstance.network_interfacesifni.name==network_interface_name),None,)ifnetwork_interfaceisNone:raiseValueError(f"No network interface named '{network_interface_name}' found on instance{instance_name}.")access_config=next((acforacinnetwork_interface.access_configsifac.type_=="ONE_TO_ONE_NAT"),None,)ifaccess_config:# Delete the existing access configurationdelete_request=DeleteAccessConfigInstanceRequest(project=project_id,zone=zone,instance=instance_name,access_config=access_config.name,network_interface=network_interface_name,request_id=str(uuid.uuid4()),)delete_operation=client.delete_access_config(delete_request)delete_operation.result()updated_instance=client.get(project=project_id,zone=zone,instance=instance_name)returnupdated_instance

Release a static external IP address

If you no longer need a static external IPv4 or IPv6 address, you can releasethe IP address by deleting the IP address resource. Deleting an instance doesn'tautomatically release a static external IP address. You must manually releasestatic external IP addresses when you no longer require them.

To release a static external IP address, seeRelease a static external IP addressin the VPC documentation.

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.