Configurer des adresses IP externes statiques


Vous pouvez attribuer des adresses IP externes statiques à vos instances de machine virtuelle (VM) et bare metal. Vous pouvez également modifier, lister et libérer des adresses IP statiques pour vos instances. Pour réserver une adresse IP externe statique, consultez la page Réserver une adresse IP externe statique.

Les adresses IP externes peuvent être statiques ou éphémères. Si une instance requiert une adresse IP externe fixe qui ne change pas, procédez comme suit:

  1. Obtenez une adresse IP externe statique. Vous pouvez réserver de nouvelles adresses IP externes ou convertir des adresses IP externes éphémères existantes.
  2. Attribuez l'adresse IP réservée à une instance existante, ou attribuez-la lors de la création d'une instance.

Si vous avez besoin d'une adresse IP statique sur votre réseau interne Compute Engine, consultez la page Réserver une adresse IP interne statique.

Pour savoir comment réserver une adresse IP externe statique ou créer une adresse IP externe globale, consultez la page Réserver une adresse IP externe statique.

Avant de commencer

  • En savoir plus sur les adresses IP.
  • En savoir plus sur les quotas et limites pour les adresses IP externes statiques.
  • Consultez la section sur la tarification des adresses IP externes.
  • Si ce n'est pas déjà fait, configurez l'authentification. L'authentification est le processus permettant de valider votre identité pour accéder aux services et aux API Google Cloud . Pour exécuter du code ou des exemples depuis un environnement de développement local, vous pouvez vous authentifier auprès de Compute Engine en sélectionnant l'une des options suivantes:

    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

      Pour utiliser les exemples Terraform de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

      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.

      Pour en savoir plus, consultez Set up authentication for a local development environment.

      REST

      Pour utiliser les exemples d'API REST de cette page dans un environnement de développement local, vous devez utiliser les identifiants que vous fournissez à gcloud CLI.

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

        gcloud init

      Pour en savoir plus, consultez la section S'authentifier pour utiliser REST dans la documentation sur l'authentification Google Cloud.

Rôles requis

Pour obtenir les autorisations nécessaires pour configurer et gérer des adresses IP statiques, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

Pour en savoir plus sur l'attribution de rôles, consultez la page Gérer l'accès aux projets, aux dossiers et aux organisations.

Ces rôles prédéfinis contiennent les autorisations requises pour configurer et gérer des adresses IP statiques. Pour connaître les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

Vous devez disposer des autorisations suivantes pour configurer et gérer des adresses IP statiques :

  • compute.instances.update sur l'instance
  • compute.instances.updateNetworkInterface sur l'instance
  • compute.instances.addAccessConfig sur l'instance
  • compute.instances.deleteAccessConfig sur l'instance
  • compute.networks.list sur le réseau
  • compute.subnetworks.use sur le sous-réseau
  • compute.subnetworks.list sur le sous-réseau
  • Pour créer des instances :
    • compute.instances.create sur le projet
    • Pour créer la VM à l'aide d'une image personnalisée : compute.images.useReadOnly sur l'image
    • Pour créer la VM à l'aide d'un instantané : compute.snapshots.useReadOnly sur l'instantané
    • Pour créer la VM à l'aide d'un modèle d'instance : compute.instanceTemplates.useReadOnly sur le modèle d'instance
    • Pour attribuer un ancien réseau à la VM : compute.networks.use sur le projet
    • Pour spécifier une adresse IP statique pour la VM : compute.addresses.use sur le projet
    • Pour attribuer une adresse IP externe à la VM, en cas d'utilisation d'un ancien réseau : compute.networks.useExternalIp sur le projet
    • Pour spécifier un sous-réseau pour la VM : compute.subnetworks.use sur le projet ou sur le sous-réseau choisi
    • Pour attribuer une adresse IP externe à la VM, en cas d'utilisation d'un réseau VPC : compute.subnetworks.useExternalIp sur le projet ou sur le sous-réseau choisi
    • Pour définir les métadonnées d'instance de VM pour la VM : compute.instances.setMetadata sur le projet
    • Pour définir des tags pour la VM : compute.instances.setTags sur la VM
    • Pour définir des libellés pour la VM : compute.instances.setLabels sur la VM
    • Pour définir un compte de service à utiliser avec la VM : compute.instances.setServiceAccount sur la VM
    • Pour créer un disque pour la VM : compute.disks.create sur le projet
    • Pour associer un disque existant en mode lecture seule ou en mode lecture-écriture : compute.disks.use sur le disque
    • Pour associer un disque existant en mode lecture seule : compute.disks.useReadOnly sur le disque

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Limites

  • Une adresse IP externe statique peut être utilisée par une seule ressource à la fois.

  • Il n'y a aucun moyen de vérifier si une adresse IP est statique ou éphémère après son attribution à une ressource. Vous pouvez comparer l'adresse IP à la liste des adresses IP externes statiques réservées pour ce projet. Exécutez la sous-commande gcloud compute addresses list pour afficher la liste des adresses IP externes statiques disponibles pour le projet.

  • Chaque VM peut avoir plusieurs interfaces réseau, et chaque interface peut avoir les adresses IP suivantes attribuées en fonction de son type de pile:

    • Interfaces IPv4 uniquement :
      • Une adresse IPv4 interne (obligatoire)
      • Une adresse IPv4 externe (facultatif)
    • Interfaces à double pile (IPv4 et IPv6) :
      • Une adresse IPv4 interne (obligatoire)
      • Une adresse IPv4 externe (facultatif)
      • Une plage d'adresses IPv6 /96, internes ou externes, mais pas les deux (obligatoire)
    • Interfaces IPv6 uniquement (preview) :
      • Une plage d'adresses IPv6 /96, internes ou externes, mais pas les deux (obligatoire)
  • Vous ne pouvez pas annuler l'attribution ni modifier l'adresse IPv6 externe d'une VM avec une interface réseau IPv6 uniquement. Cependant, vous pouvez convertir l'adresse IP externe éphémère d'une ressource en adresse IP externe statique afin que l'adresse reste réservée, même après la suppression de la ressource.

  • Vous ne pouvez pas modifier le nom d'une adresse IP statique.

Remarque : Les interfaces réseau peuvent recevoir du trafic provenant de plusieurs règles de transfert, qui peuvent diffuser d'autres adresses IP externes. Le nombre d'adresses IP externes pouvant faire référence à une interface réseau via ces règles de transfert est libre, en revanche, chaque interface réseau ne peut se voir attribuer qu'une seule adresse IPv4 externe et une seule plage d'adresses IPv6 externes /96.

Pour en savoir plus sur l'équilibrage de charge et les règles de transfert, consultez la documentation sur l'équilibrage de charge.

Afficher les adresses IP externes statiques disponibles

Pour répertorier les adresses IP externes statiques que vous avez réservées pour votre projet, procédez comme suit :

Console

  1. Dans la console Google Cloud , accédez à la page Adresses IP.

    Accéder à la page "Adresses IP"

  2. Cliquez sur Adresses IP externes.

gcloud

Exécutez la commande gcloud compute addresses list :

  • Pour répertorier toutes les adresses IP, utilisez la commande suivante :

    gcloud compute addresses list
  • Pour répertorier toutes les adresses IP globales, utilisez la commande suivante :

    gcloud compute addresses list --global
  • Pour répertorier toutes les adresses IP régionales dans une région donnée, utilisez la commande suivante :

    gcloud compute addresses list \
        --regions=REGION
    

    Remplacez REGION par la région pour laquelle vous souhaitez répertorier les adresses. Vous pouvez répertorier les adresses de plusieurs régions en spécifiant des noms de région séparés par une virgule :

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

API

  • Pour répertorier les adresses IPv4 ou IPv6 régionales, appelez la méthode addresses.list :

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

    Remplacez les éléments suivants :

    • PROJECT_ID : ID du projet pour cette requête
    • REGION : nom de la région pour cette requête
  • Pour répertorier toutes les adresses dans toutes les régions, appelez la méthode addresses.aggregatedList :

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/aggregated/addresses
    
  • Pour répertorier les adresses IPv4 ou IPv6 globales, appelez la méthode globalAddresses.list :

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

    Remplacez les éléments suivants :

    PROJECT_ID : ID du projet pour cette requête

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.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

Configurer des adresses IP externes statiques

Les sections suivantes expliquent comment configurer des adresses IP externes statiques pour vos instances.

Créer une instance qui utilise une adresse IP externe statique

Après avoir réservé une adresse IP externe statique, vous pouvez l'attribuer à une instance.

Console

  1. Dans la console Google Cloud , accédez à la page Créer une instance.

    Accéder à la page Créer une instance

  2. Spécifiez les détails de l'instance.

  3. Développez la section Options avancées.

  4. Développez la section Mise en réseau.

  5. Dans la section Interfaces réseau, développez une interface réseau pour la modifier.

  6. Pour attribuer une adresse IPv4, procédez comme suit :

    1. Sélectionnez un réseau.
    2. Sélectionnez l'adresse IP dans la liste Adresse IPv4 externe.
  7. Pour attribuer une adresse IPv6, procédez comme suit :

    1. Sélectionnez un réseau contenant un sous-réseau avec une plage d'adresses IPv6 externe.
    2. Sélectionnez le sous-réseau dans la liste Sous-réseau.
    3. Dans le champ Type de pile d'adresses IP, sélectionnez IPv4 et IPv6 (double pile) ou IPv6 (pile unique).
    4. Sélectionnez la nouvelle adresse IPv6 externe réservée dans la liste Adresse IPv6 externe. Vous pouvez également sélectionner Réserver une adresse IPv6 externe statique et réserver une nouvelle adresse IPv6 externe statique.
    5. Pour Niveau de service réseau, sélectionnez Premium.
  8. Pour terminer la modification de l'interface réseau par défaut, cliquez sur Terminé.

  9. Continuez le processus de création de l'instance.

gcloud

Vous pouvez créer une instance et attribuer une adresse IP externe régionale statique que vous avez déjà réservée.

  • Pour attribuer une adresse IPv4 externe statique, procédez comme suit :

    gcloud compute instances create INSTANCE_NAME \
        --zone=ZONE \
        --address=IPV4_ADDRESS
    
  • Pour attribuer une adresse IPv6 externe statique, procédez comme suit :

    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
    

    Remplacez les éléments suivants :

    • INSTANCE_NAME: nom de l'instance de calcul.
    • ZONE: zone dans laquelle créer l'instance.
    • IPV4_ADDRESS: adresse IPv4 à attribuer à l'instance. Utilisez l'adresse IP externe statique réservée plutôt que le nom d'adresse.
    • SUBNET: sous-réseau contenant des adresses IPv6 externes
    • STACK_TYPE: type de pile de l'instance, IPV4_IPV6 (double pile) ou IPV6_ONLY
    • IPV6_ADDRESS: adresse IPv6 à attribuer à l'instance. Utilisez l'adresse IP externe statique réservée plutôt que le nom d'adresse.

Terraform

Vous pouvez utiliser la ressource google_compute_instance pour attribuer une adresse IP externe.

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

  • Pour attribuer une adresse IPv4 externe statique à une nouvelle instance de calcul, procédez comme suit:

    Dans votre requête de création d'instance, indiquez explicitement la propriété networkInterfaces[].accessConfigs[].natIP et l'adresse IPv4 externe que vous souhaitez utiliser, par exemple:

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

    Remplacez les éléments suivants :

    • INSTANCE_NAME: nom de l'instance de calcul
    • ZONE: zone dans laquelle créer l'instance.
    • MACHINE_TYPE (facultatif) : URL complète ou partielle de la ressource de type de machine à utiliser lors de la création de l'instance, au format :zones/ZONE/machineTypes/MACHINE_TYPE
    • IPV4_ADDRESS: adresse IPv4 à attribuer à l'instance. Utilisez l'adresse IP externe statique réservée plutôt que le nom d'adresse.
    • SOURCE_IMAGE: version spécifique d'une image publique, telle que projects/debian-cloud/global/images/debian-10-buster-v20200309 ou d'une famille d'images, telle que projects/debian-cloud/global/images/family/debian-10
  • Pour attribuer une adresse IPv6 externe statique à une nouvelle instance, procédez comme suit:

    Dans votre requête de création d'instance, indiquez explicitement la propriété networkInterfaces[].ipv6AccessConfigs[].externalIpv6 et l'adresse IPv6 externe que vous souhaitez utiliser, par exemple:

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

    Remplacez les éléments suivants :

    • INSTANCE_NAME: nom de l'instance de calcul
    • ZONE: zone dans laquelle créer l'instance.
    • MACHINE_TYPE (facultatif) : URL complète ou partielle de la ressource de type de machine à utiliser lors de la création de l'instance, au format :zones/ZONE/machineTypes/MACHINE_TYPE
    • IPV6_ADDRESS: adresse IPv6 à attribuer à l'instance. Utilisez l'adresse IP externe statique réservée plutôt que le nom d'adresse.
    • STACK_TYPE: type de pile de l'instance, IPV4_IPV6 (double pile) ou IPV6_ONLY
    • SUBNET: sous-réseau contenant des adresses IPv6 externes
    • SOURCE_IMAGE: version spécifique d'une image publique, telle que "projects/debian-cloud/global/images/debian-10-buster-v20200309" ou d'une famille d'images, telle que "projects/debian-cloud/global/images/family/debian-10"

Go


// assignStaticExternalToNewVM creates a new VM instance and assigns a static external IP address to it.
// NOTE: ip address is expected to exist and be located in the same region as new 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

Modifier ou attribuer une adresse IP externe à une instance existante

Vous pouvez modifier ou attribuer une adresse IP externe, éphémère ou statique, à une instance IPv4 uniquement ou à double pile existante. Cette procédure n'est pas compatible avec les instances IPv6 uniquement.

Une instance de calcul peut avoir plusieurs interfaces. Une interface à pile unique peut avoir une adresse IP externe. Une interface à double pile peut avoir une adresse IPv4 externe et une adresse IPv6 externe. Si l'instance en possède déjà une, vous devez d'abord supprimer cette adresse. Vous pouvez ensuite attribuer une nouvelle adresse IP externe à l'instance existante.

Console

  1. Dans la console Google Cloud , accédez à la page Instances de VM.

    Accéder à la page Instances de VM

  2. Cliquez sur le nom de l'instance à laquelle vous souhaitez attribuer une adresse IP externe. La page de détails de l'instance s'affiche.

  3. Sur la page des détails de l'instance, procédez comme suit :

    1. Cliquez sur Modifier.
    2. Développez la section Interfaces réseau.
    3. Sélectionnez l'adresse IP externe requise à attribuer à l'instance. Si l'instance est IPv4 uniquement et que vous souhaitez attribuer une adresse IPv6, vous devez d'abord définir le type de pile sur double pile.
      1. Dans le champ Adresse IPv4 externe, sélectionnez l'option Éphémère, ou bien une adresse IPv4 externe statique.
      2. Dans le champ Adresse IPv6 externe, sélectionnez l'option Éphémère, ou bien une adresse IPv6 externe statique.
    4. Cliquez sur OK.
  4. Cliquez sur Enregistrer.

gcloud

  1. Facultatif : Réservez une adresse IP externe statique.

    Si vous souhaitez attribuer une adresse IP externe statique, vous devez réserver une adresse et vous assurer que celle-ci n'est pas utilisée par une autre ressource. Si nécessaire, suivez les instructions pour réserver une nouvelle adresse IP externe statique ou pour annuler l'attribution d'une adresse IP externe statique.

    Si vous souhaitez utiliser une adresse IP externe éphémère, vous pouvez ignorer cette étape. Compute Engine vous attribue alors une adresse IP externe éphémère de manière aléatoire.

  2. Supprimez toute attribution d'adresse IP existante, comme décrit dans la section Annuler l'attribution d'une adresse IP externe statique.

  3. Attribuez la nouvelle adresse IP externe.

    • Pour attribuer une adresse IPv4, utilisez la sous-commande instances add-access-config :

      Remarque : Ne remplacez pas IP_ADDRESS par le nom de l'adresse IP statique. Vous devez utiliser l'adresse IP réelle.
      gcloud compute instances add-access-config INSTANCE_NAME \
        --access-config-name="ACCESS_CONFIG_NAME" --address=IP_ADDRESS
      

      Remplacez les éléments suivants :

      • INSTANCE_NAME : nom de l'instance.
      • ACCESS_CONFIG_NAME : nom destiné à cette configuration d'accès. Assurez-vous d'inclure le nom complet entre guillemets.
      • IP_ADDRESS : adresse IP à ajouter.

      Si vous souhaitez que Compute Engine attribue une adresse IP externe éphémère plutôt que d'utiliser une adresse IP externe statique, ne renseignez pas la propriété --address IP_ADDRESS :

      gcloud compute instances add-access-config INSTANCE_NAME \
        --access-config-name="ACCESS_CONFIG_NAME"
      
    • Pour passer une instance en double pile et lui attribuer une adresse IPv6, utilisez la sous-commande instance network-interfaces update:

      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
      

      Remplacez les éléments suivants :

      • INSTANCE_NAME : nom de l'instance.
      • NIC : nom de l'interface réseau
      • STACK_TYPE: type de pile de l'instance, qui doit être IPV4_IPV6. Vous ne pouvez pas remplacer le type de pile par IPV6_ONLY.
      • IPV6_ADDRESS: adresse IPv6 à attribuer à l'instance. Spécifiez la première adresse IPv6 de la plage /96.
      • ZONE : zone de l'instance.

REST

Vous pouvez modifier l'adresse IPv4 ou IPv6 externe d'une instance en ajoutant une nouvelle configuration d'accès pour cette instance.

  1. Supprimez toute attribution d'adresse IP existante, comme décrit dans la section Annuler l'attribution d'une adresse IP externe statique.

  2. Supprimez la configuration d'accès existante en envoyant une requête POST à la méthode instances.deleteAccessConfig.

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/deleteAccessConfig
    
  3. Ajoutez une configuration d'accès à l'interface réseau de l'instance en envoyant une requête POST à la méthode instances.addAccessConfig.

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.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

Limiter les adresses IP externes à des instances spécifiques

Pour certaines charges de travail, il est possible que vous deviez respecter des conditions requises essentielles, telles que des restrictions de sécurité et de réseau. Par exemple, vous pouvez restreindre les adresses IP externes afin que seules des instances de calcul spécifiques puissent les utiliser. Cette option permet d'éviter l'exfiltration de données ou de maintenir l'isolation du réseau. À l'aide d'une règle d'administration, vous pouvez limiter les adresses IP externes à des instances spécifiques avec des contraintes pour contrôler l'utilisation des adresses IP externes pour vos instances au sein d'une organisation ou d'un projet.

Voici la contrainte pour contrôler les adresses IP externes sur les instances:

constraints/compute.vmExternalIpAccess

Pour utiliser la contrainte, vous devez spécifier une règle avec la liste allowedList des instances pouvant avoir des adresses IP externes. Si vous ne spécifiez pas de règle, toutes les adresses IP externes sont autorisées pour toutes les instances. Lorsque la règle est en place, seules les instances répertoriées dans la liste allowedValues peuvent se voir attribuer une adresse IP externe, éphémère ou statique. En revanche, les autres instances Compute Engine dans l'organisation ou le projet et qui ne sont pas explicitement définies dans la règle ne sont pas autorisées à utiliser des adresses IP externes.

Les instances sont identifiées dans les listes d'autorisation et de refus à l'aide de l'URI de l'instance:

projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME

Spécifications pour la restriction des adresses IP externes

  • Vous ne pouvez appliquer cette contrainte de liste qu'aux instances.
  • Vous ne pouvez pas appliquer la contrainte rétroactivement. Toutes les instances qui avaient des adresses IP externes avant l'activation de la règle conservent leurs adresses IP externes.
  • Cette contrainte accepte soit une liste allowedList, soit une liste deniedList, mais pas les deux dans la même règle.
  • C'est à vous ou à un administrateur disposant des autorisations nécessaires de gérer et d'administrer le cycle de vie et l'intégrité de l'instance. La contrainte ne valide que l'URI de l'instance et n'empêche pas les instances de la liste d'autorisation d'être modifiées, supprimées ni recréées.

Autorisations requises pour restreindre les adresses IP externes

Pour définir une contrainte au niveau du projet ou de l'organisation, vous devez disposer du rôle orgpolicy.policyAdmin sur l'organisation.

Définir la contrainte de règle au niveau de l'organisation

Console

  1. Accédez à la page Règles d'administration.

    Accéder à la page "Règles d'administration"

  2. Si nécessaire, sélectionnez l'organisation requise dans le menu déroulant du projet.
  3. Cliquez sur Définir les adresses IP externes autorisées pour les instances de VM.
  4. Cliquez sur Modifier pour modifier la règle des adresses IP externes. Si vous ne pouvez pas accéder à l'outil Modifier, cela signifie que vous ne disposez pas des autorisations appropriées.
  5. Sélectionnez Personnaliser pour appliquer une règle d'administration à certaines instances.

    Option de personnalisation sur la page de modification de la règle d&#39;administration.

  6. Sélectionnez les valeurs appropriées dans Application des règles et Type de règle.

  7. Pour Valeurs de règles, sélectionnez Personnalisé.

  8. Saisissez un URI pour une instance. L'URI doit respecter le format suivant:

    projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME
    
  9. Cliquez sur Nouvelle valeur de règle et saisissez les URI des instances si nécessaire.

  10. Cliquez sur Enregistrer pour appliquer la contrainte.

gcloud

Pour définir une contrainte pour l'accès aux adresses IP externes, vous devez d'abord disposer de l'ID de votre organisation. Vous pouvez trouver l'ID de l'organisation en exécutant la commande organizations list et en recherchant l'ID numérique dans la réponse :

gcloud organizations list

gcloud CLI renvoie une liste d'organisations au format suivant :

DISPLAY_NAME               ID
example-organization1      29252605212
example-organization2      1234567890

Exécutez la commande gcloud resource-manager org-policies set-policy pour définir la règle. Vous devez fournir votre règle sous la forme d'un fichier JSON. Créez un fichier JSON au format suivant :

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

Remplacez les éléments suivants :

  • PROJECT_ID : ID de projet de cette requête, tel que example-project. Sachez que la procédure diffère des étapes à suivre pour configurer les règles d'administration qui, elles, nécessitent l'ID numérique de l'organisation.
  • ZONE : zone de l'instance
  • INSTANCE_NAME : nom de l'instance

Vous pouvez également spécifier une liste deniedValues pour indiquer les instances pour lesquelles vous voulez explicitement interdire les adresses IP externes. Les instances qui ne figurent pas sur la liste seront implicitement autorisées à posséder une adresse IP externe. Vous pouvez spécifier une liste allowedValues ou une liste deniedValues, mais pas les deux.

Ensuite, transmettez le fichier avec votre requête :

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

Remplacez ORGANIZATION_ID par l'ID numérique de l'organisation.

Si vous ne souhaitez pas que les instances aient accès aux adresses IP externes, vous pouvez configurer une règle avec le paramètre allValues défini sur DENY:

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

REST

Utilisez l'API setOrgPolicy() pour définir votre contrainte. Les instances de la liste allowedValue que vous spécifiez sont autorisées à disposer d'adresses IP externes. Vous pouvez également spécifier une liste deniedValues pour indiquer les instances pour lesquelles vous voulez explicitement interdire les adresses IP externes. Les instances qui ne figurent pas sur la liste seront implicitement autorisées à posséder une adresse IP externe. Vous pouvez spécifier une liste allowedValues ou une liste deniedValues, mais pas les deux.

Par exemple, voici une requête permettant de définir la contrainte compute.vmExternalIpAccess sur une organisation, dans laquelle les instances de certains projets de l'organisation sont autorisées à posséder des adresses IP externes:

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

ORGANIZATION_ID est l'ID numérique de l'organisation.

Dans le corps de votre requête, indiquez la règle pour cette contrainte :

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

Si vous ne souhaitez pas que les instances aient accès aux adresses IP externes, vous pouvez configurer une règle avec le paramètre allValues défini sur DENY:

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

Définir la règle au niveau du projet

Une règle définie au niveau du projet est prioritaire sur la règle définie au niveau de l'organisation. Exemple : si example-vm-1 figure sur la liste allowedValues au niveau de l'organisation, mais que la règle au niveau du projet mentionne la même instance sur la liste deniedValues, l'instance ne sera pas autorisée à posséder une adresse IP externe.

Console

Suivez la même procédure que celle décrite à la section Définir la contrainte de règle au niveau de l'organisation en choisissant le projet dans le sélecteur de projet plutôt que via le sélecteur d'organisation.

Sélecteur de projet

gcloud

Exécutez la commande gcloud resource-manager org-policies set-policy pour définir la règle. Vous devez fournir votre règle sous la forme d'un fichier JSON. Créez un fichier JSON au format suivant :

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

Remplacez les éléments suivants :

  • PROJECT_ID : ID de projet de cette requête, tel que example-project. Sachez que la procédure diffère des étapes à suivre pour configurer les règles d'administration qui, elles, nécessitent l'ID numérique de l'organisation.
  • ZONE : zone de l'instance.
  • INSTANCE_NAME : nom de l'instance.

Vous pouvez également spécifier une liste deniedValues d'instances pour lesquelles vous voulez explicitement interdire les adresses IP externes. Les instances qui ne figurent pas sur la liste seront implicitement autorisées à posséder une adresse IP externe. Vous pouvez spécifier une liste allowedValues ou une liste deniedValues, mais pas les deux.

Ensuite, transmettez le fichier avec votre requête :

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

REST

Utilisez l'API setOrgPolicy pour définir votre contrainte. Les instances de la liste allowedValue que vous spécifiez sont autorisées à disposer d'adresses IP externes. Vous pouvez également spécifier une liste deniedValues pour indiquer les instances pour lesquelles vous voulez explicitement interdire les adresses IP externes. Les instances qui ne figurent pas dans la liste sont implicitement autorisées à posséder une adresse IP externe. Vous ne pouvez spécifier que allowedValues ou deniedValues, mais pas les deux.

Par exemple, voici une requête permettant de définir la contrainte compute.vmExternalIpAccess sur un projet pour autoriser des instances spécifiques à posséder des adresses IP externes:

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

Remplacez PROJECT_ID par l'ID du projet pour cette requête.

Le corps de la requête contient la règle pour cette contrainte :

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

Bonnes pratiques pour restreindre les adresses IP externes

  • Évitez d'utiliser la liste deniedValues avec cette contrainte. Si vous définissez des valeurs dans la liste deniedValues, cela signifie que seules les instances de la liste deniedValues ne peuvent pas se servir d'adresses IP externes. Cela peut poser un problème de sécurité si vous souhaitez contrôler exactement quelles instances peuvent disposer d'adresses IP externes. Si vous voulez supprimer certaines instances de la liste allowedValues, mettez à jour la règle existante pour retirer les instances de la liste allowedList plutôt que d'ajouter des instances à la liste deniedValues à un niveau hiérarchique inférieur.

  • Si vous souhaitez définir une règle sur une grande partie de la hiérarchie des ressources, mais exclure certains projets, restaurez la règle par défaut à l'aide de la méthode setOrgPolicy. Pour ce faire, spécifiez l'objet restoreDefault pour que toutes les instances des projets puissent être associées à des adresses IP externes. Les règles actuelles concernant les projets ne sont pas affectées par le paramètre par défaut.

  • Appliquez cette règle d'administration avec les rôles IAM pour mieux contrôler votre environnement. Cette règle ne s'applique qu'aux instances, mais si vous souhaitez mieux contrôler et restreindre les adresses IP externes sur les appareils réseau, vous pouvez accorder le rôle compute.networkAdmin aux parties appropriées.

  • Tous les services et produits qui s'exécutent sur Compute Engine au sein de l'organisation ou du projet avec la règle activée sont soumis à cette règle d'administration. Plus précisément, les services tels que Google Kubernetes Engine, Cloud Dataflow, Cloud Dataproc et Cloud SQL sont affectés par cette règle. Si cela pose problème, Google recommande de configurer d'autres services et produits dans un projet différent auquel la règle d'administration n'est pas appliquée, et d'utiliser si nécessaire un VPC partagé.

Gérer des adresses IP externes statiques

Les sections suivantes expliquent comment gérer les adresses IP externes statiques pour vos instances.

Déterminer si une adresse IP interne est éphémère ou statique

Les adresses IP internes statiques et éphémères se comportent et apparaissent de manière identique dans la plupart des contextes. Cependant, avec les adresses IP internes statiques, vous pouvez utiliser la même adresse IP pour la même ressource même si vous supprimez et recréez la ressource. En général, une adresse IP éphémère est libérée si vous arrêtez ou supprimez la ressource.

Pour déterminer si une adresse est statique ou éphémère, procédez comme suit :

  1. Dans la console Google Cloud , accédez à la page Adresses IP.

    Accéder à la page "Adresses IP"

  2. Recherchez l'adresse dans la liste et vérifiez le type d'adresse IP dans la colonne Type.

Annuler l'attribution d'une adresse IP externe statique

Cette annulation d'attribution supprime l'adresse IP de la ressource, mais elle reste réservée. Une fois l'attribution de l'adresse IP annulée, vous pouvez la réattribuer à une autre ressource. Cette procédure est compatible avec les instances à double pile, mais pas avec les instances IPv6 uniquement.

Vous pouvez également annuler l'attribution d'une adresse IPv4 ou IPv6 en supprimant l'instance.

Console

  1. Dans la console Google Cloud , accédez à la page Adresses IP.

    Accéder à la page "Adresses IP"

  2. Cliquez sur Adresses IP externes.

  3. Sélectionnez l'adresse IP statique dont vous souhaitez annuler l'attribution.

  4. Cliquez sur Afficher les actions, puis sélectionnez l'option Réattribuer à une autre ressource.

  5. Dans la liste déroulante Associer à, sélectionnez Aucune.

  6. Cliquez sur OK.

gcloud

  1. Vérifiez si une adresse IP statique est utilisée à l'aide de la commande gcloud compute addresses list :

    gcloud compute addresses list
    

    Le résultat ressemble à ce qui suit :

    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
    
    • Si l'adresse IP n'est pas utilisée, l'état est défini sur RESERVED.
    • Si l'adresse IP n'est pas utilisée, l'état est défini sur IN_USE.
  2. Récupérez le nom de l'instance qui utilise l'adresse IP:

    gcloud compute addresses describe ADDRESS_NAME \
      --region=REGION
    

    Remplacez les éléments suivants :

    • ADDRESS_NAME : nom de la ressource d'adresse IPv6
    • REGION : région de la ressource d'adresse IPv6

    Le résultat ressemble à ce qui suit :

    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
    

    Le champ users affiche le nom de l'instance qui utilise l'adresse IP.

  3. Annulez l'attribution de l'adresse IP à l'instance.

    • Pour annuler l'attribution d'une adresse IPv4, supprimez le fichier de configuration d'accès de l'instance :

      1. Récupérez le nom de la configuration d'accès à supprimer. Pour cela, utilisez la commande gcloud compute instances describe. Remplacez INSTANCE_NAME par le nom de l'instance.

        gcloud compute instances describe INSTANCE_NAME
        

        La configuration d'accès s'affiche au format suivant :

        networkInterfaces:
          - accessConfigs:
            - kind: compute#accessConfig
              name: external-nat
              natIP: 203.0.113.1
              type: ONE_TO_ONE_NAT
        
      2. Supprimez la configuration d'accès à l'aide de la commande gcloud compute instances delete-access-config :

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

        Remplacez les éléments suivants :

        • INSTANCE_NAME : nom de l'instance.
        • ACCESS_CONFIG_NAME : nom de la configuration d'accès à supprimer. Assurez-vous d'inclure le nom complet entre guillemets.
    • Pour annuler l'attribution d'une plage d'adresses IPv6, utilisez la commande instance network-interfaces update :

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

      Remplacez les éléments suivants :

      • INSTANCE_NAME: nom de l'instance qui utilise l'adresse IP.
      • ZONE : zone de l'instance.
  4. Vérifiez que votre adresse IP externe statique est maintenant disponible et marquée comme RESERVED au lieu de IN_USE.

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

    Remplacez les éléments suivants :

    • ADDRESS_NAME : nom de la ressource d'adresse IP
    • REGION : région de l'adresse IP

Maintenant que votre adresse IP externe statique est disponible, vous pouvez choisir de l'attribuer à une autre instance.

REST

Pour annuler l'attribution d'une adresse IPv4 ou IPv6 externe statique, procédez comme suit :

  • Pour les adresses IPv4, supprimez la configuration d'accès associée à l'instance qui utilise l'adresse.

    1. Pour vérifier les détails de configuration d'accès d'une instance, envoyez une requête GET à la méthode instances.get.

      GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME
      
    2. Supprimez la configuration d'accès existante en envoyant une requête POST à la méthode instances.deleteAccessConfig.

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

      Remplacez les éléments suivants :

      • PROJECT_ID : ID du projet pour cette requête
      • ZONE : zone où se trouve l'instance.
      • INSTANCE_NAME : nom de l'instance
  • Pour les adresses IPv6, mettez à jour le type de pile de l'interface réseau pour l'instance à laquelle l'adresse IPv6 est associée.

    1. Envoyez une requête PATCH à la méthode instances.updateNetworkInterface.

    2. Dans le corps de la requête, remplacez la valeur du champ stackType par IPV4_ONLY.

      Par exemple :

      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

Libérer une adresse IP externe statique

Si vous n'avez plus besoin d'une adresse IPv4 ou IPv6 externe statique, vous pouvez la libérer en supprimant la ressource d'adresse IP. La suppression d'une instance ne libère pas automatiquement une adresse IP externe statique. Vous devez libérer manuellement les adresses IP externes statiques lorsque vous n'en avez plus besoin.

Pour libérer une adresse IP externe statique, consultez la page Libérer une adresse IP externe statique dans la documentation sur les VPC.

Étapes suivantes