Configurare indirizzi IP esterni statici


Puoi assegnare indirizzi IP esterni statici alle tue macchine virtuali (VM) e alle istanze bare metal. Puoi anche modificare, elencare e rilasciare indirizzi IP statici per le tue istanze. Per prenotare un indirizzo IP esterno statico, consulta Prenotare un indirizzo IP esterno statico.

Gli indirizzi IP esterni possono essere statici o temporanei. Se un'istanza richiede un indirizzo IP esterno fisso che non cambia, svolgi quanto segue:

  1. Ottieni un indirizzo IP esterno statico. Puoi prenotare nuovi indirizzi IP esterni o promuovere indirizzi IP esterni temporanei esistenti.
  2. Assegna l'indirizzo IP riservato a un'istanza esistente o quando crei una nuova istanza.

Se hai bisogno di un indirizzo IP statico sulla tua rete Compute Engine interna, consulta Prenota un indirizzo IP interno statico.

Per informazioni su come prenotare un indirizzo IP esterno statico o creare un indirizzo IP esterno globale, consulta Prenotare un indirizzo IP esterno statico.

Prima di iniziare

  • Scopri di più sugli indirizzi IP.
  • Scopri di più su quote e limiti per gli indirizzi IP esterni statici.
  • Scopri di più sui prezzi degli indirizzi IP esterni.
  • Se non l'hai ancora fatto, configura l'autenticazione. L'autenticazione è la procedura mediante la quale la tua identità viene verificata per l'accesso ai servizi e alle API di Google Cloud . Per eseguire codice o esempi da un ambiente di sviluppo locale, puoi autenticarti su Compute Engine selezionando una delle seguenti opzioni:

    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

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. Terraform

      Per utilizzare gli esempi di Terraform in questa pagina in un ambiente di sviluppo locale, installa e inizializza gcloud CLI, quindi configura le Credenziali predefinite dell'applicazione con le tue credenziali utente.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. 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.

      Per ulteriori informazioni, consulta Set up authentication for a local development environment.

      REST

      Per utilizzare gli esempi dell'API REST in questa pagina in un ambiente di sviluppo locale, utilizza le credenziali fornite a gcloud CLI.

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      Per saperne di più, consulta Eseguire l'autenticazione per l'utilizzo di REST nella documentazione sull'autenticazione di Google Cloud .

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per configurare e gestire gli indirizzi IP statici, chiedi all'amministratore di concederti i seguenti ruoli IAM nel progetto:

Per saperne di più sulla concessione dei ruoli, consulta Gestire l'accesso a progetti, cartelle e organizzazioni.

Questi ruoli predefiniti contengono le autorizzazioni necessarie per configurare e gestire gli indirizzi IP statici. Per visualizzare le autorizzazioni esatte richieste, espandi la sezione Autorizzazioni richieste:

Autorizzazioni obbligatorie

Per configurare e gestire gli indirizzi IP statici sono richieste le seguenti autorizzazioni:

  • compute.instances.update nell'istanza
  • compute.instances.updateNetworkInterface nell'istanza
  • compute.instances.addAccessConfig nell'istanza
  • compute.instances.deleteAccessConfig nell'istanza
  • compute.networks.list sulla rete
  • compute.subnetworks.use nella subnet
  • compute.subnetworks.list nella subnet
  • Per creare istanze:
    • compute.instances.create sul progetto
    • Per utilizzare un'immagine personalizzata per creare la VM: compute.images.useReadOnly sull'immagine
    • Per utilizzare uno snapshot per creare la VM: compute.snapshots.useReadOnly sullo snapshot
    • Per utilizzare un modello di istanza per creare la VM: compute.instanceTemplates.useReadOnly nel modello di istanza
    • Per assegnare una rete legacy alla VM: compute.networks.use nel progetto
    • Per specificare un indirizzo IP statico per la VM: compute.addresses.use nel progetto
    • Per assegnare un indirizzo IP esterno alla VM quando nel progetto viene utilizzata una rete precedente: compute.networks.useExternalIp
    • Per specificare una subnet per la VM: compute.subnetworks.use nel progetto o nella subnet scelta
    • Per assegnare un indirizzo IP esterno alla VM quando utilizzi una rete VPC: compute.subnetworks.useExternalIp nel progetto o nella subnet scelta
    • Per impostare i metadati dell'istanza VM per la VM: compute.instances.setMetadata nel progetto
    • Per impostare i tag per la VM: compute.instances.setTags sulla VM
    • Per impostare le etichette per la VM: compute.instances.setLabels sulla VM
    • Per impostare un account di servizio per consentire alla VM di utilizzare: compute.instances.setServiceAccount sulla VM
    • Per creare un nuovo disco per la VM: compute.disks.create nel progetto
    • Per collegare un disco esistente in modalità di sola lettura o di lettura e scrittura: compute.disks.use sul disco
    • Per collegare un disco esistente in modalità di sola lettura: compute.disks.useReadOnly sul disco

Potresti anche ottenere queste autorizzazioni con ruoli personalizzati o altri ruoli predefiniti.

Limitazioni

  • Solo una risorsa alla volta può utilizzare un indirizzo IP esterno statico.

  • Non è possibile verificare se un indirizzo IP è statico o temporaneo dopo che è stato assegnato a una risorsa. Puoi confrontare l'indirizzo IP con l'elenco di indirizzi IP esterni statici riservati al progetto. Utilizza il comando secondario gcloud compute addresses list per visualizzare un elenco di indirizzi IP esterni statici disponibili per il progetto.

  • Ogni VM può avere più interfacce di rete e a ogni interfaccia possono essere assegnati i seguenti indirizzi IP in base al tipo di stack:

    • Interfacce solo IPv4:
      • Un indirizzo IPv4 interno (obbligatorio)
      • Un indirizzo IPv4 esterno (facoltativo)
    • Interfacce a doppio stack (IPv4 e IPv6):
      • Un indirizzo IPv4 interno (obbligatorio)
      • Un indirizzo IPv4 esterno (facoltativo)
      • Un intervallo di indirizzi IPv6 /96, interno o esterno, ma non entrambi (obbligatorio)
    • Interfacce solo IPv6 (anteprima):
      • Un intervallo di indirizzi IPv6 /96, interno o esterno, ma non entrambi (obbligatorio)
  • Non puoi annullare l'assegnazione o modificare l'indirizzo IPv6 esterno di una VM con un'interfaccia di rete solo IPv6. Tuttavia, puoi promuovere un indirizzo IP esterno temporaneo di una risorsa a un indirizzo IP esterno statico in modo che rimanga riservato anche dopo l'eliminazione della risorsa.

  • Non puoi modificare il nome di un indirizzo IP statico.

Nota: le interfacce di rete possono ricevere traffico da più regole di inoltro, che potrebbero servire altri indirizzi IP esterni. Qualsiasi numero di indirizzi IP esterni può fare riferimento a un'interfaccia di rete tramite queste regole di inoltro, ma a ogni interfaccia di rete può essere assegnato un solo indirizzo IPv4 esterno e un solo intervallo di indirizzi IPv6 /96 esterni.

Per ulteriori informazioni sul bilanciamento del carico e sulle regole di inoltro, consulta la documentazione sul bilanciamento del carico.

Visualizzare gli indirizzi IP esterni statici disponibili

Per elencare gli indirizzi IP esterni statici che hai prenotato per il tuo progetto:

Console

  1. Nella console Google Cloud , vai alla pagina Indirizzi IP.

    Vai a indirizzi IP

  2. Fai clic su Indirizzi IP esterni.

gcloud

Utilizza il comando gcloud compute addresses list:

  • Per elencare tutti gli indirizzi IP, utilizza il seguente comando:

    gcloud compute addresses list
  • Per elencare tutti gli indirizzi IP globali, utilizza il seguente comando:

    gcloud compute addresses list --global
  • Per elencare tutti gli indirizzi IP regionali in una determinata regione, utilizza il seguente comando:

    gcloud compute addresses list \
        --regions=REGION
    

    Sostituisci REGION con la regione per cui vuoi elencare gli indirizzi. Puoi elencare gli indirizzi di più regioni specificando i nomi delle regioni separati da virgole:

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

API

  • Per elencare gli indirizzi IPv4 o IPv6 regionali, chiama il metodo addresses.list:

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

    Sostituisci quanto segue:

    • PROJECT_ID: l'ID progetto per questa richiesta
    • REGION: il nome della regione per questa richiesta
  • Per elencare tutti gli indirizzi in tutte le regioni, chiama il metodo addresses.aggregatedList:

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/aggregated/addresses
    
  • Per elencare gli indirizzi IPv4 o IPv6 globali, chiama il metodo globalAddresses.list:

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

    Sostituisci quanto segue:

    PROJECT_ID: l'ID progetto per questa richiesta

Vai

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.Address
	for {
		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.Address
	for {
		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, Optional

from google.cloud.compute_v1.services.addresses.client import AddressesClient
from google.cloud.compute_v1.services.global_addresses import GlobalAddressesClient
from google.cloud.compute_v1.types import Address


def 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

Configurare indirizzi IP esterni statici

Le sezioni seguenti descrivono come configurare indirizzi IP esterni statici per le istanze.

Crea un'istanza che utilizza un indirizzo IP esterno statico

Dopo aver prenotato un indirizzo IP esterno statico, puoi assegnarlo a un'istanza.

Console

  1. Nella console Google Cloud , vai alla pagina Crea un'istanza.

    Vai a Crea un'istanza

  2. Specifica i dettagli dell'istanza.

  3. Espandi la sezione Opzioni avanzate.

  4. Espandi la sezione Networking.

  5. Nella sezione Interfacce di rete, espandi un'interfaccia di rete per modificarla.

  6. Per assegnare un indirizzo IPv4:

    1. Seleziona una rete.
    2. Seleziona l'indirizzo IP dall'elenco Indirizzo IPv4 esterno.
  7. Per assegnare un indirizzo IPv6:

    1. Seleziona una rete che contenga una subnet con un intervallo di indirizzi IPv6 esterni.
    2. Seleziona la subnet dall'elenco Subnet.
    3. Per Tipo di stack IP, seleziona IPv4 e IPv6 (stack doppio) o IPv6 (stack singolo).
    4. Seleziona l'indirizzo IPv6 esterno appena prenotato dall'elenco Indirizzo IPv6 esterno. In alternativa, seleziona Prenota indirizzo IPv6 esterno statico e prenota un nuovo indirizzo IPv6 esterno statico.
    5. In Network Service Tier (Livello di servizio di rete), seleziona Premium.
  8. Per completare la modifica dell'interfaccia di rete predefinita, fai clic su Fine.

  9. Continua con la procedura di creazione dell'istanza.

gcloud

Puoi creare un'istanza e assegnare un indirizzo IP esterno regionale statico che hai già prenotato.

  • Per assegnare un indirizzo IPv4 esterno statico, procedi nel seguente modo:

    gcloud compute instances create INSTANCE_NAME \
        --zone=ZONE \
        --address=IPV4_ADDRESS
    
  • Per assegnare un indirizzo IPv6 esterno statico, procedi nel seguente modo:

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

    Sostituisci quanto segue:

    • INSTANCE_NAME: il nome dell'istanza di calcolo.
    • ZONE: la zona in cui creare l'istanza
    • IPV4_ADDRESS: l'indirizzo IPv4 da assegnare all'istanza. Utilizza l'indirizzo IP esterno statico prenotato, non il nome dell'indirizzo.
    • SUBNET: una subnet contenente indirizzi IPv6 esterni
    • STACK_TYPE: il tipo di stack per l'istanza, IPV4_IPV6 (doppio stack) o IPV6_ONLY
    • IPV6_ADDRESS: l'indirizzo IPv6 da assegnare all'istanza. Utilizza l'indirizzo IP esterno statico prenotato, non il nome dell'indirizzo.

Terraform

Puoi utilizzare la risorsa google_compute_instance per assegnare un indirizzo IP esterno.

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

  • Per assegnare un indirizzo IPv4 esterno statico a una nuova istanza di calcolo:

    Nella richiesta per creare una nuova istanza, fornisci esplicitamente la proprietà networkInterfaces[].accessConfigs[].natIP e l'indirizzo IPv4 esterno che vuoi utilizzare, ad esempio:

    {
      "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"
             }
      }]
    }
    

    Sostituisci quanto segue:

    • INSTANCE_NAME: il nome dell'istanza di calcolo
    • ZONE: la zona in cui creare l'istanza
    • MACHINE_TYPE: facoltativo, un URL completo o parziale della risorsa del tipo di macchina da utilizzare per la creazione dell'istanza, nel formato: zones/ZONE/machineTypes/MACHINE_TYPE
    • IPV4_ADDRESS: l'indirizzo IPv4 da assegnare all'istanza. Utilizza l'indirizzo IP esterno statico prenotato, non il nome dell'indirizzo.
    • SOURCE_IMAGE: una versione specifica di un'immagine pubblica, ad esempioprojects/debian-cloud/global/images/debian-10-buster-v20200309 o una famiglia di immagini, ad esempioprojects/debian-cloud/global/images/family/debian-10
  • Per assegnare un indirizzo IPv6 esterno statico a una nuova istanza, procedi nel seguente modo:

    Nella richiesta di creazione di una nuova istanza, fornisci esplicitamente la proprietà networkInterfaces[].ipv6AccessConfigs[].externalIpv6 e l'indirizzo IPv6 esterno che vuoi utilizzare, ad esempio:

    {
      "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"
          },
      }],
    }
    

    Sostituisci quanto segue:

    • INSTANCE_NAME: il nome dell'istanza di calcolo
    • ZONE: la zona in cui creare l'istanza
    • MACHINE_TYPE: facoltativo: un URL completo o parziale della risorsa del tipo di macchina da utilizzare durante la creazione dell'istanza, nel formato: zones/ZONE/machineTypes/MACHINE_TYPE
    • IPV6_ADDRESS: l'indirizzo IPv6 da assegnare all'istanza. Utilizza l'indirizzo IP esterno statico prenotato, non il nome dell'indirizzo.
    • STACK_TYPE: il tipo di stack per l'istanza, IPV4_IPV6 (doppio stack) o IPV6_ONLY
    • SUBNET: una subnet contenente indirizzi IPv6 esterni
    • SOURCE_IMAGE: una versione specifica di un'immagine pubblica, ad esempio"projects/debian-cloud/global/images/debian-10-buster-v20200309" o una famiglia di immagini, ad esempio"projects/debian-cloud/global/images/family/debian-10"

Vai


// 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 VM
func 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.123

	ctx := 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 annotations

import re
import sys
from typing import Any
import warnings

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def 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_image


def 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_disk


def 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 result


def 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

Modificare o assegnare un indirizzo IP esterno a un'istanza esistente

Puoi modificare o assegnare un indirizzo IP esterno, temporaneo o statico, a un'istanza IPv4 o dual-stack esistente. Questa procedura non è supportata per le istanze solo IPv6.

Un'istanza di calcolo può avere più interfacce. Un'interfaccia a stack singolo può avere un indirizzo IP esterno. Un'interfaccia a doppio stack può avere un indirizzo IPv4 esterno e un indirizzo IPv6 esterno. Se l'istanza ha già un indirizzo IP esterno, devi prima rimuoverlo. Poi puoi assegnare un nuovo indirizzo IP esterno all'istanza esistente.

Console

  1. Nella console Google Cloud , vai alla pagina Istanze VM.

    Vai a Istanze VM

  2. Fai clic sul nome dell'istanza a cui vuoi assegnare un indirizzo IP esterno. Viene visualizzata la pagina Dettagli istanza.

  3. Nella pagina Dettagli istanza, completa i seguenti passaggi:

    1. Fai clic su Modifica.
    2. Espandi Interfacce di rete.
    3. Seleziona l'indirizzo IP esterno richiesto da assegnare all'istanza. Se l'istanza è solo IPv4 e vuoi assegnare un indirizzo IPv6, devi prima impostare il tipo di stack su doppio stack.
      1. Per Indirizzo IPv4 esterno, seleziona Temporaneo o un indirizzo IPv4 esterno statico.
      2. Per Indirizzo IPv6 esterno, seleziona Temporaneo o un indirizzo IPv6 esterno statico.
    4. Fai clic su Fine.
  4. Fai clic su Salva.

gcloud

  1. (Facoltativo) Prenota un indirizzo IP esterno statico.

    Se vuoi assegnare un indirizzo IP esterno statico, devi prenotarne uno e assicurarti che non sia in uso da un'altra risorsa. Se necessario, segui le istruzioni per prenotare un nuovo indirizzo IP esterno statico o per annullare l'assegnazione di un indirizzo IP esterno statico.

    Se intendi utilizzare un indirizzo IP esterno temporaneo, puoi saltare questo passaggio e Compute Engine assegnerà in modo casuale un indirizzo IP esterno temporaneo.

  2. Rimuovi eventuali assegnazioni di indirizzi IP esistenti, come descritto in Annullare l'assegnazione di un indirizzo IP esterno statico.

  3. Assegna il nuovo indirizzo IP esterno.

    • Per assegnare un indirizzo IPv4, utilizza il subcomando instances add-access-config:

      Nota: non sostituireIP_ADDRESS con il nome dell'indirizzo IP statico. Devi utilizzare l'indirizzo IP effettivo.
      gcloud compute instances add-access-config INSTANCE_NAME \
        --access-config-name="ACCESS_CONFIG_NAME" --address=IP_ADDRESS
      

      Sostituisci quanto segue:

      • INSTANCE_NAME: il nome dell'istanza.
      • ACCESS_CONFIG_NAME: il nome da assegnare a questa configurazione di accesso. Assicurati di includere il nome completo tra virgolette.
      • IP_ADDRESS: l'indirizzo IP da aggiungere.

      Se vuoi che Compute Engine assegni un indirizzo IP esterno temporaneo anziché utilizzare un indirizzo IP esterno statico, ometti la proprietà --address IP_ADDRESS:

      gcloud compute instances add-access-config INSTANCE_NAME \
        --access-config-name="ACCESS_CONFIG_NAME"
      
    • Per impostare un'istanza su doppio stack e assegnarle un indirizzo IPv6, utilizza il instance network-interfaces updatecomando secondario:

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

      Sostituisci quanto segue:

      • INSTANCE_NAME: il nome dell'istanza.
      • NIC: il nome dell'interfaccia di rete.
      • STACK_TYPE: il tipo di stack per l'istanza, che deve essere IPV4_IPV6. Non puoi impostare il tipo di stack su IPV6_ONLY.
      • IPV6_ADDRESS: l'indirizzo IPv6 da assegnare all'istanza. Specifica il primo indirizzo IPv6 nell'intervallo/96.
      • ZONE: la zona dell'istanza.

REST

Puoi modificare l'indirizzo IPv4 o IPv6 esterno di un'istanza aggiungendo una nuova configurazione di accesso per l'istanza.

  1. Rimuovi eventuali assegnazioni di indirizzi IP esistenti, come descritto in Annullare l'assegnazione di un indirizzo IP esterno statico.

  2. Elimina la configurazione di accesso esistente inviando una richiesta POST al metodo instances.deleteAccessConfig.

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/deleteAccessConfig
    
  3. Aggiungi una nuova configurazione di accesso all'interfaccia di rete dell'istanza inviando una richiesta POST al metodo instances.addAccessConfig.

Vai

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.NetworkInterface
	for _, ni := range instance.NetworkInterfaces {
		if *ni.Name == networkInterfaceName {
			networkInterface = ni
			break
		}
	}

	if networkInterface == nil {
		return fmt.Errorf("No network interface named '%s' found on instance %s", networkInterfaceName, instanceName)
	}

	var accessConfig *computepb.AccessConfig
	for _, ac := range networkInterface.AccessConfigs {
		if *ac.Type == computepb.AccessConfig_ONE_TO_ONE_NAT.String() {
			accessConfig = ac
			break
		}
	}

	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 uuid

from google.cloud.compute_v1 import InstancesClient
from google.cloud.compute_v1.types import AccessConfig
from google.cloud.compute_v1.types import AddAccessConfigInstanceRequest
from google.cloud.compute_v1.types import DeleteAccessConfigInstanceRequest


def 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

Limitare gli indirizzi IP esterni a istanze specifiche

Per determinati carichi di lavoro, potresti avere requisiti essenziali che includono limitazioni di sicurezza e di rete. Ad esempio, potresti voler limitare gli indirizzi IP esterni in modo che solo istanze di calcolo specifiche possano utilizzarli. Questa opzione può contribuire a impedire l'esfiltrazione di dati o mantenere l'isolamento della rete. Con un criterio dell'organizzazione, puoi limitare gli indirizzi IP esterni a istanze specifiche con vincoli per controllare l'utilizzo degli indirizzi IP esterni per le tue istanze all'interno di un'organizzazione o di un progetto.

Il vincolo per il controllo dell'indirizzo IP esterno sulle istanze è:

constraints/compute.vmExternalIpAccess

Per utilizzare la limitazione, specifica un criterio con un allowedList di istanze che possono avere indirizzi IP esterni. Se non specifichi un criterio, tutti gli indirizzi IP esterni sono consentiti per tutte le istanze. Quando il criterio è attivo, solo alle istanze elencate nell'elenco allowedValues può essere assegnato un indirizzo IP esterno, temporaneo o statico, mentre alle altre istanze Compute Engine dell'organizzazione o del progetto non definite esplicitamente nel criterio è vietato utilizzare indirizzi IP esterni.

Le istanze vengono identificate negli elenchi consentiti e vietati utilizzando l'URI dell'istanza:

projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME

Specifiche per la limitazione degli indirizzi IP esterni

  • Puoi applicare questa restrizione dell'elenco solo alle istanze.
  • Non puoi applicare il vincolo in modo retroattivo. Tutte le istanze che hanno indirizzi IP esterni prima dell'attivazione del criterio mantengono i propri indirizzi IP esterni.
  • Questo vincolo accetta un allowedList o un deniedList, ma non entrambi nella stessa norma.
  • Spetta a te o a un amministratore con le autorizzazioni richieste gestire e mantenere l'integrità e il ciclo di vita dell'istanza. La limitazione verifica solo l'URI dell'istanza e non impedisce che le istanze nella lista consentita vengano alterate, eliminate o ricreate.

Autorizzazioni necessarie per limitare gli indirizzi IP esterni

Per impostare un vincolo a livello di progetto o di organizzazione, devi avere ricevuto il ruolo orgpolicy.policyAdmin nell'organizzazione.

Imposta il vincolo dei criteri a livello di organizzazione

Console

  1. Vai alla pagina Criteri dell'organizzazione.

    Vai a Criteri dell'organizzazione

  2. Se necessario, seleziona l'organizzazione richiesta dal menu a discesa del progetto.
  3. Fai clic su Definisci IP esterni consentiti per le istanze VM.
  4. Fai clic su Modifica per modificare il criterio per gli IP esterni. Se non riesci ad accedere allo strumento Modifica, significa che non disponi delle autorizzazioni corrette.
  5. Seleziona Personalizza per impostare il criterio dell'organizzazione per istanze specifiche.

    Opzione Personalizza nella pagina di modifica del criterio dell&#39;organizzazione.

  6. Seleziona Applicazione delle norme e Tipo di norme.

  7. In Valori criterio, seleziona Personalizzato.

  8. Inserisci un URI per un'istanza. L'URI deve avere il seguente formato:

    projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME
    
  9. Fai clic su Nuovo valore criterio e inserisci gli URI per le istanze, se necessario.

  10. Fai clic su Salva per applicare la limitazione.

gcloud

Per impostare una limitazione per l'accesso IP esterno, devi prima avere l'ID della tua organizzazione. Puoi trovare l'ID organizzazione eseguendo il comando organizations list e cercando l'ID numerico nella risposta:

gcloud organizations list

Gcloud CLI restituisce un elenco di organizzazioni nel seguente formato:

DISPLAY_NAME               ID
example-organization1      29252605212
example-organization2      1234567890

Utilizza il comando gcloud resource-manager org-policies set-policy per impostare il criterio. Devi fornire i criteri come file JSON. Crea un file JSON nel seguente formato:

{
"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"
  ]
 }
}

Sostituisci quanto segue:

  • PROJECT_ID: l'ID progetto per questa richiesta, ad esempio example-project. Tieni presente che questa operazione è diversa dalla configurazione dei criteri dell'organizzazione, che richiedono l'ID numerico dell'organizzazione.
  • ZONE: la zona dell'istanza
  • INSTANCE_NAME: il nome dell'istanza

In alternativa, puoi specificare un elenco deniedValues per indicare le istanze a cui vuoi vietare esplicitamente di avere un indirizzo IP esterno. A qualsiasi istanza non presente nell'elenco sarebbe implicitamente consentito avere un indirizzo IP esterno. Puoi specificare solo allowedValues o deniedValues, ma non entrambi.

Quindi, passa il file con la richiesta:

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

Sostituisci ORGANIZATION_ID con l'ID numerico dell'organizzazione.

Se non vuoi che nessuna istanza abbia accesso all'IP esterno, puoi impostare un criterio con allValues impostato su DENY:

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

REST

Utilizza l'API setOrgPolicy() per definire la limitazione. Le istanze nell'elenco allowedValue che specifichi possono avere indirizzi IP esterni. In alternativa, puoi specificare un elenco deniedValues per indicare le istanze per le quali vuoi vietare esplicitamente l'assegnazione di un indirizzo IP esterno. A qualsiasi istanza non presente nell'elenco sarebbe implicitamente consentito avere un indirizzo IP esterno. Puoi specificare solo allowedValues o deniedValues, ma non entrambi.

Ad esempio, di seguito è riportata una richiesta di applicazione del vincolo compute.vmExternalIpAccess a un'organizzazione in cui le istanze di determinati progetti all'interno dell'organizzazione possono avere indirizzi IP esterni:

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

dove ORGANIZATION_ID è l'ID numerico dell'organizzazione.

Ora, nel corpo della richiesta, fornisci il criterio per questo vincolo:

{
  "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"
        ]
      }
    }
 }

Se non vuoi che nessuna istanza abbia accesso all'IP esterno, puoi impostare un criterio con allValues impostato su DENY:

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

Imposta il criterio a livello di progetto

L'impostazione di un criterio a livello di progetto sostituisce il criterio a livello di organizzazione. Ad esempio, se a livello di organizzazione è presente example-vm-1 nell'elencoallowedValues, ma il criterio a livello di progetto ha la stessa istanza nell'elencodeniedValues, all'istanza non sarà consentito avere un indirizzo IP esterno.

Console

Segui la stessa procedura descritta in Impostare un vincolo dei criteri a livello di organizzazione, ma scegli il progetto dal selettore dei progetti anziché dall'organizzazione.

Selettore di progetti.

gcloud

Utilizza il comando gcloud resource-manager org-policies set-policy per impostare il criterio. Devi fornire i criteri come file JSON. Crea un file JSON nel seguente formato:

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

Sostituisci quanto segue:

  • PROJECT_ID: l'ID progetto per questa richiesta, ad esempio example-project. Tieni presente che questa operazione è diversa dalla configurazione dei criteri dell'organizzazione, che richiedono l'ID numerico dell'organizzazione.
  • ZONE: la zona dell'istanza.
  • INSTANCE_NAME: il nome dell'istanza.

In alternativa, puoi specificare un deniedValueselenco di istanze per le quali vuoi vietare esplicitamente l'utilizzo di un indirizzo IP esterno. A qualsiasi istanza non presente nell'elenco sarà implicitamente consentito avere un indirizzo IP esterno. Puoi specificare solo allowedValues o deniedValues, ma non entrambi.

Quindi, passa il file con la richiesta:

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

REST

Utilizza l'API setOrgPolicy per definire la limitazione. Le istanze nell'elenco allowedValue che specifichi possono avere indirizzi IP esterni. In alternativa, puoi specificare un elenco deniedValues per indicare le istanze per le quali vuoi esplicitamente vietare l'utilizzo di un indirizzo IP esterno. A qualsiasi istanza non presente nell'elenco è implicitamente consentito avere un indirizzo IP esterno. Puoi specificare solo allowedValues o deniedValues, ma non entrambi.

Ad esempio, di seguito è riportata una richiesta per impostare il vincolo compute.vmExternalIpAccess su un progetto per consentire a istanze specifiche di avere indirizzi IP esterni:

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

Sostituisci PROJECT_ID con l'ID progetto per questa richiesta.

Il corpo della richiesta contiene il criterio per questo vincolo:

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

Best practice per limitare gli indirizzi IP esterni

  • Evita di utilizzare l'elenco deniedValues con questo vincolo. Se definisci valori nell'elenco deniedValues, significa che solo le istanze nell'elenco deniedValues non possono utilizzare indirizzi IP esterni. Questo potrebbe rappresentare un problema di sicurezza se vuoi controllare esattamente quali istanze possono avere indirizzi IP esterni. Se vuoi rimuovere determinate istanze dall'elenco allowedValues, aggiorna il criterio esistente per rimuoverle dall'elenco allowedValues anziché inserirle nell'elenco deniedValues in una gerarchia inferiore.allowedList

  • Se vuoi impostare un criterio su gran parte della gerarchia delle risorse, ma esentare determinati progetti, ripristina il criterio predefinito utilizzando il metodo setOrgPolicy specificando l'oggetto restoreDefault per consentire l'associazione di tutte le istanze dei progetti ad indirizzi IP esterni. I criteri attuali per i progetti non sono interessati dall'impostazione predefinita.

  • Utilizza i criteri dell'organizzazione insieme ai ruoli IAM per controllare meglio il tuo ambiente. Questo criterio si applica solo alle istanze, ma se vuoi controllare e limitare meglio gli indirizzi IP esterni sui dispositivi di rete, puoi concedere il ruolo compute.networkAdmin alle parti appropriate.

  • Tutti i servizi e i prodotti in esecuzione su Compute Engine all'interno dell'organizzazione o del progetto con il criterio abilitato sono soggetti a queste norme dell'organizzazione. Nello specifico, questo criterio riguarda servizi come Google Kubernetes Engine, Dataflow, Dataproc e Cloud SQL. Se si tratta di un problema, Google consiglia di configurare altri servizi e prodotti in un progetto diverso a cui non sono stati applicati i criteri dell'organizzazione e di utilizzare VPC condiviso, se necessario.

Gestire gli indirizzi IP esterni statici

Le sezioni seguenti descrivono come gestire gli indirizzi IP esterni statici per le tue istanze.

Determinare se un indirizzo IP interno è temporaneo o statico

Gli indirizzi IP interni statici e temporanei si comportano e appaiono allo stesso modo nella maggior parte dei contesti. Tuttavia, con gli indirizzi IP interni statici, puoi utilizzare lo stesso indirizzo IP per la stessa risorsa anche se la elimini e la ricrei. In genere, un indirizzo IP temporaneo viene rilasciato se interrompi o elimini la risorsa.

Per determinare se un indirizzo è statico o temporaneo:

  1. Nella console Google Cloud , vai alla pagina Indirizzi IP.

    Vai a indirizzi IP

  2. Individua l'indirizzo nell'elenco e controlla la colonna Tipo per conoscere il tipo di indirizzo IP.

Annullare l'assegnazione di un indirizzo IP esterno statico

Se annulli l'assegnazione di un indirizzo IP, questo viene rimosso dalla risorsa, ma rimane riservato. Una volta che l'indirizzo IP è stato disassociato, puoi riassegnare l'indirizzo IP a un'altra risorsa. Questa procedura è supportata per le istanze a doppio stack, ma non per quelle solo IPv6.

Puoi anche annullare l'assegnazione dell'indirizzo IPv4 o IPv6 eliminando l'istanza.

Console

  1. Nella console Google Cloud , vai alla pagina Indirizzi IP.

    Vai a indirizzi IP

  2. Fai clic su Indirizzi IP esterni.

  3. Seleziona l'indirizzo IP statico di cui vuoi annullare l'assegnazione.

  4. Fai clic su Visualizza azioni e seleziona l'opzione Riassegna a un'altra risorsa.

  5. Nell'elenco a discesa Allega a, seleziona Nessuno.

  6. Fai clic su OK.

gcloud

  1. Controlla se è in uso un indirizzo IP statico utilizzando il comando gcloud compute addresses list:

    gcloud compute addresses list
    

    L'output è simile al seguente:

    NAME                      REGION    ADDRESS                  STATUS
    example-address-ipv4      REGION    198.51.100.1             RESERVED
    example-address-new-ipv4  REGION    203.0.113.1              IN_USE
    example-address-ipv6      REGION    2001:db8:1:1:1:1:1:1     RESERVED
    example-address-new-ipv6  REGION    2001:db8:4:4:4:4:4:4     IN_USE
    
    • Se l'indirizzo IP non è in uso, lo stato è RESERVED.
    • Se l'indirizzo IP è in uso, lo stato è IN_USE.
  2. Recupera il nome dell'istanza che utilizza l'indirizzo IP:

    gcloud compute addresses describe ADDRESS_NAME \
      --region=REGION
    

    Sostituisci quanto segue:

    • ADDRESS_NAME: il nome della risorsa dell'indirizzo IPv6.
    • REGION: la regione della risorsa indirizzo IPv6.

    L'output è simile al seguente:

    address: IP_ADDRESS
    addressType: EXTERNAL
    ...
    region: https://www.googleapis.com/compute/v1/projects/PROJECT/regions/REGION
    selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT/regions/REGION/addresses/ADDRESS_NAME
    status: IN_USE
    subnetwork: https://www.googleapis.com/compute/v1/projects/PROJECT/regions/REGION/subnetworks/SUBNET
    users:
    - https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/instances/INSTANCE_NAME
    

    Il campo users mostra il nome dell'istanza che utilizza l'indirizzo IP.

  3. Annullare l'assegnazione dell'indirizzo IP all'istanza.

    • Per annullare l'assegnazione di un indirizzo IPv4, elimina il file di configurazione dell'accesso dell'istanza:

      1. Recupera il nome della configurazione di accesso da eliminare. Per ottenere il nome, utilizza il comando gcloud compute instances describe. Sostituisci INSTANCE_NAME con il nome dell'istanza.

        gcloud compute instances describe INSTANCE_NAME
        

        La configurazione dell'accesso viene visualizzata nel seguente formato:

        networkInterfaces:
          - accessConfigs:
            - kind: compute#accessConfig
              name: external-nat
              natIP: 203.0.113.1
              type: ONE_TO_ONE_NAT
        
      2. Elimina la configurazione di accesso utilizzando il comando gcloud compute instances delete-access-config:

        gcloud compute instances delete-access-config INSTANCE_NAME \
          --access-config-name="ACCESS_CONFIG_NAME"
        

        Sostituisci quanto segue:

        • INSTANCE_NAME: il nome dell'istanza.
        • ACCESS_CONFIG_NAME: il nome della configurazione di accesso da eliminare. Assicurati di includere il nome completo tra virgolette.
    • Per annullare l'assegnazione di un intervallo di indirizzi IPv6, utilizza il comando instance network-interfaces update:

      gcloud compute instances network-interfaces update INSTANCE_NAME \
        --network-interface=nic0 \
        --stack-type=IPV4_ONLY \
        --zone=ZONE
      

      Sostituisci quanto segue:

      • INSTANCE_NAME: il nome dell'istanza che utilizza l'indirizzo IP.
      • ZONE: la zona dell'istanza.
  4. Verifica che l'indirizzo IP esterno statico sia ora disponibile e contrassegnato come RESERVED anziché IN_USE.

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

    Sostituisci quanto segue:

    • ADDRESS_NAME: il nome della risorsa dell'indirizzo IP.
    • REGION: la regione della risorsa indirizzo IP.

Ora che il tuo indirizzo IP esterno statico è disponibile, puoi scegliere di assegnarlo a un'altra istanza.

REST

Per annullare l'assegnazione di un indirizzo IPv4 o IPv6 esterno statico, svolgi i seguenti passaggi:

  • Per gli indirizzi IPv4, elimina la configurazione di accesso associata all'istanza che utilizza l'indirizzo.

    1. Per controllare i dettagli della configurazione di accesso di un'istanza, effettua una richiesta GET al metodo instances.get.

      GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME
      
    2. Elimina la configurazione di accesso esistente inviando una richiesta POST al metodo instances.deleteAccessConfig.

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

      Sostituisci quanto segue:

      • PROJECT_ID: l'ID progetto per questa richiesta
      • ZONE: la zona in cui si trova l'istanza
      • INSTANCE_NAME: il nome dell'istanza
  • Per gli indirizzi IPv6, aggiorna il tipo di stack dell'interfaccia di rete per l'istanza a cui è collegato l'indirizzo IPv6.

    1. Invia una richiesta PATCH al metodo instances.updateNetworkInterface.

    2. Nel corpo della richiesta, aggiorna il valore del campo stackType in IPV4_ONLY.

      Ad esempio:

      PATCH https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_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 uuid

from google.cloud.compute_v1 import InstancesClient
from google.cloud.compute_v1.types import DeleteAccessConfigInstanceRequest


def 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

Rilasciare un indirizzo IP esterno statico

Se non hai più bisogno di un indirizzo IPv4 o IPv6 esterno statico, puoi rilasciarlo eliminando la risorsa indirizzo IP. L'eliminazione di un'istanza non comporta il rilascio automatico di un indirizzo IP esterno statico. Devi rilasciare manualmente gli indirizzi IP esterni statici quando non sono più necessari.

Per rilasciare un indirizzo IP esterno statico, consulta Rilasciare un indirizzo IP esterno statico nella documentazione di VPC.

Passaggi successivi