You can assign static external IP addresses to your virtual machine (VM)instances. You can also change, list, and release static IP addresses for yourVMs. To reserve a static external IP address, seeReserve a static external IP address.
External IP addresses can bestatic or ephemeral.If a VM requires a fixed external IP address that does not change, do thefollowing:
- Obtain a static external IP address. You can reserve new external IPaddresses or promote existing ephemeral external IP addresses.
- Assign the reserved IP address to an existing VM, or assign it when creatinga new VM.
If you require a static IP address on your internal Compute Enginenetwork, see insteadReserve a static internal IP address.
Before you begin
- Read about IP addresses.
- Read about quotas and limits for static external IP addresses.
- Read about external IP address pricing.
- If you haven't already, set up authentication. Authentication is the process by which your identity is verified for access to Google Cloud services and APIs. To run code or samples from a local development environment, you can authenticate to Compute Engine as follows.
Select the tab for how you plan to use the samples on this page:
Console
When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.
gcloud
-
Install the Google Cloud CLI, then initialize it by running the following command:
gcloud init
- Set a default region and zone.
Terraform
To use the Terraform samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
If you're using a local shell, then create local authentication credentials for your user account:
gcloud auth application-default login
You don't need to do this if you're using Cloud Shell.
For more information, see Set up authentication for a local development environment.
REST
To use the REST API samples on this page in a local development environment, you use the credentials you provide to the gcloud CLI.
Install the Google Cloud CLI, then initialize it by running the following command:
gcloud init
For more information, see Authenticate for using REST in the Google Cloud authentication documentation.
-
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:
- To create and update VMs: Compute Instance Admin (v1) (
roles/compute.instanceAdmin.v1
)
For more information about granting roles, see Manage 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 the Required permissions section:
Required permissions
The following permissions are required to configure and manage static IP addresses:
-
compute.instances.update
on the VM instance -
compute.instances.updateNetworkInterface
on the VM instance -
compute.instances.addAccessConfig
on the VM instance -
compute.instances.deleteAccessConfig
on the VM instance -
compute.networks.list
on the network -
compute.subnetworks.use
on the subnet -
compute.subnetworks.list
on the subnet - To create VMs:
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 a legacy 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 with custom roles or other predefined 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 the
gcloud compute addresses list
sub-commandto see a list of static external IP addresses available to theproject.Each VM can havemultiple network interfaces,and each interface can have the following IP addresses assigned:
- An internal IPv4 address (required)
- An external IPv4 address
- A
/96
IPv6 address range, either internal or external, but not both
You cannot change the name of a static IP address.
Assigned external IP addresses exist on the same physical host as the VMand exist in the same region as the VM for all purposes, includingrouting, latency, and pricing. This is true regardless ofinternet geolocationlookup information.
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 the load balancing documentation.
View available static external IP addresses
To list static external IP addresses that you have reserved for yourproject, follow these steps.
Console
In the Google Cloud console, go to the IP addresses page.
Click External IP addresses.
gcloud
Use the gcloud 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
Replace
REGION
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 the
addresses.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 requestREGION
: the name of the region for thisrequest
To list all addresses in all regions, call the
addresses.aggregatedList
method:GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/aggregated/addresses
To list global IPv4 or IPv6 addresses, call the
globalAddresses.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.func listRegionalExternal(w io.Writer, projectID, region string) ([]*computepb.Address, error) {// projectID := "your_project_id"// region := "europe-west3"ctx := context.Background()// Create the service client.addressesClient, err := compute.NewAddressesRESTClient(ctx)if err != nil {return nil, err}defer addressesClient.Close()// Build the request.req := &computepb.ListAddressesRequest{Project: projectID,Region: region,}// List the addresses.it := addressesClient.List(ctx, req)// Iterate over the results.var addresses []*computepb.Addressfor {address, err := it.Next()if err == iterator.Done {break}if err != nil {return nil, err}addresses = append(addresses, address)}// Print the addresses.fmt.Fprint(w, "Fetched addresses: \n")for _, address := range addresses {fmt.Fprintf(w, "%s\n", *address.Name)}return addresses, nil}// listGlobalExternal retrieves list external global IP addresses in Google Cloud Platform.func listGlobalExternal(w io.Writer, projectID string) ([]*computepb.Address, error) {// projectID := "your_project_id"ctx := context.Background()// Create the service client.addressesClient, err := compute.NewGlobalAddressesRESTClient(ctx)if err != nil {return nil, err}defer addressesClient.Close()// Build the request.req := &computepb.ListGlobalAddressesRequest{Project: projectID,}// List the addresses.it := addressesClient.List(ctx, req)// Iterate over the results.var addresses []*computepb.Addressfor {address, err := it.Next()if err == iterator.Done {break}if err != nil {return nil, err}addresses = append(addresses, address)}// Print the addresses.fmt.Fprint(w, "Fetched addresses: \n")for _, address := range addresses {fmt.Fprintf(w, "%s\n", *address.Name)}return addresses, nil}
Java
import com.google.cloud.compute.v1.Address;import com.google.cloud.compute.v1.AddressesClient;import com.google.cloud.compute.v1.GlobalAddressesClient;import com.google.cloud.compute.v1.ListAddressesRequest;import com.google.cloud.compute.v1.ListGlobalAddressesRequest;import com.google.common.collect.Lists;import java.io.IOException;import java.util.List;import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeoutException;public class ListStaticExternalIp { public static void main(String[] args) throws IOException, 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. String projectId = "your-project-id"; // Region where the VM and IP is located. String region = "your-region-id"; listStaticExternalIp(projectId, region); } // Lists all static external IP addresses, either regional or global. public static List<Address> listStaticExternalIp(String projectId, String region) throws IOException { // Use regional client if a region is specified if (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 (AddressesClient client = AddressesClient.create()) { ListAddressesRequest request = ListAddressesRequest.newBuilder() .setProject(projectId) .setRegion(region) .build(); return Lists.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 (GlobalAddressesClient client = GlobalAddressesClient.create()) { ListGlobalAddressesRequest request = ListGlobalAddressesRequest.newBuilder() .setProject(projectId) .build(); return Lists.newArrayList(client.list(request).iterateAll()); } } }}
Python
from typing import List, Optionalfrom google.cloud.compute_v1.services.addresses.client import AddressesClientfrom google.cloud.compute_v1.services.global_addresses import GlobalAddressesClientfrom google.cloud.compute_v1.types import Addressdef list_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. """ if region: # Use regional client if a region is specified client = AddressesClient() addresses_iterator = client.list(project=project_id, region=region) else: # Use global client if no region is specified client = GlobalAddressesClient() addresses_iterator = client.list(project=project_id) return list(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 VMs.
Create a VM that uses a static external IP address
After you have reserved a static external IP address,you can assign it to a VM.
Console
In the Google Cloud console, go to the Create an instance page.
Specify the VM details.
Expand the Advanced options section.
Expand the Networking section.
In the Network interfaces section, expand a networkinterface to edit it.
To assign an IPv4 address, do the following:
- Select a network.
- Select the IP address from the External IPv4 address list.
To assign an IPv6 address, do the following:
- Select a network that contains an IPv6 subnet.
- Select a dual-stack subnet from the Subnetwork list.
- For IP stack type, select IPv4 and IPv6 (dual-stack).
- Select the newly reserved external IPv6 address from theExternal IPv6 address list. Alternatively, selectCREATE IP ADDRESS and reserve a new static external IPv6 address.
- For Network Service Tier, select Premium.
To finish modifying the default network interface, click Done.
Continue with the VM creation process.
gcloud
You can create a VM 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 create VM_NAME --address=IP_ADDRESS
Replace the following:
VM_NAME
: the name of the VM.IP_ADDRESS
: the IP address to assign to the VM. Use the reserved static external IP address, not the address name.
To assign a static external IPv6 address, do the following:
gcloud compute instances create VM_NAME \ --subnet=SUBNET \ --stack-type=IPV4_IPV6 \ --external-ipv6-address=IPV6_ADDRESS \ --external-ipv6-prefix-length=96 \ --ipv6-network-tier=PREMIUM \ --zone=ZONE
Terraform
You can use the google_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 VM, do the following:
In your request tocreate a new VM,explicitly provide thenetworkInterfaces[].accessConfigs[].natIP
property and the external IPv4 address that you want to use. For example:
{ "name": "VM_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" }}]}
To assign a static external IPv6 address to a new VM, do the following:
In your request tocreate a new VM,explicitly provide thenetworkInterfaces[].ipv6AccessConfigs[].externalIpv6
property and the external IPv6 address that you want to use. For example:
{ "name": "VM_NAME", "machineType": "zones/ZONE/machineTypes/MACHINE_TYPE", "networkInterfaces": [{ "accessConfigs": [{ "name": "external-nat", "type": "ONE_TO_ONE_NAT" }], "ipv6AccessConfigs": [{ "externalIpv6": "IOV6_ADDRESS", "externalIpv6PrefixLength": 96, "name": "external-ipv6-access-config", "networkTier": "PREMIUM", "type": "DIRECT_IPV6" }], "stackType": "IPV4_IPV6", "subnetwork":"SUBNETWORK }], "disks": [{ "autoDelete": "true", "boot": "true", "mode": "READ_WRITE", "type": "PERSISTENT", "initializeParams": { "sourceImage": "SOURCE_IMAGE" }, }], }
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 VMfunc assignStaticExternalToNewVM(w io.Writer, projectID, zone, instanceName, ipAddress string) 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)if err != nil {return fmt.Errorf("NewInstancesRESTClient: %w", err)}defer instancesClient.Close()imagesClient, err := compute.NewImagesRESTClient(ctx)if err != nil {return fmt.Errorf("NewImagesRESTClient: %w", err)}defer imagesClient.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)if err != nil {return fmt.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)if err != nil {return fmt.Errorf("unable to create instance: %w", err)}if err = op.Wait(ctx); err != nil {return fmt.Errorf("unable to wait for the operation: %w", err)}fmt.Fprintf(w, "Static address %s assigned to new VM", ipAddress)return nil}
Java
import com.google.cloud.compute.v1.AccessConfig;import com.google.cloud.compute.v1.AccessConfig.Type;import com.google.cloud.compute.v1.Address.NetworkTier;import com.google.cloud.compute.v1.AttachedDisk;import com.google.cloud.compute.v1.AttachedDiskInitializeParams;import com.google.cloud.compute.v1.GetInstanceRequest;import com.google.cloud.compute.v1.ImagesClient;import com.google.cloud.compute.v1.InsertInstanceRequest;import com.google.cloud.compute.v1.Instance;import com.google.cloud.compute.v1.InstancesClient;import com.google.cloud.compute.v1.NetworkInterface;import java.io.IOException;import java.util.UUID;import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeUnit;import java.util.concurrent.TimeoutException;public class AssignStaticExternalNewVmAddress { public static void main(String[] args) throws IOException, 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. String projectId = "your-project-id"; // Instance ID of the Google Cloud project you want to use. String instanceId = "your-instance-id"; // Name of the zone to create the instance in. For example: "us-west3-b" String zone = "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" String machineType = String.format("zones/%s/machineTypes/{your-machineType-id}", zone); // boolean flag indicating if the instance should have an external IPv4 address assigned. boolean externalAccess = 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. String externalIpv4 = "your-externalIpv4-id"; assignStaticExternalNewVmAddress(projectId, instanceId, zone, externalAccess, machineType, externalIpv4); } // Create a new VM instance with assigned static external IP address. public static Instance assignStaticExternalNewVmAddress(String projectId, String instanceName, String zone, boolean externalAccess, String machineType, String externalIpv4) throws IOException, ExecutionException, InterruptedException, TimeoutException { String sourceImage; // 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 (ImagesClient imagesClient = ImagesClient.create()) { sourceImage = imagesClient.getFromFamily("debian-cloud", "debian-11").getSelfLink(); } AttachedDisk attachedDisk = buildAttachedDisk(sourceImage, zone); return createInstance(projectId, instanceName, zone, attachedDisk, machineType, externalAccess, externalIpv4); } private static AttachedDisk buildAttachedDisk(String sourceImage, String zone) { AttachedDiskInitializeParams initializeParams = AttachedDiskInitializeParams.newBuilder() .setSourceImage(sourceImage) .setDiskSizeGb(10) .setDiskType(String.format("zones/%s/diskTypes/pd-standard", zone)) .build(); return AttachedDisk.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. private static Instance createInstance(String projectId, String instanceName, String zone, AttachedDisk disks, String machineType, boolean externalAccess, String externalIpv4) throws IOException, 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 (InstancesClient client = InstancesClient.create()) { Instance instanceResource = buildInstanceResource(instanceName, disks, machineType, externalAccess, externalIpv4); InsertInstanceRequest build = InsertInstanceRequest.newBuilder() .setProject(projectId) .setRequestId(UUID.randomUUID().toString()) .setZone(zone) .setInstanceResource(instanceResource) .build(); client.insertCallable().futureCall(build).get(60, TimeUnit.SECONDS); GetInstanceRequest getInstanceRequest = GetInstanceRequest.newBuilder() .setInstance(instanceName) .setProject(projectId) .setZone(zone) .build(); return client.get(getInstanceRequest); } } private static Instance buildInstanceResource(String instanceName, AttachedDisk disk, String machineType, boolean externalAccess, String externalIpv4) { NetworkInterface networkInterface = networkInterface(externalAccess, externalIpv4); return Instance.newBuilder() .setName(instanceName) .addDisks(disk) .setMachineType(machineType) .addNetworkInterfaces(networkInterface) .build(); } private static NetworkInterface networkInterface(boolean externalAccess, String externalIpv4) { NetworkInterface.Builder build = NetworkInterface.newBuilder() .setNetwork("global/networks/default"); if (externalAccess) { AccessConfig.Builder accessConfig = 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()); } return build.build(); }}
Python
from __future__ import annotationsimport reimport sysfrom typing import Anyimport warningsfrom google.api_core.extended_operation import ExtendedOperationfrom google.cloud import compute_v1def get_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-details newest_image = image_client.get_from_family(project=project, family=family) return newest_imagedef disk_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_image initialize_params.disk_size_gb = disk_size_gb initialize_params.disk_type = disk_type boot_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_delete boot_disk.boot = boot return boot_diskdef wait_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) if operation.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) raise operation.exception() or RuntimeError(operation.error_message) if operation.warnings: print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True) for warning in operation.warnings: print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True) return resultdef create_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_link if subnetwork_link: network_interface.subnetwork = subnetwork_link if internal_ip: network_interface.network_i_p = internal_ip if external_access: access = compute_v1.AccessConfig() access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name access.name = "External NAT" access.network_tier = access.NetworkTier.PREMIUM.name if external_ipv4: access.nat_i_p = external_ipv4 network_interface.access_configs = [access] # Collect information into the Instance object. instance = compute_v1.Instance() instance.network_interfaces = [network_interface] instance.name = instance_name instance.disks = disks if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type): instance.machine_type = machine_type else: instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}" instance.scheduling = compute_v1.Scheduling() if accelerators: instance.guest_accelerators = accelerators instance.scheduling.on_host_maintenance = ( compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name ) if preemptible: # Set the preemptible setting warnings.warn( "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning ) instance.scheduling = compute_v1.Scheduling() instance.scheduling.preemptible = True if spot: # Set the Spot VM setting instance.scheduling.provisioning_model = ( compute_v1.Scheduling.ProvisioningModel.SPOT.name ) instance.scheduling.instance_termination_action = instance_termination_action if custom_hostname is not None: # Set the custom hostname for the instance instance.hostname = custom_hostname if delete_protection: # Set the delete protection bit instance.deletion_protection = True # Prepare the request to insert an instance. request = compute_v1.InsertInstanceRequest() request.zone = zone request.project = project_id request.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.") return instance_client.get(project=project_id, zone=zone, instance=instance_name)def assign_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, ) return instance
Change or assign an external IP address to an existing VM
You can change or assign an external IP address, either ephemeral or static, toan existing VM.
A VM can have multiple interfaces and each interface can have an externalIP address. If the VM already has an external IP address, you mustremove that address first. Then, you can assign a new externalIP address to the existing VM.
Console
- In the Google Cloud console, go to the VM instances page.
- Click the name of the VM that you want to assign an external IPto. The Instance details page displays.
From the Instance details page, complete the following steps:
- Click Edit.
- Expand Network interfaces.
- Select the required external IP address to assign to the VM:
- For External IPv4 address, selecteither Ephemeral or a static external IPv4 address.
- For External IPv6 address, selecteither Ephemeral or a static external IPv6 address.
- Click Done.
Click Save.
gcloud
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.
Remove any existing IP address assignment, as described inUnassign a static external IP address.
Assign the new external IP address.
To assign an IPv4 address, use the
instances add-access-config
sub-command:Note: Don't replace
IP_ADDRESS
with the name of the static IPaddress. You must use the actual IP address.gcloud compute instances add-access-config VM_NAME \ --access-config-name="ACCESS_CONFIG_NAME" --address=IP_ADDRESS
Replace the following:
VM_NAME
: the name of the VM.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
--address IP_ADDRESS
property:gcloud compute instances add-access-config VM_NAME \ --access-config-name="ACCESS_CONFIG_NAME"
To assign an IPv6 address range, use the
instance network-interfacesupdate
sub-command:gcloud compute instances network-interfaces update VM_NAME \ --network-interface==NIC \ --ipv6-network-tier=PREMIUM \ --stack-type=IPV4_IPV6 \ --external-ipv6-address=IPV6_ADDRESS \ --external-ipv6-prefix-length=96 \ --zone=ZONE
Replace the following:
VM_NAME
: the name of the VM.NIC
: the name of the network interface.IPV6_ADDRESS
: the IPv6 address to assignto the VM. Specify the first IPv6 address in the/96
range.ZONE
: the zone of the VM.
REST
You can change the external IPv4 or IPv6 address of a VM by adding a newaccess configuration for that VM.
Remove any existing IP address assignment, as described inUnassign a static external IP address.
Delete the existing access configuration by making a
POST
request to theinstances.deleteAccessConfig
method.POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/deleteAccessConfig
Add a new access configuration to the network interface of the VMby making a
POST
request to theinstances.addAccessConfig
method.For IPv4 addresses, make the following request:
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/addAccessConfig{"natIP": "IPV4_ADDRESS","name": "ACCESS_CONFIG_NAME"}
For IPv6 addresses, update the
networkInterfaces[].ipv6AccessConfigs[].externalIpv6
property and the external IPv6 address that you want to use.
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.func assignStaticAddressToExistingVM(w io.Writer, projectID, zone, instanceName, IPAddress, networkInterfaceName string) 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)if err != nil {return fmt.Errorf("NewInstancesRESTClient: %w", err)}defer instancesClient.Close()reqGet := &computepb.GetInstanceRequest{Project: projectID,Zone: zone,Instance: instanceName,}instance, err := instancesClient.Get(ctx, reqGet)if err != nil {return fmt.Errorf("could not get instance: %w", err)}var networkInterface *computepb.NetworkInterfacefor _, ni := range instance.NetworkInterfaces {if *ni.Name == networkInterfaceName {networkInterface = nibreak}}if networkInterface == nil {return fmt.Errorf("No network interface named '%s' found on instance %s", networkInterfaceName, instanceName)}var accessConfig *computepb.AccessConfigfor _, ac := range networkInterface.AccessConfigs {if *ac.Type == computepb.AccessConfig_ONE_TO_ONE_NAT.String() {accessConfig = acbreak}}if accessConfig != 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)if err != nil {return fmt.Errorf("unable to delete access config: %w", err)}if err = opDelete.Wait(ctx); err != nil {return fmt.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)if err != nil {return fmt.Errorf("unable to add access config: %w", err)}if err = opAdd.Wait(ctx); err != nil {return fmt.Errorf("unable to wait for the operation: %w", err)}fmt.Fprintf(w, "Static address %s assigned to the instance %s\n", IPAddress, instanceName)return nil}
Java
import com.google.cloud.compute.v1.AccessConfig;import com.google.cloud.compute.v1.AccessConfig.Type;import com.google.cloud.compute.v1.Instance;import com.google.cloud.compute.v1.InstancesClient;import com.google.cloud.compute.v1.NetworkInterface;import java.io.IOException;import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeUnit;import java.util.concurrent.TimeoutException;public class AssignStaticExistingVm { public static void main(String[] args) throws IOException, 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. String projectId = "your-project-id"; // Instance ID of the Google Cloud project you want to use. String instanceId = "your-instance-id"; // Name of the zone to create the instance in. For example: "us-west3-b" String zone = "your-zone-id"; // Name of the network interface to assign. String netInterfaceName = "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. public static Instance assignStaticExistingVmAddress(String projectId, String instanceId, String zone, String netInterfaceName) throws IOException, 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 (InstancesClient client = InstancesClient.create()) { Instance instance = client.get(projectId, zone, instanceId); NetworkInterface networkInterface = null; for (NetworkInterface netInterface : instance.getNetworkInterfacesList()) { if (netInterface.getName().equals(netInterfaceName)) { networkInterface = netInterface; break; } } if (networkInterface == null) { throw new IllegalArgumentException( String.format( "No '{network_interface_name}' variable found on instance %s.", instanceId) ); } AccessConfig accessConfig = null; for (AccessConfig config : networkInterface.getAccessConfigsList()) { if (config.getType().equals(Type.ONE_TO_ONE_NAT.name())) { accessConfig = config; break; } } if (accessConfig != null) { // Delete the existing access configuration first client.deleteAccessConfigAsync(projectId, zone, instanceId, accessConfig.getName(), netInterfaceName) .get(30, TimeUnit.SECONDS); } // Add a new access configuration with the new IP AccessConfig newAccessConfig = 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 instance return client.get(projectId, zone, instanceId); } }}
Python
import uuidfrom google.cloud.compute_v1 import InstancesClientfrom google.cloud.compute_v1.types import AccessConfigfrom google.cloud.compute_v1.types import AddAccessConfigInstanceRequestfrom google.cloud.compute_v1.types import DeleteAccessConfigInstanceRequestdef assign_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( (ni for ni in instance.network_interfaces if ni.name == network_interface_name), None, ) if network_interface is None: raise ValueError( f"No network interface named '{network_interface_name}' found on instance {instance_name}." ) access_config = next( (ac for ac in network_interface.access_configs if ac.type_ == "ONE_TO_ONE_NAT"), None, ) if access_config: # Delete the existing access configuration first delete_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 IP add_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) return updated_instance
Restrict external IP addresses to specific VMs
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 VMs can use them. Thisoption can help to prevent data exfiltration ormaintain network isolation. Using anOrganization Policy,you can restrict external IP addresses to specific VMs withconstraints to control use of external IP addresses for your VMs within anorganization or a project.
The constraint for controlling external IP address on VMs is:
constraints/compute.vmExternalIpAccess
To use the constraint, you specify a policy with an allowedList
of VMs thatcan have external IP addresses. If you don't specify a policy, all external IPaddresses are allowed for all VMs. When the policy is in place, only the VMsthat are listed in the allowedValues
list can be assigned an external IPaddress, either ephemeral or static, and other Compute Engine VMs inthe organization or project that are not explicitly defined in the policy areprohibited from using external IP addresses.
VMs are identified in the allow and deny lists using the VM's URI:
projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
Specifications for restricting external IP addresses
- You can apply thislist constraintonly to VMs.
- You cannot apply the constraint retroactively. All VMs that haveexternal IP addresses before you enable the policy retain their external IPaddresses.
- This constraint accepts either an
allowedList
or adeniedList
but not bothin the same policy. - It is up to you or an administrator with the required permissions to manageand maintain the VM lifecycle and integrity. The constraint onlyverifies the VM's URI, and it does not prevent the VMs in the allowlist frombeing 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 the orgpolicy.policyAdmin
role on the organization.
Set the policy constraint at the organization level
Console
- Go to the Organizational Policies page.
- If necessary, select the required organization from the projectdrop-down menu.
- Click Define allowed external IPs for VM instances.
- Click Edit to edit the external IP policy. If you can't access theEdit tool, you don't have the correctpermissions.
Select Customize to set the org policy for specific VMs.
Select the required Policy enforcement and Policy type.
For Policy values, select Custom.
Enter a URI for a VM and press enter. The URI must be in thefollowing format:
projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
Click New policy value and enter URIs for VMs as needed.
Click Save 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/VM_NAME", "projects/PROJECT_ID/zones/ZONE/instances/VM_NAME", "projects/PROJECT_ID/zones/ZONE/instances/VM_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 VMVM_NAME
: the name of the VM
Alternatively, you can specify a deniedValues
list to indicate VMs thatyou explicitly want to prohibit from having an external IP address.Any VM not on the list would implicitly be allowed to have anexternal IP address. You can only specify either allowedValues
ordeniedValues
but not both.
Then, pass in the file with your request:
gcloud resource-manager org-policies set-policy MY_POLICY.JSON --organization=ORGANIZATION_ID
Replace ORGANIZATION_ID
with the numeric ID of theorganization.
If you don't want any VMs to have external IP access, you can set a policywith allValues
set to DENY
:
{ "constraint": "constraints/compute.vmExternalIpAccess", "listPolicy": { "allValues": "DENY" }}
REST
Use thesetOrgPolicy()
APIto define your constraint. The VMs in the allowedValue
list youspecify are allowed to have external IP addresses. Alternatively, you canspecify a deniedValues
list to express VMs that you explicitlywant to prohibit from having an external IP address. Any VM not on thelist would implicitly be allowed to have an external IP address. You canonly specify either allowedValues
or deniedValues
but not both.
For example, the following is a request to apply thecompute.vmExternalIpAccess
constraint to an organization where VMsfrom certain projects within the organization are allowed to haveexternal IP addresses:
POST https://cloudresourcemanager.googleapis.com/v1/organizations/ORGANIZATION_ID:setOrgPolicy
where ORGANIZATION_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/VM_NAME", "projects/PROJECT_ID/zones/ZONE/instances/VM_NAME", "projects/PROJECT_ID/zones/ZONE/instances/VM_NAME" ] } } }
If you don't want any VMs to have external IP access, you can set apolicy with allValues
set to DENY
:
{ "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 has example-vm-1
on theallowedValues
list but the policy at the project level has the same VMon the deniedValues
list, the VM 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.
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/VM_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 VM.VM_NAME
: the name of the VM.
Alternatively, you can specify a deniedValues
list of VMs that youexplicitly want to prohibit from having an external IP address. Any VMnot on the list would implicitly be allowed to have an external IP address.You can only specify either allowedValues
or deniedValues
but not both.
Then, pass in the file with your request:
gcloud resource-manager org-policies set-policy MY_POLICY.JSON --project=example-project
REST
Use thesetOrgPolicy
APIto define your constraint. The VMs in the allowedValue
list you specifyare allowed to have external IP addresses. Alternatively, you can specify adeniedValues
list to express VMs that you explicitly want to prohibit fromhaving an external IP address. Any VM not on the list is implicitlyallowed to have an external IP address. You can only specify eitherallowedValues
or deniedValues
but not both.
For example, the following is a request to set thecompute.vmExternalIpAccess
constraint on a project to allow specific VMsto have external IP addresses:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setOrgPolicy
Replace PROJECT_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/VM_NAME" ] } }}
Best practices for restricting external IP addresses
Avoid using the
deniedValues
list with thisconstraint. If you define values in thedeniedValues
list, it means thatonly the VMs in thedeniedValues
list are restricted from using externalIP addresses. This could be a security concern if you want control overexactly which VMs can have external IP addresses. If you want to removecertain VMs from theallowedValues
list, update the existing policyto remove the VMs from theallowedList
rather than putting theVMs 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 usingthe
setOrgPolicy
method by specifying therestoreDefault
object to allow all VMs in the projects to be associated with external IPaddresses. The current policies for projects are not affectedby the default setting.Use the org policy together with IAM roles to better control your environment.This policy applies to only VMs but if you want to better control andrestrict external IP addresses on network devices, you can grant the
compute.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 VMs.
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:
In the Google Cloud console, go to the IP addresses page.
Find the address in the list and check the Type column for the type ofIP address.
Unassign a static external IP address
Unassigning an IP address removes it from the resource butkeeps the IP address reserved. After the IP address is unassigned, you canreassign the IP address to another resource.
You can also unassign the IPv4 or IPv6 address bydeleting the VM.
Console
In the Google Cloud console, go to the IP addresses page.
Click External IP addresses.
Select the static IP address that you want to unassign.
Click Change to open the Attach IP address dialog.
From the Attach to drop-down list, select None.
Click OK.
gcloud
Check if a static IP address is in use by using the
gcloud compute addresses list
command:gcloud compute addresses list
The output is similar to the following:
NAME REGION ADDRESS STATUSexample-address-ipv4 REGION 198.51.100.1 RESERVEDexample-address-new-ipv4 REGION 203.0.113.1 IN_USEexample-address-ipv6 REGION 2001:db8:1:1:1:1:1:1 RESERVEDexample-address-new-ipv6 REGION 2001:db8:4:4:4:4:4:4 IN_USE
- If the IP address is not in use, the status is
RESERVED
. - If the IP address is in use, the status is
IN_USE
.
- If the IP address is not in use, the status is
Retrieve the name of the VM that is using the IP address:
gcloud compute addresses describe ADDRESS_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/VM_NAME
The
users
field displays the name of the VM that is using the IPaddress.Unassign the IP address from the VM.
To unassign an IPv4 address, delete the VM's access config file:
Get the name of the access config to delete. To get the name,use the
gcloud compute instances describe
command.ReplaceVM_NAME
with the name of the VM.gcloud compute instances describe VM_NAME
The access config appears in the following format:
networkInterfaces: - accessConfigs: - kind: compute#accessConfig name: external-nat natIP: 203.0.113.1 type: ONE_TO_ONE_NAT
Delete the access config by using the
gcloud compute instances delete-access-config
command:gcloud compute instances delete-access-config VM_NAME \ --access-config-name="ACCESS_CONFIG_NAME"
Replace the following:
VM_NAME
: the name of the VM.ACCESS_CONFIG_NAME
: the name of theaccess config to delete. Be sure to include the full namebetween quotes.
To unassign an IPv6 address range, use the
instance network-interfaces update
command:gcloud compute instances network-interfaces update VM_NAME \ --network-interface=nic0 \ --stack-type=IPV4_ONLY \ --zone=ZONE
Replace the following:
VM_NAME
: the name of the VMthat is using the IP address.ZONE
: the zone of the VM.
Check that your static external IP address is now available and marked as
RESERVED
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 VM.
REST
To unassign a static external IPv4 or IPv6 address, perform the followingsteps:
For IPv4 addresses, delete the access configuration attached to the VMthat's using the address.
To check the access configuration details of a VM, make a
GET
request to theinstances.get
method.GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
Delete the existing access configuration by making a
POST
request to theinstances.deleteAccessConfig
method.POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/deleteAccessConfig
Replace the following:
PROJECT_ID
: the project ID for thisrequestZONE
: the zone where the VM is locatedVM_NAME
: the name of the VM
For IPv6 addresses, update the stack type of the networkinterface for the VM where the IPv6 address is attached.
Make a
PATCH
request to theinstances.updateNetworkInterface
method.In the request body, update the value of the
stackType
field toIPV4_ONLY
.For example:
PATCH https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/updateNetworkInterface{ "networkInterfaces": [{ ... "stackType" : "IPV4_ONLY" ... }]}
Java
import com.google.cloud.compute.v1.AccessConfig;import com.google.cloud.compute.v1.AccessConfig.Type;import com.google.cloud.compute.v1.Instance;import com.google.cloud.compute.v1.InstancesClient;import com.google.cloud.compute.v1.NetworkInterface;import java.io.IOException;import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeUnit;import java.util.concurrent.TimeoutException;public class UnassignStaticIpAddress { public static void main(String[] args) throws IOException, 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. String projectId = "your-project-id"; // Instance ID of the Google Cloud project you want to use. String instanceId = "your-instance-id"; // Name of the zone to create the instance in. For example: "us-west3-b" String zone = "your-zone"; // Name of the network interface to assign. String netInterfaceName = "your-netInterfaceName"; unassignStaticIpAddress(projectId, instanceId, zone, netInterfaceName); } public static Instance unassignStaticIpAddress(String projectId, String instanceId, String zone, String netInterfaceName) throws IOException, 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 (InstancesClient client = InstancesClient.create()) { Instance instance = client.get(projectId, zone, instanceId); NetworkInterface networkInterface = null; for (NetworkInterface netIterface : instance.getNetworkInterfacesList()) { if (netIterface.getName().equals(netInterfaceName)) { networkInterface = netIterface; break; } } if (networkInterface == null) { throw new IllegalArgumentException( String.format( "No '{network_interface_name}' variable found on instance %s.", instanceId) ); } AccessConfig accessConfig = null; for (AccessConfig config : networkInterface.getAccessConfigsList()) { if (config.getType().equals(Type.ONE_TO_ONE_NAT.name())) { accessConfig = config; break; } } if (accessConfig != null) { // Delete the existing access configuration first client.deleteAccessConfigAsync(projectId, zone, instanceId, accessConfig.getName(), netInterfaceName).get(30, TimeUnit.SECONDS); } // return updated instance return client.get(projectId, zone, instanceId); } }}
Python
import uuidfrom google.cloud.compute_v1 import InstancesClientfrom google.cloud.compute_v1.types import DeleteAccessConfigInstanceRequestdef unassign_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( (ni for ni in instance.network_interfaces if ni.name == network_interface_name), None, ) if network_interface is None: raise ValueError( f"No network interface named '{network_interface_name}' found on instance {instance_name}." ) access_config = next( (ac for ac in network_interface.access_configs if ac.type_ == "ONE_TO_ONE_NAT"), None, ) if access_config: # Delete the existing access configuration delete_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) return updated_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 a VM does notautomatically 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
- Learn more about IP addresses.
- Learn more about networks and firewalls.
- Learn how toaddress VMs using internal DNS.
- Review VPC pricing.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2024-09-10 UTC.
[{ "type": "thumb-down", "id": "hardToUnderstand", "label":"Hard to understand" },{ "type": "thumb-down", "id": "incorrectInformationOrSampleCode", "label":"Incorrect information or sample code" },{ "type": "thumb-down", "id": "missingTheInformationSamplesINeed", "label":"Missing the information/samples I need" },{ "type": "thumb-down", "id": "otherDown", "label":"Other" }] [{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Easy to understand" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Solved my problem" },{ "type": "thumb-up", "id": "otherUp", "label":"Other" }]