🖋️

Compute Engine インスタンス名の変更が及ぼす影響を確認する

2023/12/26に公開

ご挨拶

こんにちは、クラウドエース株式会社で SRE をしている谷口です。

クリスマスも過ぎて、あっという間に年の瀬という雰囲気が漂っております。
個人的な内容で恐縮ですが、今年はワーケーションを活用して自分の普段行かないところに行く機会が増えた良い1年になりました。

さて、そんな年の瀬の 12月に Compute Engine の VM インスタンス名を後から変更出来る機能が GA になりました。

過去に作った VM インスタンスの名前が test-<任意の文字列>instance-hogehogeyyyy-mm-dd になりがちな私にとってはありがたいアップデートなのですが、ふと「インスタンス名の変更によって何か副作用は無いのか?」が気になりました。

この記事では「インスタンス名変更によってどのような影響が及ぶのか、何に気をつけておくべきか」を紹介します。

今回のリリース内容

2023年12月20日の リリースノート に記載の通り、VM インスタンスの名前変更が GA となりました。

これまでは、VM インスタンスを作成後は再作成をしない限りインスタンスの名前変更はできませんでしたが、これからはインスタンスが停止状態(TERMINATED)であれば名前を変更出来るようになります。

公式ドキュメントによるガイドは こちら になります。

VM インスタンスの名前変更による影響は?

VM 名がラフに変更出来るようになった事で、VM を参照している他の Google Cloud のリソースに影響はあるのでしょうか。
例えば、VM インスタンスの名前が意図せず書き換わってしまった事で生じる不具合は無いのでしょうか?

一例として インスタンス グループ では、グループに所属している VM インスタンスの名前を変更することは出来ないようになっています。
他にも、GKE の Standard クラスタを構成して作成されたノード用の VM もインスタンス グループによって作成しているため、後から名前を変更出来ません。

rename-vm-in-group.png

ただし、非マネージド インスタンス グループについては、VM をグループから除外すれば名前を変更出来るようになっています。
権限を持っていれば簡単に操作出来てしまいますので、状況によっては権限を見直す必要があるかもしれません。

Terraform で管理している VM インスタンスは?

Terraform を使って VM インスタンスを構築している場合、残念ながら現在の プロバイダー(バージョン 5.10.0)は名前変更の API に対応しておりません。
そのため、Terraform で構築した VM インスタンスの名前を後から変更する場合はインスタンスが 再作成 されてしまうので注意してください。

この Terraform で構築された VM インスタンスの名前を Terraform 以外の方法 で変更した場合、Terraform 上での扱いはどうなってしまうのでしょうか?

結果は Terraform の管理から外れ、新たに VM が作成 されてしまいます。

サンプル コード
main.tf
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "= 5.10.0"
    }
  }
  required_version = "= 1.6.6"
}

provider "google" {
}

resource "google_compute_instance" "test" {
  name         = "test-instance"
  machine_type = "f1-micro"
  project      = "example-project-id"
  zone         = "asia-northeast1-b"

  boot_disk {
    device_name = "test-instance"

    initialize_params {
      image = "debian-cloud/debian-11"
      size  = 20
      type  = "pd-standard"
    }
  }

  network_interface {
    subnetwork = "projects/example-project-id/regions/asia-northeast1/subnetworks/subnet-test"
  }
}
実行結果
1:Terraform で VM インスタンス(test-instance)を構築
$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_compute_instance.test will be created
  + resource "google_compute_instance" "test" {
      + name                 = "test-instance"
      + project              = "example-project-id"
      + zone                 = "asia-northeast1-b"
      (省略)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

[id=projects/example-project-id/zones/asia-northeast1-b/instances/test-instance]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
2:gcloud コマンドで名前を変更(renamed-test-instance)
$ gcloud compute instances stop test-instance --zone asia-northeast1-b --project=example-project-id
Updated [https://compute.googleapis.com/compute/v1/projects/example-project-id/zones/asia-northeast1-b/instances/test-instance].

$ gcloud compute instances set-name test-instance --zone asia-northeast1-b --new-name renamed-test-instance --project=example-project-id
Updated [https://www.googleapis.com/compute/v1/projects/example-project-id/zones/asia-northeast1-b/instances/test-instance].
3:Terraform の Plan を確認
$ terraform plan
google_compute_instance.test: Refreshing state... [id=projects/example-project-id/zones/asia-northeast1-b/instances/test-instance]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_compute_instance.test will be created
  + resource "google_compute_instance" "test" {
      + name                 = "test-instance"
      + project              = "example-project-id"
      + zone                 = "asia-northeast1-b"
      (省略)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

実行結果の terraform plan ログに出力されていますが、今回作成した VM インスタンス(test-instance)の id にはインスタンス名が含まれています。
この id は、Terraform が変更管理をする上でリソースを特定するために使用する一意となる文字列になっています。

google_compute_instance.test: Refreshing state... [id=projects/example-project-id/zones/asia-northeast1-b/instances/test-instance]

そのため、名前変更後(renamed-test-instance)の VM を、Terraform で管理している VM と同一のリソースではないと認識しているようです。

繰り返しとなりますが、VM インスタンスの名前変更自体は停止状態でなければ実施出来ないので、常時稼働している VM インスタンスであれば停止させない限りは名前変更は出来ません。
が、状況によっては意図しないリソースの再構築が発生する可能性もあるため、注意が必要です。

この Terraform の動作については、名前変更機能への対応に加え今後のアップデートによって改善される可能性があります。

リソース参照に使う URI

公式ドキュメント にも記載されている通り、名前が変更出来るようになることで VM インスタンス名を用いた ユニフォーム リソース識別子(URI) が変更になります。

URI とは、リソースを一意に識別するための文字列であり、Google Cloud 上のリソースはこの URI によってリソースを一意に識別可能となっており、Terraform でもこの URI をリソースの識別可能な文字列として利用しています。

VM インスタンスの URI は次のように表現出来ますが、今回からインスタンス名(リソース名)が変更出来るようになり、同じ URI を使って VM インスタンスを参照出来なくなってしまいます。

projects/<プロジェクト ID>/zones/<Zone>/instances/<インスタンス名>

これの解決策として、ドキュメントにも触れられている通り インスタンス名ではなく VM の ID を使う 事が推奨されています。
VM インスタンスの URI を次のように書き換えることで、名前が変更された後も同じ VM インスタンスを参照出来るようになります。

projects/<プロジェクト ID>/zones/<Zone>/instances/<VM ID>

VM インスタンスの ID は、各 VM インスタンスの詳細ページを開く事で確認出来ます。

describe-vm-id.png

ただし、リソースの URI を意識しながら Google Cloud でリソースを構築するケースというのはかなり少なく、基本的には GUI や gcloud コマンドを使って構築する場合は、引き続き VM インスタンス名を利用するケースが大多数かと思います。

そのため、Terraform などの他のツール類も含め、今後のアップデートで VM ID が利用されるようになるまでの間は、意図しない名前変更が発生しないように注意する必要がありそうです。

意図しない名前変更を防ぐには?

既に対策として触れている通り、基本的には IAM による権限制御が必要となります。

VM インスタンスの名前を変更するためには、今回 Compute Engine API に追加された instances.setName の実行権限が必要で、具体的には compute.instances.setName 権限を持つ IAM ロールが付与されている必要があります。

付与出来るロールの中から、上記の権限を持つロールの一覧を検索する場合、Cloud Console の ロール を開き、画像のように検索することで対象の IAM ロールを確認出来ます。

find-role-has-setname-perm.png

まとめ

今回は、新たに GA となった VM インスタンスの名前変更機能とその副作用についてまとめました。
自由に名前が変更出来るようになった反面、これまで不変であった URI が変更となってしまう事で、実は考慮すべき点が増えているという事が分かりました。
皆さんも、大事な VM インスタンスを抱えている場合は適切な権限管理を行うようにしましょう。

Discussion