고정 외부 IP 주소 구성


가상 머신(VM) 인스턴스에 고정 외부 IP 주소를 할당할 수 있습니다. VM의 고정 IP 주소를 변경, 나열, 해제할 수도 있습니다. 외부 IP 주소는 고정 또는 임시 주소일 수 있습니다.

VM에 변경되지 않는 고정 외부 IP 주소가 필요한 경우 다음 단계를 따르세요.

  1. 고정 외부 IP 주소를 가져옵니다. 새 외부 IP 주소를 예약하거나 기존 임시 외부 IP 주소를 승격하는 것도 가능합니다.
  2. 예약된 IP 주소를 기존 VM에 할당하거나 새 VM을 만들 때 할당합니다.

내부 Compute Engine 네트워크에 고정 IP 주소가 필요한 경우에는 대신 고정 내부 IP 주소 예약을 참조하세요.

고정 외부 IP 주소 예약 또는 글로벌 외부 IP 주소 만들기에 관한 자세한 내용은 고정 외부 IP 주소 예약을 참고하세요.

시작하기 전에

  • IP 주소에 대해 알아봅니다.
  • 고정 외부 IP 주소의 할당량 및 한도에 대해 읽어봅니다.
  • 외부 IP 주소 가격 책정에 대해 읽어봅니다.
  • 아직 인증을 설정하지 않았다면 설정합니다. 인증은 Google Cloud 서비스 및 API에 액세스하기 위해 ID를 확인하는 프로세스입니다. 로컬 개발 환경에서 코드 또는 샘플을 실행하려면 다음 옵션 중 하나를 선택하여 Compute Engine에 인증하면 됩니다.

    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

      로컬 개발 환경에서 이 페이지의 Terraform 샘플을 사용하려면 gcloud CLI를 설치 및 초기화한 다음 사용자 인증 정보로 애플리케이션 기본 사용자 인증 정보를 설정하세요.

      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.

      자세한 내용은 다음을 참조하세요: Set up authentication for a local development environment.

      REST

      로컬 개발 환경에서 이 페이지의 REST API 샘플을 사용하려면 gcloud CLI에 제공한 사용자 인증 정보를 사용합니다.

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

        gcloud init

      자세한 내용은 Google Cloud 인증 문서의 REST 사용을 위한 인증을 참고하세요.

필요한 역할

고정 IP 주소를 구성하고 관리하는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 다음 IAM 역할을 부여해 달라고 요청하세요.

역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

이러한 사전 정의된 역할에는 고정 IP 주소를 구성하고 관리하는 데 필요한 권한이 포함되어 있습니다. 필요한 정확한 권한을 보려면 필수 권한 섹션을 펼치세요.

필수 권한

고정 IP 주소를 구성하고 관리하려면 다음 권한이 필요합니다.

  • VM 인스턴스에 대한 compute.instances.update 권한
  • VM 인스턴스에 대한 compute.instances.updateNetworkInterface 권한
  • VM 인스턴스에 대한 compute.instances.addAccessConfig 권한
  • VM 인스턴스에 대한 compute.instances.deleteAccessConfig 권한
  • 네트워크에 대한 compute.networks.list
  • 서브넷에 대한 compute.subnetworks.use 권한
  • 서브넷에 대한 compute.subnetworks.list 권한
  • VM 만들기:
    • 프로젝트에 대한 compute.instances.create 권한
    • 커스텀 이미지를 사용하여 VM 만들기: 이미지에 대한 compute.images.useReadOnly 권한
    • 스냅샷을 사용하여 VM 만들기: 스냅샷에 대한 compute.snapshots.useReadOnly 권한
    • 인스턴스 템플릿을 사용하여 VM 만들기: 인스턴스 템플릿에 대한 compute.instanceTemplates.useReadOnly 권한
    • VM에 기존 네트워크 할당: 프로젝트에 대한 compute.networks.use 권한
    • VM의 고정 IP 주소 지정: 프로젝트에 대한 compute.addresses.use 권한
    • 기존 네트워크 사용 시 VM에 외부 IP 주소 할당: 프로젝트에 대한 compute.networks.useExternalIp 권한
    • VM의 서브넷 지정: 프로젝트 또는 선택한 서브넷에 대한 compute.subnetworks.use 권한
    • VPC 네트워크를 사용할 때 VM에 외부 IP 주소 할당: 프로젝트 또는 선택한 서브넷에 대한 compute.subnetworks.useExternalIp 권한
    • VM에 VM 인스턴스 메타데이터 설정: 프로젝트에 대한 compute.instances.setMetadata 권한
    • VM에 태그 설정: VM에 대한 compute.instances.setTags 권한
    • VM에 라벨 설정: VM에 대한 compute.instances.setLabels 권한
    • VM에 사용할 서비스 계정 설정: VM에 대한 compute.instances.setServiceAccount 권한
    • VM의 새 디스크 만들기: 프로젝트에 대한 compute.disks.create 권한
    • 기존 디스크를 읽기 전용 또는 읽기-쓰기 모드로 연결: 디스크에 대한 compute.disks.use 권한
    • 기존 디스크를 읽기 전용 모드로 연결: 디스크에 대한 compute.disks.useReadOnly 권한

커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.

제한사항

  • 한 번에 하나의 리소스만 고정 외부 IP 주소를 사용할 수 있습니다.

  • IP 주소가 리소스에 할당되면 해당 주소가 고정 주소인지 임시 주소인지 확인할 수 있는 방법이 없습니다. IP 주소를 해당 프로젝트에 예약된 고정 외부 IP 주소 목록과 비교할 수 있습니다. 프로젝트에서 사용할 수 있는 고정 외부 IP 주소의 목록을 확인하려면 gcloud compute addresses list 하위 명령어를 사용합니다.

  • 각 VM에는 네트워크 인터페이스가 여러 개 있을 수 있으며 각 인터페이스에는 다음 IP 주소가 할당될 수 있습니다.

    • 내부 IPv4 주소(필수)
    • 외부 IPv4 주소
    • /96 IPv6 주소 범위(내부 또는 외부 중 하나)
  • 고정 IP 주소 이름을 변경할 수 없습니다.

  • 할당된 외부 IP 주소는 VM과 동일한 물리적 호스트에 존재하고, 라우팅, 지연 시간, 가격 책정을 포함한 모든 목적을 위해 VM과 동일한 리전에 존재합니다. 이는 인터넷 위치정보 조회 정보에 관계없이 적용됩니다.

참고: 네트워크 인터페이스는 여러 전달 규칙으로부터 트래픽을 수신하며 이 전달 규칙은 다른 외부 IP 주소에도 적용될 수 있습니다. 여러 외부 IP 주소에서 이러한 전달 규칙을 통해 네트워크 인터페이스를 참조할 수 있지만 각 네트워크 인터페이스에는 외부 IPv4 주소 하나와 외부 /96 IPv6 주소 범위 하나만 할당될 수 있습니다.

부하 분산 및 전달 규칙에 대한 자세한 내용은 부하 분산 문서를 읽어보세요.

사용 가능한 고정 외부 IP 주소 보기

프로젝트에 예약한 고정 외부 IP 주소를 나열하려면 다음 단계를 수행합니다.

콘솔

  1. Google Cloud 콘솔에서 IP 주소 페이지로 이동합니다.

    IP 주소로 이동

  2. 외부 IP 주소를 클릭합니다.

gcloud

gcloud compute addresses list 명령어를 사용합니다.

  • 모든 IP 주소를 나열하려면 다음 명령어를 사용합니다.

    gcloud compute addresses list
  • 모든 전역 IP 주소를 나열하려면 다음 명령어를 사용합니다.

    gcloud compute addresses list --global
  • 특정 리전의 모든 리전 IP 주소를 나열하려면 다음 명령어를 사용합니다.

    gcloud compute addresses list \
        --regions=REGION
    

    REGION을 주소를 나열할 리전으로 바꿉니다. 쉼표로 구분한 리전 이름을 지정하여 여러 리전의 주소를 나열할 수 있습니다.

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

API

  • 리전 IPv4 또는 IPv6 주소를 나열하려면 addresses.list 메서드를 호출합니다.

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

    다음을 바꿉니다.

    • PROJECT_ID: 이 요청의 프로젝트 ID
    • REGION: 요청의 리전 이름
  • 모든 리전의 모든 주소를 나열하려면 addresses.aggregatedList 메서드를 호출합니다.

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/aggregated/addresses
    
  • 전역 IPv4 또는 IPv6 주소를 나열하려면 globalAddresses.list 메서드를 호출합니다.

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

    다음을 바꿉니다.

    PROJECT_ID: 이 요청의 프로젝트 ID

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
}

자바


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

고정 외부 IP 주소 구성

다음 섹션에서는 VM의 고정 외부 IP 주소를 구성하는 방법을 설명합니다.

고정 외부 IP 주소를 사용하는 VM을 만듭니다.

고정 외부 IP 주소를 예약한 후 이를 VM에 할당할 수 있습니다.

콘솔

  1. Google Cloud 콘솔에서 인스턴스 만들기 페이지로 이동합니다.

    인스턴스 만들기로 이동

  2. VM 세부정보를 지정합니다.

  3. 고급 옵션 섹션을 펼칩니다.

  4. 네트워킹 섹션을 펼칩니다.

  5. 네트워크 인터페이스 섹션에서 네트워크 인터페이스를 확장하여 수정합니다.

  6. IPv4 주소를 할당하려면 다음 안내를 따르세요.

    1. 네트워크를 선택하세요.
    2. 외부 IPv4 주소 목록에서 IP 주소를 선택합니다.
  7. IPv6 주소를 할당하려면 다음 안내를 따르세요.

    1. IPv6 서브넷이 포함된 네트워크를 선택합니다.
    2. 서브네트워크 목록에서 이중 스택 서브넷을 선택합니다.
    3. IP 스택 유형IPv4 및 IPv6(이중 스택)을 선택합니다.
    4. 외부 IPv6 주소 목록에서 새로 예약된 외부 IPv6 주소를 선택합니다. 또는 IP 주소 만들기를 선택하고 새 고정 외부 IPv6 주소를 예약합니다.
    5. 네트워크 서비스 등급에서 프리미엄을 선택합니다.
  8. 기본 네트워크 인터페이스 수정을 완료하려면 완료를 클릭합니다.

  9. VM 만들기 프로세스를 계속 진행합니다.

gcloud

VM을 만들고 이미 예약한 고정 리전 외부 IP 주소를 할당할 수 있습니다.

  • 고정 외부 IPv4 주소를 할당하려면 다음을 실행합니다.

    gcloud compute instances create VM_NAME --address=IP_ADDRESS
    

    다음을 바꿉니다.

    • VM_NAME: VM의 이름
    • IP_ADDRESS: VM에 할당할 IP 주소 주소 이름이 아닌 예약된 고정 외부 IP 주소를 사용합니다.
  • 고정 외부 IPv6 주소를 할당하려면 다음을 실행합니다.

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

Terraform

google_compute_instance 리소스를 사용하여 외부 IP 주소를 할당할 수 있습니다.

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

새 VM에 고정 외부 IPv4 주소를 할당하려면 다음을 실행합니다.

새 VM 만들기 요청에서 networkInterfaces[].accessConfigs[].natIP 속성과 사용하려는 외부 IPv4 주소를 명시적으로 제공합니다. 예를 들면 다음과 같습니다.

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

새 VM에 고정 외부 IPv6 주소를 할당하려면 다음을 실행합니다.

새 VM 만들기 요청에서 networkInterfaces[].ipv6AccessConfigs[].externalIpv6 속성과 사용하려는 외부 IPv6 주소를 명시적으로 제공합니다. 예를 들면 다음과 같습니다.

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

Go


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

자바


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

외부 IP 주소 변경 또는 기존 VM에 할당

기존 VM에 대해 임시 또는 고정 외부 IP 주소를 변경하거나 할당할 수 있습니다.

VM은 여러 인터페이스를 가질 수 있고 각 인터페이스는 외부 IP 주소를 가질 수 있습니다. VM에 이미 외부 IP 주소가 있는 경우 먼저 해당 주소를 삭제해야 합니다. 그런 다음 새 외부 IP 주소를 기존 VM에 할당할 수 있습니다.

콘솔

  1. Google Cloud 콘솔에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스로 이동

  2. 외부 IP를 할당하려는 VM의 이름을 클릭합니다. 인스턴스 세부정보 페이지가 표시됩니다.
  3. 인스턴스 세부정보 페이지에서 다음 단계를 완료합니다.

    1. 수정을 클릭합니다.
    2. 네트워크 인터페이스를 펼칩니다.
    3. VM에 할당할 필수 외부 IP 주소를 선택합니다.
      1. 외부 IPv4 주소의 경우 임시 또는 고정 외부 IPv4 주소를 선택합니다.
      2. 외부 IPv6 주소의 경우 임시 또는 고정 외부 IPv6 주소를 선택합니다.
    4. 완료를 클릭합니다.
  4. 저장을 클릭합니다.

gcloud

  1. 선택사항: 고정 외부 IP 주소를 예약합니다.

    고정 외부 IP 주소를 할당하려는 경우에는 주소를 예약하고 해당 주소가 다른 리소스에서 사용되고 있지 않은지 확인해야 합니다. 필요한 경우에는 안내에 따라 새 고정 외부 IP 주소를 예약하거나 고정 외부 IP 주소를 할당 해제합니다.

    임시 외부 IP 주소를 사용하려는 경우에는 이 단계를 건너 뛰고, Compute Engine이 임시 외부 IP 주소를 무작위로 할당하도록 할 수 있습니다.

  2. 고정 외부 IP 주소 할당 해제에 설명된 대로 기존 IP 주소 할당을 삭제합니다.

  3. 새 외부 IP 주소를 할당합니다.

    • IPv4 주소를 할당하려면 instances add-access-config 하위 명령어를 사용합니다.

      참고: IP_ADDRESS를 고정 IP 주소의 이름으로 바꾸지 마세요. 실제 IP 주소를 사용해야 합니다.
      gcloud compute instances add-access-config VM_NAME \
        --access-config-name="ACCESS_CONFIG_NAME" --address=IP_ADDRESS
      

      다음을 바꿉니다.

      • VM_NAME: VM의 이름
      • ACCESS_CONFIG_NAME: 액세스 구성의 이름. 따옴표 사이에 전체 이름을 포함해야 합니다.
      • IP_ADDRESS: 추가할 IP 주소입니다.

      고정 외부 IP 주소를 사용하는 대신 Compute Engine이 임시 외부 IP 주소를 할당하도록 하려면 --address IP_ADDRESS 속성을 생략합니다.

      gcloud compute instances add-access-config VM_NAME \
        --access-config-name="ACCESS_CONFIG_NAME"
      
    • IPv6 주소 범위를 할당하려면 instance network-interfaces update 하위 명령어를 사용합니다.

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

      다음을 바꿉니다.

      • VM_NAME: VM의 이름
      • NIC: 네트워크 인터페이스의 이름
      • IPV6_ADDRESS: VM에 할당할 IPv6 주소. /96 범위에서 첫 번째 IPv6 주소를 지정합니다.
      • ZONE: VM의 영역

REST

VM의 새 액세스 구성을 추가하여 해당 VM의 외부 IPv4 또는 IPv6 주소를 변경할 수 있습니다.

  1. 고정 외부 IP 주소 할당 해제에 설명된 대로 기존 IP 주소 할당을 삭제합니다.

  2. instances.deleteAccessConfig 메서드POST 요청을 수행하여 기존 액세스 구성을 삭제하세요.

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/deleteAccessConfig
    
  3. instances.addAccessConfig 메서드POST 요청을 수행하여 VM의 네트워크 인터페이스에 새 액세스 구성을 추가합니다.

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
}

자바


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

외부 IP 주소를 특정 VM으로 제한

특정 워크로드에서는 기본적인 요구사항에 따라 보안 및 네트워크 제한사항이 포함될 수 있습니다. 예를 들어 특정 VM만 외부 IP 주소를 사용하도록 제한할 수 있습니다. 이렇게 하면 데이터 무단 반출을 방지하거나 네트워크 격리를 유지하는 데 도움이 될 수 있습니다. 조직 정책을 사용하면 조직 또는 프로젝트 내에서 VM의 외부 IP 주소 사용을 제어하는 제약 조건이 포함된 특정 VM에서만 외부 IP 주소를 사용할 수 있습니다.

VM에서 외부 IP 주소 제어를 위한 제약조건은 다음과 같습니다.

constraints/compute.vmExternalIpAccess

제약조건을 사용하기 위해서는 외부 IP 주소를 포함할 수 있는 VM의 allowedList를 사용하여 정책을 지정합니다. 정책을 지정하지 않으면 모든 VM에 대해 모든 외부 IP 주소가 허용됩니다. 정책이 적용되면 allowedValues 목록에 나열된 VM에만 외부 IP 주소(임시 또는 고정)를 할당할 수 있고, 조직 또는 프로젝트에서 정책에 명시적으로 정의되지 않은 다른 Compute Engine VM은 외부 IP 주소 사용이 금지됩니다.

VM은 허용 및 거부 목록에서 인스턴스의 URI를 사용하여 식별됩니다.

projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

외부 IP 주소 제한 사양

  • 목록 제약조건은 VM에만 적용할 수 있습니다.
  • 이 제약조건은 소급해서 적용할 수 없습니다. 정책을 사용 설정하기 전에 외부 IP 주소가 있는 모든 VM은 외부 IP 주소를 유지합니다.
  • 이 제약조건은 allowedList 또는 deniedList를 허용하지만 동일 정책에서 둘 다 허용하지는 않습니다.
  • 필요한 권한이 있는 사용자 또는 관리자가 VM 수명 주기 및 무결성을 관리 및 유지보수할 수 있습니다. 이 제약조건은 VM의 URI만 확인하며, 허용 목록에 있는 VM이 변경, 삭제 또는 재생성되는 것을 방지하지 않습니다.

외부 IP 주소를 제한하는 데 필요한 권한

프로젝트 또는 조직 수준에서 제약조건을 설정하려면 해당 조직에서 orgpolicy.policyAdmin 역할을 부여 받아야 합니다.

조직 수준에서 정책 제약조건 설정

콘솔

  1. 조직 정책 페이지로 이동합니다.

    조직 정책으로 이동

  2. 필요한 경우 프로젝트 드롭다운 메뉴에서 필요한 조직을 선택합니다.
  3. VM 인스턴스에 허용되는 외부 IP 정의를 클릭합니다.
  4. 수정을 클릭하여 외부 IP 정책을 수정합니다. 수정 도구에 액세스할 수 없으면 적절한 권한이 없는 것입니다.
  5. 맞춤설정을 선택하여 특정 VM의 조직 정책을 설정합니다.

    조직 정책 수정 페이지의 맞춤설정 옵션

  6. 필요한 정책 시행정책 유형을 선택합니다.

  7. 정책 값에서 커스텀을 선택합니다.

  8. VM의 URI를 입력하고 Enter를 누릅니다. URI는 다음과 같은 형식이어야 합니다.

    projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
    
  9. 새 정책 값을 클릭하고 필요에 따라 VM의 URI를 입력합니다.

  10. 저장을 클릭하여 제약조건을 적용합니다.

gcloud

외부 IP 주소에 대해 제약조건을 설정하려면 먼저 조직 ID가 필요합니다. organizations list 명령어를 실행하고 응답에서 숫자 ID를 찾아 조직 ID를 찾을 수 있습니다.

gcloud organizations list

gcloud CLI는 조직 목록을 다음 형식으로 반환합니다.

DISPLAY_NAME               ID
example-organization1      29252605212
example-organization2      1234567890

gcloud resource-manager org-policies set-policy 명령어를 사용하여 정책을 설정합니다. 정책을 JSON 파일로 제공해야 합니다. 다음 형식으로 JSON 파일을 만듭니다.

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

다음을 바꿉니다.

  • PROJECT_ID: 요청의 프로젝트 ID(예: example-project). 이는 조직 숫자 ID가 필요한 조직 정책 설정과 다릅니다.
  • ZONE: VM의 영역
  • VM_NAME: VM의 이름

또는 deniedValues 목록을 지정하여 외부 IP 주소를 갖지 못하도록 명시적으로 금지할 VM을 표시할 수 있습니다. 목록에 없는 VM은 모두 외부 IP 주소를 갖도록 암시적으로 허용됩니다. allowedValues 또는 deniedValues 중 하나를 지정할 수 있지만 둘 다 지정할 수는 없습니다.

그런 다음 요청을 사용해서 파일을 전달합니다.

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

ORGANIZATION_ID를 조직의 숫자 ID로 바꿉니다.

VM에 외부 IP 주소가 사용되지 않도록 하려면 정책 allValuesDENY로 설정할 수 있습니다.

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

REST

setOrgPolicy() API를 사용하여 제약조건을 정의합니다. 사용자가 지정하는 allowedValue 목록의 VM은 외부 IP 주소를 가질 수 있습니다. 또는 deniedValues 목록을 지정하여 외부 IP 주소를 갖지 못하도록 명시적으로 금지할 VM을 표시할 수 있습니다. 목록에 없는 VM은 모두 외부 IP 주소를 갖도록 암시적으로 허용됩니다. allowedValues 또는 deniedValues 중 하나를 지정할 수 있지만 둘 다 지정할 수는 없습니다.

예를 들어 다음은 조직 내 특정 프로젝트의 VM이 외부 IP 주소를 갖는 것이 허용되는 compute.vmExternalIpAccess 제약조건을 조직에 적용하기 위한 요청입니다.

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

여기서 ORGANIZATION_ID는 조직의 숫자 ID입니다.

이제 요청 본문에서 이 제약조건의 정책을 제공합니다.

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

VM에 외부 IP 주소가 사용되지 않도록 하려면 정책 allValuesDENY로 설정할 수 있습니다.

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

프로젝트 수준에서 정책 설정

프로젝트 수준에서 정책을 설정하면 조직 수준의 정책이 재정의됩니다. 예를 들어 조직 수준에서 allowedValues 목록에 example-vm-1이 있지만, 프로젝트 수준의 정책에서 deniedValues 목록에 동일한 VM이 있는 경우 VM이 외부 IP 주소를 갖는 것이 허용되지 않습니다.

콘솔

조직 수준에서 정책 제약조건 설정에 설명된 것과 동일한 절차를 따르지만, 조직 대신 프로젝트 선택기에서 프로젝트를 선택합니다.

프로젝트 선택기

gcloud

gcloud resource-manager org-policies set-policy 명령어를 사용하여 정책을 설정합니다. 정책을 JSON 파일로 제공해야 합니다. 다음 형식으로 JSON 파일을 만듭니다.

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

다음을 바꿉니다.

  • PROJECT_ID: 요청의 프로젝트 ID(예: example-project). 이는 조직 숫자 ID가 필요한 조직 정책 설정과 다릅니다.
  • ZONE: VM의 영역
  • VM_NAME: VM의 이름

또는 외부 IP 주소를 갖지 못하도록 명시적으로 금지할 VM의 deniedValues 목록을 지정할 수 있습니다. 목록에 없는 VM은 모두 외부 IP 주소를 갖도록 암시적으로 허용됩니다. allowedValues 또는 deniedValues 중 하나를 지정할 수 있지만 둘 다 지정할 수는 없습니다.

그런 다음 요청을 사용해서 파일을 전달합니다.

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

REST

setOrgPolicy API를 사용하여 제약조건을 정의합니다. 사용자가 지정하는 allowedValue 목록의 VM은 외부 IP 주소를 가질 수 있습니다. 또는 deniedValues 목록을 지정하여 외부 IP 주소를 갖지 못하도록 명시적으로 금지할 VM을 표시할 수 있습니다. 목록에 없는 VM은 모두 외부 IP 주소를 갖도록 암시적으로 허용됩니다. allowedValues 또는 deniedValues 중 하나를 지정할 수 있지만 둘 다 지정할 수는 없습니다.

예를 들어 다음은 특정 VM이 외부 IP 주소를 갖는 것을 허용하는 compute.vmExternalIpAccess 제약조건을 프로젝트에 설정하기 위한 요청입니다.

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

PROJECT_ID를 이 요청의 프로젝트 ID로 바꾸세요.

요청 본문에는 이 제약조건의 정책이 포함됩니다.

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

외부 IP 주소 제한을 위한 권장사항

  • 이 제약조건과 함께 deniedValues 목록을 사용하지 마세요. deniedValues 목록에 값을 정의하면 deniedValues 목록에 있는 VM만 외부 IP 주소 사용이 제한됩니다. 외부 IP 주소를 포함할 수 있는 VM을 정확하게 제어해야 할 경우, 이 방식은 보안상 문제가 될 수 있습니다. allowedValues 목록에서 특정 VM을 삭제하려면, VM을 하위 계층의 deniedValues 목록에 넣는 대신 allowedList에서 VM을 삭제하도록 기존 정책을 업데이트합니다.

  • 리소스 계층의 대부분에 적용할 정책을 설정하되 특정 프로젝트를 제외시키려는 경우 기본 정책을 복원해야 합니다. 이때 프로젝트의 모든 VM이 외부 IP 주소와 연결될 수 있도록 restoreDefault 객체를 지정하여 setOrgPolicy 메서드를 사용하면 됩니다. 프로젝트의 현재 정책은 기본 설정의 영향을 받지 않습니다.

  • 환경을 보다 효과적으로 제어하려면 조직 정책을 IAM 역할과 함께 사용합니다. 이 정책은 VM에만 적용되지만, 네트워크 기기에서 외부 IP 주소를 더 효과적으로 제어하고 제한하려는 경우 적절한 당사자에게 compute.networkAdmin 역할을 부여할 수 있습니다.

  • 정책이 사용 설정된 상태로 Compute Engine에서 실행되고 있는 조직 또는 프로젝트 내의 모든 서비스 및 제품은 이 조직 정책의 영향을 받습니다. 특히 Google Kubernetes Engine, Dataflow, Dataproc, Cloud SQL 같은 서비스가 이 정책의 영향을 받습니다. 이것이 문제가 될 경우에는 조직 정책이 적용되지 않는 다른 프로젝트에서 다른 서비스 및 제품을 설정하고 필요한 경우 공유 VPC를 사용하는 것이 좋습니다.

고정 외부 IP 주소 관리

다음 섹션에서는 VM의 고정 외부 IP 주소를 관리하는 방법을 설명합니다.

내부 IP 주소가 임시 주소 또는 고정 주소인지 확인

고정 및 임시 내부 IP 주소는 대부분의 상황에서 모양과 동작이 동일합니다. 그러나 고정 내부 IP 주소를 사용하면 리소스를 삭제하고 다시 만드는 경우에도 동일한 리소스에 같은 IP 주소를 사용할 수 있습니다. 일반적으로 임시 IP 주소는 리소스를 중지하거나 삭제할 때 해제됩니다.

주소가 고정 주소 또는 임시 주소인지 확인하려면 다음을 수행합니다.

  1. Google Cloud 콘솔에서 IP 주소 페이지로 이동합니다.

    IP 주소로 이동

  2. 목록에서 주소를 찾고 유형 열에서 IP 주소 유형을 확인합니다.

고정 외부 IP 주소 할당 해제

IP 주소를 할당 해제하면 리소스에서 삭제되지만, IP 주소를 예약된 상태로 유지합니다. IP 주소를 할당 해제하면 IP 주소를 다른 리소스에 다시 할당할 수 있습니다.

VM을 삭제하여 IPv4 또는 IPv6 주소를 할당 해제할 수도 있습니다.

콘솔

  1. Google Cloud 콘솔에서 IP 주소 페이지로 이동합니다.

    IP 주소로 이동

  2. 외부 IP 주소를 클릭합니다.

  3. 할당 해제하려는 고정 IP 주소를 선택합니다.

  4. 작업 보기를 클릭하고 다른 리소스에 재할당 옵션을 선택합니다.

  5. 연결 대상 드롭다운 목록에서 없음을 선택합니다.

  6. 확인을 클릭합니다.

gcloud

  1. gcloud compute addresses list 명령어를 사용하여 고정 IP 주소가 사용 중인지 확인합니다.

    gcloud compute addresses list
    

    출력은 다음과 비슷합니다.

    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
    
    • IP 주소가 사용 중이 아니면 상태는 RESERVED입니다.
    • IP 주소가 사용 중이면 상태는 IN_USE입니다.
  2. IP 주소를 사용하는 VM의 이름을 검색합니다.

    gcloud compute addresses describe ADDRESS_NAME \
      --region=REGION
    

    다음을 바꿉니다.

    • ADDRESS_NAME: IPv6 주소 리소스의 이름
    • REGION: IPv6 주소 리소스의 리전

    출력은 다음과 비슷합니다.

    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/VM_NAME
    

    users 필드에 IP 주소를 사용하는 VM의 이름이 표시됩니다.

  3. VM에서 IP 주소를 할당 해제합니다.

    • IPv4 주소를 할당 해제하려면 VM의 액세스 구성 파일을 삭제합니다.

      1. 삭제하려는 액세스 구성의 이름을 가져옵니다. 이름을 가져오려면 gcloud compute instances describe 명령어를 사용합니다. VM_NAME을 VM의 이름으로 바꿉니다.

        gcloud compute instances describe VM_NAME
        

        액세스 구성은 다음 형식으로 표시됩니다.

        networkInterfaces:
          - accessConfigs:
            - kind: compute#accessConfig
              name: external-nat
              natIP: 203.0.113.1
              type: ONE_TO_ONE_NAT
        
      2. gcloud compute instances delete-access-config 명령어를 사용하여 액세스 구성을 삭제합니다.

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

        다음을 바꿉니다.

        • VM_NAME: VM의 이름
        • ACCESS_CONFIG_NAME: 삭제할 액세스 구성의 이름. 따옴표 사이에 전체 이름을 포함해야 합니다.
    • IPv6 주소 범위를 할당 해제하려면 instance network-interfaces update 명령어를 사용합니다.

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

      다음을 바꿉니다.

      • VM_NAME: IP 주소를 사용 중인 VM의 이름입니다.
      • ZONE: VM의 영역
  4. 고정 외부 IP 주소를 사용할 수 있고 IN_USE 대신 RESERVED로 표시되었는지 확인합니다.

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

    다음을 바꿉니다.

    • ADDRESS_NAME: IP 주소 리소스의 이름
    • REGION: IP 주소 리소스의 리전입니다.

이제 고정 외부 IP 주소를 사용할 수 있으므로, 이를 다른 VM에 할당하도록 선택할 수 있습니다.

REST

고정 외부 IPv4 또는 IPv6 주소를 할당 해제하려면 다음 단계를 따르세요.

  • IPv4 주소의 경우 주소를 사용하는 VM에 연결된 액세스 구성을 삭제합니다.

    1. VM의 액세스 구성 세부정보를 확인하려면 instances.get 메서드GET 요청을 수행하세요.

      GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
      
    2. instances.deleteAccessConfig 메서드POST 요청을 수행하여 기존 액세스 구성을 삭제하세요.

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

      다음을 바꿉니다.

      • PROJECT_ID: 이 요청의 프로젝트 ID입니다.
      • ZONE: VM이 있는 영역
      • VM_NAME: VM의 이름
  • IPv6 주소의 경우 IPv6 주소가 연결된 VM의 네트워크 인터페이스 스택 유형을 업데이트합니다.

    1. instances.updateNetworkInterface 메서드에 대해 PATCH 요청을 실행합니다.

    2. 요청 본문에서 stackType 필드 값을 IPV4_ONLY로 업데이트합니다.

      예를 들면 다음과 같습니다.

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

자바


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

고정 외부 IP 주소 해제

고정 외부 IPv4 또는 IPv6 주소가 더 이상 필요하지 않으면 IP 주소 리소스를 삭제하여 IP 주소를 해제할 수 있습니다. VM을 삭제해도 고정 외부 IP 주소는 자동으로 해제되지 않습니다. 더 이상 필요하지 않은 고정 외부 IP 주소는 수동으로 해제해야 합니다.

고정 외부 IP 주소를 해제하려면 VPC 문서의 고정 외부 IP 주소 해제를 참고하세요.

다음 단계