インスタンス テンプレートを作成する


このページでは、インスタンス テンプレートの作成および管理方法について説明します。インスタンス テンプレートを使用すると、仮想マシン(VM)インスタンスの作成に使用するマシンタイプ、ブートディスク イメージ、ネットワーク、その他の VM プロパティを指定できます。

インスタンス テンプレートを使用すると、次のことができます。

始める前に

制限事項

  • インスタンス テンプレートでの nic0 以外のインターフェースの共有 VPC は、gcloud CLI と API ではサポートされますが Google Cloud コンソールではサポートされません。
  • 既存のインスタンス テンプレートを更新することはできません。また、インスタンス テンプレートの作成後に変更することもできません。インスタンス テンプレートが最新でなくなった場合や構成の変更が必要になった場合は、新しいインスタンス テンプレートを作成してください。
  • インスタンス テンプレートでイメージ ファミリーを指定する場合、Google Cloud コンソールは使用できません。代わりに、Google Cloud CLI または Compute Engine API を使用できます。
  • インスタンス テンプレートでリージョン永続ディスクを指定する場合、Google Cloud コンソールは使用できません。代わりに、Google Cloud CLI または Compute Engine API を使用できます。
  • リージョン インスタンス テンプレートに基づいて予約を作成する場合は、Compute Engine API と gcloud CLI のみ使用できます。Google Cloud コンソールはサポートされていません。

新しいインスタンス テンプレートを作成する

VM メタデータ、起動スクリプト、永続ディスク、サービス アカウントなど、リクエストで個々の VM インスタンスを作成する際に指定できる大半の VM プロパティはインスタンス テンプレートでも指定できます。マシンタイプ、ブートディスク、ネットワークを指定する必要があります。

Google Cloud コンソールGoogle Cloud CLI、または API を使用して、リージョン インスタンス テンプレートまたはグローバル インスタンス テンプレートを作成します。グローバル インスタンス テンプレートを作成するには、Terraform または Cloud クライアント ライブラリも使用できます。

コンソール

  1. Google Cloud コンソールで、[インスタンス テンプレート] ページに移動します。

    [インスタンス テンプレート] に移動

    残りの手順は Google Cloud コンソールに自動的に表示されます。

  2. [インスタンス テンプレートを作成] をクリックします。
  3. 次のように [ロケーション] を選択します。
    1. リージョンをまたいでインスタンス テンプレートを使用する場合は、[グローバル] を選択します。
    2. リージョン間の依存関係を減らす場合は、[リージョン] を選択します。
  4. リージョンを選択した場合は、インスタンス テンプレートを作成するリージョンを選択します。
  5. 次のフィールドでは、デフォルト値をそのまま使用するか、必要に応じて変更します。デフォルト値は、選択したマシン ファミリーに応じて変わります。

    • [マシンタイプ] を選択します。
    • ブートディスクのタイプまたはイメージを更新するには、[ブートディスク] セクションで [変更] をクリックします。
    • ネットワーク インターフェースまたは IP アドレスの設定を更新するには、[詳細オプション] をクリックしてから [ネットワーキング] をクリックし、編集するネットワーク インターフェースをクリックします。
  6. 省略可: Shielded VM をサポートするイメージを選択した場合は、VM の Shielded VM 設定を変更します。

    1. [詳細オプション] をクリックしてから、[セキュリティ] タブをクリックします。
    2. セキュアブートを無効にする場合は、[セキュアブートをオンにする] チェックボックスをオフにします。セキュアブートは、ブートレベルやカーネルレベルのマルウェアとルートキットから VM インスタンスを保護します。詳細については、セキュアブートをご覧ください。
    3. 仮想トラステッド プラットフォーム モジュール(vTPM)を無効にする場合は、[vTPM をオンにする] チェックボックスをオフにします。vTPM を使用すると、メジャード ブートが有効になり、それによって VM の起動前と起動時の整合性が検証されます。詳細については、仮想トラステッド プラットフォーム モジュール(vTPM)をご覧ください。

    4. 整合性モニタリングを無効にする場合は、[整合性のモニタリングを有効にする] チェックボックスをオフにします。整合性モニタリングを使用すると、Shielded VM インスタンス起動時の整合性を Cloud Monitoring でモニタリングできます。詳細については、整合性モニタリングをご覧ください。

  7. 省略可: [詳細オプション] で、タブをクリックするとテンプレートをさらにカスタマイズできます。たとえば、ブートディスク以外のセカンダリ ディスクを最大 15 個追加できます。

  8. 省略可: [同等の REST] をクリックして REST リクエスト本文を表示します。リクエスト本文には、インスタンス テンプレートの JSON 表現が含まれています。

  9. [作成] をクリックしてテンプレートを作成します。

gcloud

リージョンまたはグローバルのインスタンス テンプレートを作成するには、instance-templates create コマンドを使用します。リージョン インスタンス テンプレートの場合、--instance-template-region フラグを使用してテンプレートのリージョンを設定する必要があります。

次のコマンドを使用して、リージョン インスタンス テンプレートを作成します。

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --instance-template-region=REGION

次のコマンドを使用して、グローバル インスタンス テンプレートを作成します。

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME

明示的なテンプレート設定を指定しない場合、gcloud compute は次のデフォルト値を使用します。

  • マシンタイプ: マシンタイプ(n1-standard-1 など)
  • イメージ: 最新の Debian イメージ
  • ブートディスク: VM にちなんで名付けられた新しい標準のブートディスク
  • ネットワーク: デフォルトの VPC ネットワーク
  • IP アドレス: エフェメラル外部 IP アドレス

これらの構成設定は明示的に指定することもできます。例:

gcloud compute instance-templates create example-template-custom \
    --machine-type=e2-standard-4 \
    --image-family=debian-10 \
    --image-project=debian-cloud \
    --boot-disk-size=250GB

ブートディスク以外のセカンダリ ディスクを最大 15 個追加できます。作成する各セカンダリ ディスクに --create-disk フラグを指定します。公開イメージまたはカスタム イメージからセカンダリ ディスクを作成するには、--create-disk フラグに各ディスクの image プロパティと image-project プロパティを指定します。空のディスクを作成するには、これらのプロパティを指定しないでください。ディスクの size プロパティと type プロパティは必要に応じて指定してください。リージョン永続ディスクを指定するには、replica-zones プロパティを使用します。

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --create-disk= \
        image-family=DISK_IMAGE_FAMILY, \
        image-project=DISK_IMAGE_PROJECT, \
        size=SIZE_GB_DISK1 \
    --create-disk= \
        device-name=DISK_NAME,type=DISK_TYPE, \
        size=SIZE_GB_DISK2 \
        replica-zones=^:^ZONE:REMOTE_ZONE, \
        boot=false

次のように置き換えます。

  • INSTANCE_TEMPLATE_NAME: 新しいテンプレートの名前。
  • REGION: リージョン インスタンス テンプレートを作成するリージョン。
  • IMAGE_FAMILY: 非ブートディスクとして使用するイメージ ファミリー。

    イメージ ファミリーの詳細については、Compute Engine でイメージ ファミリーを使用する場合のベスト プラクティスをご覧ください。

    代わりに --image=IMAGE フラグを使用すると、特定バージョンのイメージを指定できます。

    空のディスクの場合は、image-family プロパティまたは image プロパティを指定しないでください。

  • DISK_IMAGE_PROJECT: イメージを含むイメージ プロジェクト。

    空のディスクには、image-project プロパティを指定しないでください。公開イメージの詳細については、公開イメージをご覧ください。

  • SIZE_GB_DISK1SIZE_GB_DISK2: 各セカンダリ ディスクのサイズ。

  • DISK_NAME: 省略可。VM の作成後にゲスト OS に表示されるディスク名。

  • DISK_TYPE: 省略可。作成するディスクのタイプ。指定しない場合、デフォルトはマシンタイプに応じて pd-standard または pd-balanced になります。

  • ZONEREMOTE_ZONE: リージョン永続ディスクを作成するゾーンと複製するゾーン。

    ゾーンディスクの場合は、replica-zones プロパティを指定しないでください。

Shielded VM をサポートするイメージを選択した場合は、必要に応じて次のいずれかのフラグを使用してインスタンスの Shielded VM の設定を変更できます。

  • --no-shielded-secure-boot: セキュアブートをオフにします。

    セキュアブートは、ブートレベルとカーネルレベルのマルウェアとルートキットから VM インスタンスを保護します。詳細については、セキュアブートをご覧ください。

  • --no-shielded-vtpm: 仮想トラステッド プラットフォーム モジュール(vTPM)をオフにします。

    vTPM を使用すると、メジャード ブートが有効になり、それによって VM の起動前と起動時の整合性が検証されます。詳細については、仮想トラステッド プラットフォーム モジュール(vTPM)をご覧ください。

  • --no-shielded-integrity-monitoring: 整合性モニタリングをオフにします。

    整合性モニタリングを使用すると、Shielded VM インスタンス起動時の整合性を Cloud Monitoring でモニタリングできます。詳細については、整合性モニタリングをご覧ください。

使用可能なすべてのサブコマンドとフラグの一覧については、instance-templates リファレンスをご覧ください。

デフォルトの構成設定を使用したテンプレートは次のようになります。

gcloud compute instance-templates describe example-template
creationTimestamp: '2019-09-10T16:18:32.042-07:00'
description: ''
id: '6057583701980539406'
kind: compute#instanceTemplate
name: example-template
properties:
  canIpForward: false
  disks:
  - autoDelete: true
    boot: true
    initializeParams:
      sourceImage: https://compute.googleapis.com/compute/v1/projects/debian-cloud/global/images/family/debian-10
    kind: compute#attachedDisk
    mode: READ_WRITE
    type: PERSISTENT
  machineType: e2-standard-2
  networkInterfaces:
  - accessConfigs:
    - kind: compute#accessConfig
      name: external-nat
      type: ONE_TO_ONE_NAT
    network: https://compute.googleapis.com/compute/v1/projects/myproject/global/networks/default
  scheduling:
    automaticRestart: true
    onHostMaintenance: MIGRATE
  serviceAccounts:
  - email: default
    scopes:
    - https://www.googleapis.com/auth/devstorage.read_only
selfLink: https://compute.googleapis.com/compute/v1/projects/myproject/global/instanceTemplates/example-template

Terraform

インスタンス テンプレートを作成するには、google_compute_instance_template リソースを使用できます。

この Terraform の例は、次の gcloud CLI コマンドと類似しています。

gcloud compute instance-templates create my-instance-template \
    --machine-type=e2-standard-4 \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --boot-disk-size=250GB
resource "google_compute_instance_template" "foobar" {
  name         = "my-instance-template"
  machine_type = "e2-standard-4"

  disk {
    source_image = "debian-cloud/debian-11"
    disk_size_gb = 250
  }

  network_interface {
    network = "default"

    # secret default
    access_config {
      network_tier = "PREMIUM"
    }
  }

  # secret default
  service_account {
    scopes = [
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring.write",
      "https://www.googleapis.com/auth/pubsub",
      "https://www.googleapis.com/auth/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append",
    ]
  }
}

Terraform 構成を適用または削除する方法については、基本的な Terraform コマンドをご覧ください。

API

リージョン インスタンス テンプレートを作成するには、次のように regionInstanceTemplates.insert メソッドPOST リクエストを送信します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/instanceTemplates

グローバル インスタンス テンプレートを作成するには、instanceTemplates.insert メソッドPOST リクエストを送信します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/instanceTemplates

追加するディスクごとに 1 つのフィールドで、disks プロパティを使用するとブートディスク以外のセカンダリ ディスクを最大 15 個追加できます。追加するディスクごとに次の操作を行うことができます。

  • 公開イメージまたは非公開イメージを使用して追加ディスクを作成します。
  • 空のディスクを追加するには、sourceImage 値のない initializeParams エントリを定義します。
  • リージョン永続ディスクを作成するには、replicaZones プロパティを指定して initializeParams エントリを定義します。

リクエスト本文で、テンプレート プロパティを指定します。

{
  "name": "INSTANCE_TEMPLATE_NAME",
  "properties": {
    "machineType": "MACHINE_TYPE",
    "networkInterfaces": [
      {
        "network": "global/networks/default",
        "accessConfigs":
        [
          {
            "name": "external-IP",
            "type": "ONE_TO_ONE_NAT"
          }
        ]
      }
    ],
    "disks":
    [
      {
        "type": "PERSISTENT",
        "boot": true,
        "mode": "READ_WRITE",
        "initializeParams":
        {
          "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
        }
      },
      {
        "type": "PERSISTENT",
        "boot": false,
        "deviceName": "DISK_NAME",
        "initializeParams":
        {
          "replicaZones": [
              "projects/PROJECT_NAME/zones/ZONE",
              "projects/PROJECT_NAME/zones/REMOTE_ZONE"
          ]
        }
      }
    ]
  }
}

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID
  • REGION: リージョン インスタンス テンプレートを作成するリージョン。
  • INSTANCE_TEMPLATE_NAME: インスタンス テンプレートの名前。
  • ZONE: VM を配置するゾーン。
  • MACHINE_TYPE: VM のマシンタイプ。

  • IMAGE_PROJECT: イメージを含むイメージ プロジェクト。

    公開イメージの詳細については、公開イメージをご覧ください。

  • IMAGE または IMAGE_FAMILY: 次のいずれかを指定します。
    • IMAGE: 特定のバージョンのイメージ

      例: "sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20200309"

    • IMAGE_FAMILY: イメージ ファミリー

      これにより、非推奨ではない最新の OS イメージから VM が作成されます。たとえば、"sourceImage": "projects/debian-cloud/global/images/family/debian-10" を指定すると、Compute Engine は Debian 10 イメージ ファミリーの OS イメージの最新バージョンから VM を作成します。

      イメージ ファミリーの詳細については、Compute Engine でイメージ ファミリーを使用する場合のベスト プラクティスをご覧ください。

  • DISK_NAME: 省略可。VM の作成後にゲスト OS に表示されるディスク名。

  • PROJECT_NAME: VM に関連付けられているプロジェクト。

  • REMOTE_ZONE: リージョン ディスクの複製先となるゾーン。

disks プロパティには、次のいずれかのオプションを指定できます。

  • インスタンスごとに永続ブートディスクを作成するには、initializeParams を指定します。追加するディスクごとに initializeParams プロパティを使用すると、ブートディスク以外のセカンダリ ディスクを最大 15 個追加できます。前の例に示すように、公開イメージまたはカスタム イメージ(またはイメージ ファミリー)を sourceImage に使用してディスクを作成できます。空のディスクを追加するには、sourceImage を指定しないでください。

  • 既存の永続ブートディスクをアタッチするには、source を指定します。既存のブートディスクをアタッチした場合、テンプレートから作成できるインスタンスは 1 つのみです。

initializeParams には diskSizeGbdiskTypelabels のプロパティを、source には diskSizeGb プロパティを必要に応じて指定します。

Shielded VM をサポートするイメージを選択した場合は、必要に応じて次のブール値の項目をリクエスト本文で使用して、VM の Shielded VM の設定を変更できます。

  • enableSecureBoot: セキュアブートをオンまたはオフにします。

    セキュアブートは、ブートレベルとカーネルレベルのマルウェアとルートキットから VM インスタンスを保護します。詳細については、セキュアブートをご覧ください。

  • enableVtpm: 仮想トラステッド プラットフォーム モジュール(vTPM)をオンまたはオフにします。

    vTPM を使用すると、メジャード ブートが有効になり、それによって VM の起動前と起動時の整合性が検証されます。詳細については、仮想トラステッド プラットフォーム モジュール(vTPM)をご覧ください。

  • enableIntegrityMonitoring: 整合性モニタリングをオンまたはオフにします。

    整合性モニタリングを使用すると、Shielded VM インスタンスの実行時の起動の整合性を Cloud Monitoring レポートでモニタリングして検証できます。詳細については、整合性モニタリングをご覧ください。

リクエスト パラメータの詳細については、instanceTemplates.insert メソッドをご覧ください。

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
	"google.golang.org/protobuf/proto"
)

// createTemplate creates a new instance template with the provided name and a specific instance configuration.
func createTemplate(w io.Writer, projectID, templateName string) error {
	// projectID := "your_project_id"
	// templateName := "your_template_name"

	ctx := context.Background()
	instanceTemplatesClient, err := compute.NewInstanceTemplatesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstanceTemplatesRESTClient: %w", err)
	}
	defer instanceTemplatesClient.Close()

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name: proto.String(templateName),
			Properties: &computepb.InstanceProperties{
				// The template describes the size and source image of the boot disk
				// to attach to the instance.
				Disks: []*computepb.AttachedDisk{
					{
						InitializeParams: &computepb.AttachedDiskInitializeParams{
							DiskSizeGb:  proto.Int64(250),
							SourceImage: proto.String("projects/debian-cloud/global/images/family/debian-11"),
						},
						AutoDelete: proto.Bool(true),
						Boot:       proto.Bool(true),
					},
				},
				MachineType: proto.String("e2-standard-4"),
				// The template connects the instance to the `default` network,
				// without specifying a subnetwork.
				NetworkInterfaces: []*computepb.NetworkInterface{
					{
						Name: proto.String("global/networks/default"),
						// The template lets the instance use an external IP address.
						AccessConfigs: []*computepb.AccessConfig{
							{
								Name:        proto.String("External NAT"),
								Type:        proto.String(computepb.AccessConfig_ONE_TO_ONE_NAT.String()),
								NetworkTier: proto.String(computepb.AccessConfig_PREMIUM.String()),
							},
						},
					},
				},
			},
		},
	}

	op, err := instanceTemplatesClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create instance template: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance template created\n")

	return nil
}

Java

import com.google.cloud.compute.v1.AccessConfig;
import com.google.cloud.compute.v1.AccessConfig.NetworkTier;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.GlobalOperationsClient;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
import com.google.cloud.compute.v1.InstanceProperties;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateInstanceTemplate {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // projectId: project ID or project number of the Cloud project you use.
    // templateName: name of the new template to create.
    String projectId = "your-project-id";
    String templateName = "template-name";
    createInstanceTemplate(projectId, templateName);
  }

  /*
    Create a new instance template with the provided name and a specific
    instance configuration.
   */
  public static void createInstanceTemplate(String projectId, String templateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create()) {

      String machineType = "e2-standard-4";
      String sourceImage = "projects/debian-cloud/global/images/family/debian-11";

      // The template describes the size and source image of the boot disk
      // to attach to the instance.
      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setSourceImage(sourceImage)
              .setDiskType("pd-balanced")
              .setDiskSizeGb(250).build())
          .setAutoDelete(true)
          .setBoot(true).build();

      // The template connects the instance to the `default` network,
      // without specifying a subnetwork.
      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName("global/networks/default")
          // The template lets the instance use an external IP address.
          .addAccessConfigs(AccessConfig.newBuilder()
              .setName("External NAT")
              .setType(AccessConfig.Type.ONE_TO_ONE_NAT.toString())
              .setNetworkTier(NetworkTier.PREMIUM.toString()).build()).build();

      InstanceProperties instanceProperties = InstanceProperties.newBuilder()
          .addDisks(attachedDisk)
          .setMachineType(machineType)
          .addNetworkInterfaces(networkInterface).build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(InstanceTemplate.newBuilder()
              .setName(templateName)
              .setProperties(instanceProperties).build()).build();

      // Create the Instance Template.
      Operation response = instanceTemplatesClient.insertAsync(insertInstanceTemplateRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance Template creation failed ! ! " + response);
        return;
      }
      System.out
          .printf("Instance Template Operation Status %s: %s", templateName, response.getStatus());
    }
  }

  public static void createInstanceTemplateWithDiskType(String projectId, String templateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create();
        GlobalOperationsClient globalOperationsClient = GlobalOperationsClient.create()) {

      AttachedDisk disk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setDiskSizeGb(10)
              .setDiskType("pd-balanced")
              .setSourceImage("projects/debian-cloud/global/images/family/debian-10").build())
          .setAutoDelete(true)
          .setBoot(true)
          .setType(AttachedDisk.Type.PERSISTENT.toString()).build();

      InstanceTemplate instanceTemplate = InstanceTemplate.newBuilder()
          .setName(templateName)
          .setProperties(InstanceProperties.newBuilder()
              .setMachineType("n1-standard-1")
              .addDisks(disk)
              .addNetworkInterfaces(NetworkInterface.newBuilder()
                  .setName("global/networks/default").build()).build()).build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(instanceTemplate).build();

      Operation response = instanceTemplatesClient.insertAsync(insertInstanceTemplateRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance Template creation failed ! ! " + response);
        return;
      }
      System.out
          .printf("Instance Template Operation Status %s: %s", templateName, response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const templateName = 'your_template_name';

const compute = require('@google-cloud/compute');

// Create a new instance template with the provided name and a specific instance configuration.
async function createTemplate() {
  const instanceTemplatesClient = new compute.InstanceTemplatesClient();

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: {
      name: templateName,
      properties: {
        disks: [
          {
            // The template describes the size and source image of the boot disk
            // to attach to the instance.
            initializeParams: {
              diskSizeGb: '250',
              sourceImage:
                'projects/debian-cloud/global/images/family/debian-11',
            },
            autoDelete: true,
            boot: true,
          },
        ],
        machineType: 'e2-standard-4',
        // The template connects the instance to the `default` network,
        // without specifying a subnetwork.
        networkInterfaces: [
          {
            // Use the network interface provided in the networkName argument.
            name: 'global/networks/default',
            // The template lets the instance use an external IP address.
            accessConfigs: [
              {
                name: 'External NAT',
                type: 'ONE_TO_ONE_NAT',
                networkTier: 'PREMIUM',
              },
            ],
          },
        ],
      },
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Instance template created.');
}

createTemplate();

Python

from __future__ import annotations

import sys
from typing import Any

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

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_template(project_id: str, template_name: str) -> compute_v1.InstanceTemplate:
    """
    Create a new instance template with the provided name and a specific
    instance configuration.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        template_name: name of the new template to create.

    Returns:
        InstanceTemplate object that represents the new instance template.
    """
    # The template describes the size and source image of the boot disk
    # to attach to the instance.
    disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = (
        "projects/debian-cloud/global/images/family/debian-11"
    )
    initialize_params.disk_size_gb = 250
    disk.initialize_params = initialize_params
    disk.auto_delete = True
    disk.boot = True

    # The template connects the instance to the `default` network,
    # without specifying a subnetwork.
    network_interface = compute_v1.NetworkInterface()
    network_interface.name = "global/networks/default"

    # The template lets the instance use an external IP address.
    access_config = compute_v1.AccessConfig()
    access_config.name = "External NAT"
    access_config.type_ = "ONE_TO_ONE_NAT"
    access_config.network_tier = "PREMIUM"
    network_interface.access_configs = [access_config]

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.properties.disks = [disk]
    template.properties.machine_type = "e2-standard-4"
    template.properties.network_interfaces = [network_interface]

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )

    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

既存のインスタンスに基づいてインスタンス テンプレートを作成する

Compute Engine API または gcloud CLI を使用して、既存の VM インスタンスの構成をインスタンス テンプレートとして保存できます。必要に応じて、テンプレートでソースディスクの定義方法をオーバーライドできます。

他のプロパティをオーバーライドする必要がある場合は、既存のインスタンスに基づいてインスタンス テンプレートを作成してから、オーバーライドを追加した同様のテンプレートを作成します。

gcloud

--source-instance フラグと --source-instance-zone フラグを指定して、gcloud compute instance-templates create コマンドを使用します。リージョン インスタンス テンプレートを作成する場合は、--instance-template-region フラグを使用してインスタンス テンプレートのリージョンも指定する必要があります。

リージョン インスタンス テンプレートを作成するには、次のコマンドを使用します。

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --source-instance=SOURCE_INSTANCE \
    --source-instance-zone=SOURCE_INSTANCE_ZONE \
    --instance-template-region=REGION

グローバル インスタンス テンプレートを作成するには、次のコマンドを使用します。

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --source-instance=SOURCE_INSTANCE \
    --source-instance-zone=SOURCE_INSTANCE_ZONE

ソース インスタンスのディスクの定義方法をオーバーライドするには、--configure-disk フラグを 1 つ以上追加します。

次の例では、既存のインスタンスからグローバル インスタンス テンプレートを作成し、指定した仕様でソース インスタンスのディスクをオーバーライドします。

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --source-instance=SOURCE_INSTANCE \
    --source-instance-zone=SOURCE_INSTANCE_ZONE \
    --configure-disk= \
        device-name=SOURCE_DISK, \
        instantiate-from=INSTANTIATE_OPTIONS, \
        auto-delete=AUTO_DELETE

次のように置き換えます。

  • INSTANCE_TEMPLATE_NAME: 作成するテンプレートの名前。
  • SOURCE_INSTANCE: 新しいテンプレートのモデルとして使用するインスタンスの名前。
  • SOURCE_INSTANCE_ZONE: ソース インスタンスを含むゾーン。
  • REGION: リージョン インスタンス テンプレートを作成するリージョン。
  • SOURCE_DISK: テンプレート内でオーバーライドするソース インスタンスのディスクの名前。
  • INSTANTIATE_OPTIONS: ディスクを組み込むかどうかを指定します。組み込む場合は、どのイメージを使用するかを指定します。有効な値は、ディスクのタイプによって異なります。

    • source-image または source-image-family(ブートディスクとその他の読み取り / 書き込み用の永続ディスクにのみ有効)。ソース VM インスタンスでディスクの作成に使用したものと同じソースイメージまたはソースイメージ ファミリーを使用する場合は、このオプションを指定します。
    • custom-image(ブートディスクとその他の読み取り / 書き込み用の永続ディスクにのみ有効)。インスタンス テンプレートのソース VM のアプリケーションと設定を保持する場合は、カスタム イメージを作成して、テンプレートを作成するときに指定できます。指定する場合、次の例のようにカスタム イメージのパスまたは URL を指定します。また、次の形式を使用してイメージ ファミリーを指定することもできます。

      --configure-disk=device-name=DATA_DISK_NAME,instantiate-from=custom-image,
      custom-image=projects/PROJECT_ID/global/images/family/IMAGE_FAMILY_NAME

    • attach-read-only(読み取り専用ディスクにのみ有効)。

    • blank(ブートディスク以外の永続ディスクとローカル SSD にのみ有効)。指定した場合、テンプレートを使用して新しいインスタンスを作成すると、ディスクはフォーマットされていない状態で作成されます。スケーラブルな設定でディスクを使用するには、起動スクリプトでディスクをフォーマットしてマウントする必要があります。

    • do-not-include(ブートディスク以外の永続ディスクと読み取り専用ディスクにのみ有効)。

  • インスタンスを削除したときに AUTO_DELETE でディスクを自動削除するかどうかを指定します。有効な値は falsenotrueyes です。

たとえば、次のコマンドは my-source-instance に基づくインスタンス テンプレートを作成して、data-disk-a からオリジナルのイメージを使用することもできますが、自動削除を true に設定し、data-disk-bをカスタム イメージに置き換えます。

gcloud compute instance-templates create my-instance-template  \
    --source-instance=my-source-instance \
    --configure-disk=device-name=data-disk-a,instantiate-from=source-image, \
      auto-delete=true
    --configure-disk=device-name=data-disk-b,instantiate-from=custom-image, \
      custom-image=projects/cps-cloud/global/images/cos-89-16108-403-15

API

リージョン インスタンス テンプレートを作成するには、regionInstanceTemplates.insert メソッドを使用します。グローバル インスタンス テンプレートを作成するには、instanceTemplates.insert メソッド を使用します。

リクエストでは、sourceInstance フィールドを指定する必要があります。ソース インスタンスのディスクの定義方法をオーバーライドするには、1 つ以上の diskConfigs フィールドを追加します。

たとえば、既存のインスタンスからグローバル インスタンス テンプレートを作成するには、次の呼び出しを行います。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/instanceTemplates

{
  "name": "INSTANCE_TEMPLATE_NAME",
  "sourceInstance": "zones/SOURCE_INSTANCE_ZONE/instances/SOURCE_INSTANCE",
  "sourceInstanceParams": {
    "diskConfigs": [
      {
        "deviceName": "SOURCE_DISK",
        "instantiateFrom": "INSTANTIATE_OPTIONS",
        "autoDelete": false
      }
    ]
  }
}

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID
  • INSTANCE_TEMPLATE_NAME: 新しいテンプレートの名前。
  • SOURCE_INSTANCE_ZONE: ソース インスタンスのゾーン。
  • SOURCE_INSTANCE: このインスタンス テンプレートのモデルとして使用するソース インスタンスの名前。
  • SOURCE_DISK: テンプレート内でオーバーライドするソース インスタンスのディスクの名前。
  • INSTANTIATE_OPTIONS: ディスクを組み込むかどうかを指定します。組み込む場合は、どのイメージを使用するかを指定します。

    有効な値は、ディスクのタイプによって異なります。

    • source-image または source-image-family(ブートディスクとその他の読み取り / 書き込み用の永続ディスクにのみ有効)。
    • custom-image(ブートディスクとその他の読み取り / 書き込み用の永続ディスクにのみ有効)。インスタンス テンプレートのソース VM のアプリケーションと設定を保持する場合は、カスタム イメージを作成して、テンプレートを作成するときに指定できます。指定する場合、次の例のようにカスタム イメージのパスまたは URL を指定します。また、次の形式を使用してイメージ ファミリーを指定することもできます。

      --configure-disk=device-name=DATA_DISK_NAME,instantiate-from=custom-image,
      custom-image=projects/PROJECT_ID/global/images/family/IMAGE_FAMILY_NAME

    • attach-read-only(読み取り専用ディスクにのみ有効)。

    • blank(ブートディスク以外の永続ディスクとローカル SSD にのみ有効)。指定した場合、テンプレートを使用して新しいインスタンスを作成すると、ディスクはフォーマットされていない状態で作成されます。スケーラブルな設定でディスクを使用するには、起動スクリプトでディスクをフォーマットしてマウントする必要があります。

    • do-not-include(ブートディスク以外の永続ディスクと読み取り専用ディスクにのみ有効)。

次の例では、my-source-instance に基づく新しいインスタンス テンプレートを作成しています。インスタンス テンプレートでは、data-disk-a のイメージは projects/cos-cloud/global/images/cos-89-16108-403-15 に置き換えられます。

POST https://compute.googleapis.com/compute/v1/projects/my_project/global/instanceTemplates

{
  "name": "my-instance-template",
  "sourceInstance": "zones/us-central1-a/instances/my-source-instance",
  "sourceInstanceParams":
  {
    "diskConfigs":
    [
      {
        "deviceName": "data-disk-a",
        "instantiateFrom": "custom-image",
        "customImage": "projects/cos-cloud/global/images/cos-89-16108-403-15"
      }
    ]
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
	"google.golang.org/protobuf/proto"
)

// createTemplateFromInstance creates a new instance template based on an existing instance.
// This new template specifies a different boot disk.
func createTemplateFromInstance(w io.Writer, projectID, instance, templateName string) error {
	// projectID := "your_project_id"
	// instance := "projects/project/zones/zone/instances/instance"
	// templateName := "your_template_name"

	ctx := context.Background()
	instanceTemplatesClient, err := compute.NewInstanceTemplatesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstanceTemplatesRESTClient: %w", err)
	}
	defer instanceTemplatesClient.Close()

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name:           proto.String(templateName),
			SourceInstance: proto.String(instance),
			SourceInstanceParams: &computepb.SourceInstanceParams{
				DiskConfigs: []*computepb.DiskInstantiationConfig{
					{
						// Device name must match the name of a disk attached to the instance
						// your template is based on.
						DeviceName: proto.String("disk-1"),
						// Replace the original boot disk image used in your instance with a Rocky Linux image.
						InstantiateFrom: proto.String(computepb.DiskInstantiationConfig_CUSTOM_IMAGE.String()),
						CustomImage:     proto.String("projects/rocky-linux-cloud/global/images/family/rocky-linux-8"),
						// Override the auto_delete setting.
						AutoDelete: proto.Bool(true),
					},
				},
			},
		},
	}

	op, err := instanceTemplatesClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create instance template: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance template created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.DiskInstantiationConfig;
import com.google.cloud.compute.v1.DiskInstantiationConfig.InstantiateFrom;
import com.google.cloud.compute.v1.GlobalOperationsClient;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.SourceInstanceParams;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateTemplateFromInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // projectId: project ID or project number of the Cloud project you use.
    // instance: the instance to base the new template on. This value uses the following format:
    // **NOTE**: "projects/{project}/zones/{zone}/instances/{instance_name}"
    // templateName: name of the new template to create.
    String projectId = "your-project-id";
    String templateName = "template-name";
    String instance = String.format("projects/%s/zones/%s/instances/%s", projectId, "zone",
        "instanceName");
    createTemplateFromInstance(projectId, templateName, instance);
  }

  // Create a new instance template based on an existing instance.
  // This new template specifies a different boot disk.
  public static void createTemplateFromInstance(String projectId, String templateName,
      String instance)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create();
        GlobalOperationsClient globalOperationsClient = GlobalOperationsClient.create()) {

      SourceInstanceParams sourceInstanceParams = SourceInstanceParams.newBuilder()
          .addDiskConfigs(DiskInstantiationConfig.newBuilder()
              // Device name must match the name of a disk attached to the instance you are
              // basing your template on.
              .setDeviceName("disk-1")
              // Replace the original boot disk image used in your instance
              // with a Rocky Linux image.
              .setInstantiateFrom(InstantiateFrom.CUSTOM_IMAGE.toString())
              .setCustomImage(
                  String.format("projects/%s/global/images/family/%s", "rocky-linux-cloud",
                      "rocky-linux-8"))
              // Override the AutoDelete setting.
              .setAutoDelete(true).build())
          .build();

      InstanceTemplate instanceTemplate = InstanceTemplate.newBuilder()
          .setName(templateName)
          .setSourceInstance(instance)
          .setSourceInstanceParams(sourceInstanceParams)
          .build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(instanceTemplate)
          .build();

      Operation operation = instanceTemplatesClient.insertCallable()
          .futureCall(insertInstanceTemplateRequest).get(3, TimeUnit.MINUTES);

      Operation response = globalOperationsClient.wait(projectId, operation.getName());

      if (response.hasError()) {
        System.out.println("Instance Template creation failed ! ! " + response);
        return;
      }
      System.out.printf("Instance Template creation operation status %s: %s", templateName,
          response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const instance = 'projects/project/zones/zone/instances/instance';
// const templateName = 'your_template_name';

const compute = require('@google-cloud/compute');

// Create a new instance template based on an existing instance.
// This new template specifies a different boot disk.
async function createTemplateFromInstance() {
  const instanceTemplatesClient = new compute.InstanceTemplatesClient();

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: {
      name: templateName,
      sourceInstance: instance,
      sourceInstanceParams: {
        diskConfigs: [
          {
            // Device name must match the name of a disk attached to the instance
            // your template is based on.
            deviceName: 'disk-1',
            // Replace the original boot disk image used in your instance with a Rocky Linux image.
            instantiateFrom: 'CUSTOM_IMAGE',
            customImage:
              'projects/rocky-linux-cloud/global/images/family/rocky-linux-8',
            // Override the auto_delete setting.
            autoDelete: true,
          },
        ],
      },
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Instance template created.');
}

createTemplateFromInstance();

Python

from __future__ import annotations

import sys
from typing import Any

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

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_template_from_instance(
    project_id: str, instance: str, template_name: str
) -> compute_v1.InstanceTemplate:
    """
    Create a new instance template based on an existing instance.
    This new template specifies a different boot disk.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        instance: the instance to base the new template on. This value uses
            the following format: "projects/{project}/zones/{zone}/instances/{instance_name}"
        template_name: name of the new template to create.

    Returns:
        InstanceTemplate object that represents the new instance template.
    """
    disk = compute_v1.DiskInstantiationConfig()
    # Device name must match the name of a disk attached to the instance you are
    # basing your template on.
    disk.device_name = "disk-1"
    # Replace the original boot disk image used in your instance with a Rocky Linux image.
    disk.instantiate_from = "CUSTOM_IMAGE"
    disk.custom_image = "projects/rocky-linux-cloud/global/images/family/rocky-linux-8"
    # Override the auto_delete setting.
    disk.auto_delete = True

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.source_instance = instance
    template.source_instance_params = compute_v1.SourceInstanceParams()
    template.source_instance_params.disk_configs = [disk]

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )

    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

次の表は、ディスクをオーバーライドするオプションがテンプレートでどのように定義されるかを示しています。

ディスクタイプ オプション
ブートディスク
  • [デフォルト] ソース インスタンスでブートディスクを作成するために使用されたソースイメージまたはイメージ ファミリーと同じものを使用します。
  • 前の例で説明したように、任意のイメージ(カスタムまたは公開)の URL を使用するか、次の形式を使用してイメージ ファミリーを指定します。

    projects/exampleproject/global/images/family/IMAGE_FAMILY_NAME

その他の読み取り / 書き込み用の永続ディスク
  • [デフォルト] ソース インスタンスでディスクを作成するために使用されたソースイメージまたはソースイメージ ファミリーと同じものを使用します。注: ソース インスタンスのディスクにソースイメージまたはソースイメージ ファミリーのプロパティがない場合、空のディスクとしてテンプレートに含まれます。
  • 前の例で説明したように、任意のイメージ(カスタムまたは公開)の URL を使用するか、次の形式を使用してイメージ ファミリーを指定します。

    projects/exampleproject/global/images/family/IMAGE_FAMILY_NAME

  • 代わりに空のディスクをテンプレートで使用します。テンプレートを使用して新しいインスタンスを作成すると、このディスクはフォーマットされていない状態で作成されます。スケーラブルな設定でディスクを使用するには、起動スクリプトでディスクをフォーマットしてマウントする必要があります。
  • ディスクを組み込みません。
読み取り専用ディスク
  • [デフォルト] ディスクを読み取り専用モードで組み込みます。
  • ディスクを組み込みません。
ローカル SSD
  • [デフォルト] 空のローカル SSD を組み込みます。テンプレートを使用して新しいインスタンスを作成すると、このディスクはフォーマットされていない状態で作成されます。スケーラブルな設定でディスクを使用するには、起動スクリプトでディスクをフォーマットしてマウントする必要があります。

ディスクごとで auto-delete 属性をオーバーライドして、関連付けられたインスタンスが削除されるときにディスクを削除するかどうかも指定できます。

デフォルトでは、オーバーライド オプションが指定されていない場合、テンプレート内のディスク構成はソース インスタンスと同じになります。

既存のテンプレートに基づいてインスタンス テンプレートを作成する

既存のインスタンス テンプレートを更新することはできません。ただし、インスタンス テンプレートが最新でなくなった場合や、変更を行う必要がある場合は、コンソールを使用して、同様のプロパティを持つ別のインスタンス テンプレートを作成できます。

  1. [インスタンス テンプレート] ページに移動します。

    [インスタンス テンプレート] に移動

  2. コピーして更新するインスタンス テンプレートをクリックします。

  3. [同様のものを作成] をクリックします。

  4. 新しいテンプレートで構成を更新します。

  5. [作成] をクリックします。

コンテナ イメージを指定してインスタンス テンプレートを作成する

インスタンス テンプレートでコンテナ イメージを指定できます。デフォルトでは、Compute Engine によって、Docker がインストールされた Container-Optimized OS イメージもテンプレートに組み込まれます。テンプレートを使用して新しいインスタンスを作成すると、インスタンスの起動時にコンテナが自動的に起動されます。

Console

  1. [インスタンス テンプレート] ページに移動します。

    [インスタンス テンプレート] に移動

  2. [インスタンス テンプレートを作成] をクリックします。

  3. [コンテナ] セクションで、[コンテナをデプロイ] をクリックします。

  4. [コンテナを構成] ダイアログで、使用するコンテナ イメージを指定します。

    • Container Registry または Artifact Registry からイメージを指定できます。次に例を示します。
      • gcr.io/cloud-marketplace/google/nginx1:TAG。ここで、TAG は Google Cloud Marketplace で利用可能な特定バージョンの NGINX コンテナ イメージ用に定義されたタグです。
      • us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 は、Artifact Registry に格納されているサンプル hello-app イメージを選択します。
    • Docker Hub のコンテナ イメージを使用する場合は、常に完全な Docker イメージ名を指定します。たとえば、Apache コンテナ イメージをデプロイするには、次のイメージ名 docker.io/httpd:2.4 を指定します。
  5. 必要に応じて、[コンテナの詳細オプション] をクリックします。詳細については、コンテナを実行する際のオプションの構成をご覧ください。

  6. [作成] をクリックします。

gcloud

gcloud compute instance-templates create-with-container コマンドを実行します。

gcloud compute instance-templates create-with-container INSTANCE_TEMPLATE_NAME \
     --container-image=CONTAINER_IMAGE

次のように置き換えます。

  • INSTANCE_TEMPLATE_NAME: 作成するテンプレートの名前。
  • CONTAINER_IMAGE: 使用するコンテナ イメージの完全な名前。

たとえば、次のコマンドは nginx-vm という新しいインスタンス テンプレートを作成します。このテンプレートから作成された VM インスタンスは、起動時にコンテナ イメージ gcr.io/cloud-marketplace/google/nginx1:TAG を起動して実行します。

gcloud compute instance-templates create-with-container nginx-vm \
     --container-image=gcr.io/cloud-marketplace/google/nginx1:TAG

TAG を、Google Cloud Marketplace で利用可能な特定バージョンの NGINX コンテナ イメージ用に定義されたタグに置き換えます。

コンテナの実行オプションを構成することもできます。

サブネットを指定してインスタンス テンプレートを作成する

gcloud

リージョンまたはグローバルのインスタンス テンプレートを作成するには、instance-templates create コマンドを使用します。--subnet フラグを使用して、テンプレートから作成されたインスタンスを任意のサブネットに配置します。--subnet フラグには --region フラグが必要です。

リージョン インスタンス テンプレートを作成する場合は、--instance-template-region フラグを使用してテンプレートのリージョンを設定する必要があります。リージョン インスタンス テンプレートを作成するリージョンと同じリージョンのサブネットを使用してください。

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
  --region=REGION \
  --subnet=SUBNET_NAME_OR_URL \
  --instance-template-region=INSTANCE_TEMPLATE_REGION

次のように置き換えます。

  • INSTANCE_TEMPLATE_NAME: インスタンス テンプレートの名前
  • REGION: サブネットのリージョン
  • SUBNET_NAME_OR_URL: サブネットの名前またはその URL

  • INSTANCE_TEMPLATE_REGION: インスタンス テンプレートを作成するリージョン。REGION と同じにする必要があります。

次の例では、subnet-us-qa サブネットでのみインスタンスを作成する template-qa というテンプレートを作成しています。

gcloud compute instance-templates create template-qa \
  --region=us-central1 \
  --subnet=subnet-us-qa

Created [https://compute.googleapis.com/compute/latest/projects/PROJECT_ID/global/instanceTemplates/template-qa].
NAME        MACHINE_TYPE        PREEMPTIBLE CREATION_TIMESTAMP
template-qa e2-standard-2       2019-12-23T20:34:00.791-07:00

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
	"google.golang.org/protobuf/proto"
)

// createTemplateWithSubnet creates an instance template that uses a provided subnet.
func createTemplateWithSubnet(w io.Writer, projectID, network, subnetwork, templateName string) error {
	// projectID := "your_project_id"
	// network := "projects/project/global/networks/network"
	// subnetwork := "projects/project/regions/region/subnetworks/subnetwork"
	// templateName := "your_template_name"

	ctx := context.Background()
	instanceTemplatesClient, err := compute.NewInstanceTemplatesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstanceTemplatesRESTClient: %w", err)
	}
	defer instanceTemplatesClient.Close()

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name: proto.String(templateName),
			Properties: &computepb.InstanceProperties{
				// The template describes the size and source image of the boot disk
				// to attach to the instance.
				Disks: []*computepb.AttachedDisk{
					{
						InitializeParams: &computepb.AttachedDiskInitializeParams{
							DiskSizeGb:  proto.Int64(250),
							SourceImage: proto.String("projects/debian-cloud/global/images/family/debian-11"),
						},
						AutoDelete: proto.Bool(true),
						Boot:       proto.Bool(true),
					},
				},
				MachineType: proto.String("e2-standard-4"),
				// The template connects the instance to the specified network and subnetwork.
				NetworkInterfaces: []*computepb.NetworkInterface{
					{
						Network:    proto.String(network),
						Subnetwork: proto.String(subnetwork),
					},
				},
			},
		},
	}

	op, err := instanceTemplatesClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create instance template: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance template created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.GlobalOperationsClient;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
import com.google.cloud.compute.v1.InstanceProperties;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateTemplateWithSubnet {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /*
    TODO(developer): Replace these variables before running the sample.
    projectId: project ID or project number of the Cloud project you use.
    network: the network to be used in the new template. This value uses
        the following format: "projects/{project}/global/networks/{network}"
    subnetwork: the subnetwork to be used in the new template. This value
        uses the following format: "projects/{project}/regions/{region}/subnetworks/{subnetwork}"
    templateName: name of the new template to create.
    */
    String projectId = "your-project-id";
    String network = String.format("projects/%s/global/networks/%s", projectId, "network");
    String subnetwork = String.format("projects/%s/regions/%s/subnetworks/%s", projectId, "region",
        "subnetwork");
    String templateName = "template-name";
    createTemplateWithSubnet(projectId, network, subnetwork, templateName);
  }

  // Create an instance template that uses a provided subnet.
  public static void createTemplateWithSubnet(String projectId, String network, String subnetwork,
      String templateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create();
        GlobalOperationsClient globalOperationsClient = GlobalOperationsClient.create()) {

      AttachedDisk disk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setSourceImage(
                  String.format("projects/%s/global/images/family/%s", "debian-cloud", "debian-11"))
              .setDiskSizeGb(250).build())
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      InstanceProperties instanceProperties = InstanceProperties.newBuilder()
          .addDisks(disk)
          .setMachineType("e2-standard-4")
          .addNetworkInterfaces(NetworkInterface.newBuilder()
              .setNetwork(network)
              .setSubnetwork(subnetwork).build())
          .build();

      InstanceTemplate instanceTemplate = InstanceTemplate.newBuilder()
          .setName(templateName)
          .setProperties(instanceProperties)
          .build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(instanceTemplate)
          .build();

      Operation operation = instanceTemplatesClient.insertCallable()
          .futureCall(insertInstanceTemplateRequest).get(3, TimeUnit.MINUTES);

      Operation response = globalOperationsClient.wait(projectId, operation.getName());

      if (response.hasError()) {
        System.out.println("Template creation from subnet failed ! ! " + response);
        return;
      }
      System.out.printf("Template creation from subnet operation status %s: %s", templateName,
          response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const network = 'projects/project/global/networks/network';
// const subnetwork = 'projects/project/regions/region/subnetworks/subnetwork';
// const templateName = 'your_template_name';

const compute = require('@google-cloud/compute');

// Create an instance template that uses a provided subnet.
async function createTemplateWithSubnet() {
  const instanceTemplatesClient = new compute.InstanceTemplatesClient();

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: {
      name: templateName,
      properties: {
        // The template describes the size and source image of the boot disk
        // to attach to the instance.
        disks: [
          {
            // The template describes the size and source image of the boot disk
            // to attach to the instance.
            initializeParams: {
              diskSizeGb: '250',
              sourceImage:
                'projects/debian-cloud/global/images/family/debian-11',
            },
            autoDelete: true,
            boot: true,
          },
        ],
        machineType: 'e2-standard-4',
        // The template connects the instance to the specified network and subnetwork.
        networkInterfaces: [
          {
            network,
            subnetwork,
          },
        ],
      },
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Instance template created.');
}

createTemplateWithSubnet();

Python

from __future__ import annotations

import sys
from typing import Any

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

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_template_with_subnet(
    project_id: str, network: str, subnetwork: str, template_name: str
) -> compute_v1.InstanceTemplate:
    """
    Create an instance template that uses a provided subnet.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        network: the network to be used in the new template. This value uses
            the following format: "projects/{project}/global/networks/{network}"
        subnetwork: the subnetwork to be used in the new template. This value
            uses the following format: "projects/{project}/regions/{region}/subnetworks/{subnetwork}"
        template_name: name of the new template to create.

    Returns:
        InstanceTemplate object that represents the new instance template.
    """
    # The template describes the size and source image of the book disk to
    # attach to the instance.
    disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = (
        "projects/debian-cloud/global/images/family/debian-11"
    )
    initialize_params.disk_size_gb = 250
    disk.initialize_params = initialize_params
    disk.auto_delete = True
    disk.boot = True

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.properties = compute_v1.InstanceProperties()
    template.properties.disks = [disk]
    template.properties.machine_type = "e2-standard-4"

    # The template connects the instance to the specified network and subnetwork.
    network_interface = compute_v1.NetworkInterface()
    network_interface.network = network
    network_interface.subnetwork = subnetwork
    template.properties.network_interfaces = [network_interface]

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )
    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

このテンプレートを使用して MIG のインスタンスを作成すると(自動スケーリングの設定は任意)、指定したリージョンとサブネットにインスタンスが自動的に作成されます。これにより、ロード バランシングのために新規作成するインスタンスのサブネットを制御できるようになります。

インスタンス テンプレートでカスタム イメージまたは公開イメージを使用する

インスタンス テンプレートには、カスタム イメージまたは公開イメージを使用できます。

  • カスタム イメージ。MIG はインスタンスの追加と削除が頻繁に行われることを想定した設計であるため、カスタム イメージを作成し、それをインスタンス テンプレートで指定するようにすると便利です。VM に必要なアプリケーションと設定でイメージを準備できるため、MIG の個々の VM でこれらの項目を手動で構成する必要はありません。

  • 公開イメージ公開イメージ起動スクリプトを使用するインスタンス テンプレートを作成し、それを起動してインスタンスを準備できます。

カスタム イメージは起動スクリプトを使用する VM より確定的であり、起動時間が短くなります。ただし、起動スクリプトのほうが柔軟性が高く、インスタンス内のアプリと設定を簡単に更新できます。

イメージ ファミリーを使用してイメージを管理している場合、カスタム イメージまたは公開イメージのファミリー名をインスタンス テンプレートに指定できます。イメージ ファミリーの詳細については、Compute Engine でイメージ ファミリーを使用する場合のベスト プラクティスをご覧ください。

次のステップ