Terraform Google Provider 6.0.0 の新機能と変更点について
こんにちは、クラウドエース株式会社 SRE 部の阿部です。
この記事ではメジャーアップデートした Terraform Google Provider 6.0.0 の新機能と変更点について紹介します。
概要
2024 年 8 月 27 日に、Terraform の Google Cloud 向けプラグイン(Provider)である Terraform Google Provider が 6.0.0 にバージョンアップしました。
また、同日に 6.0.1 もリリースされております。
このブログ記事では、6.0.1 の内容もあわせて紹介します。
対象読者
- Terraform で Google Cloud の構築・運用をしているエンジニア
- メジャーバージョン間の非互換が気になる方
変更点概要
- プロバイダデフォルトラベル(
goog-terraform-provisioned
)が自動付与されるようになりました - いくつかのリソースの
name_prefix
の最大長を 37 文字から 54 文字に拡大しました -
google_project
を含むいくつかのリソースで削除防止フィールドが追加されました
また、上記以外にも多数のリソースにおいて機能追加、非互換、および、機能削除があります。
詳細は後述の参考リンクから、変更点を確認してください。
バージョン 5.x 系からアップグレードする場合の注意点
公式の 6.0.0 アップグレードガイドでは、まず 5.x 系の最新バージョン(記事執筆時点では 5.48.1)にアップグレードしてから、アップグレードガイドに記載されている変更内容や廃止項目に応じて修正し、 terraform plan
で予期しない変更がないかを確認しながらアップグレードすることを推奨しています。
また、アップグレードガイドには記載されていませんが、念のため terraform state pull
コマンドで State ファイルをバックアップしておくことをおすすめします。
バージョン 6.0.0 から 5.x 系へのダウングレードについて
terraform init
や terraform plan
を実行しただけでは State ファイルは更新されないため、もし意図せず 6.0.0 以降になってしまった場合は、 Provider version constraint を使って元々使用していたバージョンに固定してから、再度 terraform init -upgrade
を実行しましょう。
terraform refresh
や terraform apply
を実行すると、State ファイルが更新されるため、事前に取得した State ファイルのバックアップを使って戻すか、 Cloud Storage のオブジェクトバージョニングを使って戻すことを検討してください。
参考リンク
- v6.0.0 リリースノート
- v6.0.1 リリースノート
- Terraform Google Provider 6.0.0 Upgrade Guide
- Google ブログ: Announcing Terraform Google Provider 6.0.0: More Flexibility, Better Control
- Hashicorp ブログ: Terraform provider for Google Cloud 6.0 is now GA
新機能
バージョン 6.0.0 で追加された新機能について紹介します。
プロバイダデフォルトラベルの自動付与
プロバイダデフォルトラベル(goog-terraform-provisioned
)が自動付与されるようになりました。
これは バージョン 5.16.0 からオプトインすることで使用可能な機能で、 6.0.0 からはデフォルトで有効になりました。
これにより、リソースが Terraform で作成されたのか、 Google Cloud コンソールや gcloud CLI 等別の手段で作成されたのかを識別することができます。
この機能は新規作成リソースのみで有効であり、作成済みリソースには適用されません。
デフォルトラベル適用を無効にする場合は、 provider ブロックで以下のように設定します。
provider "google" {
# デフォルトラベル適用を無効にする
add_terraform_attribution_label = false
}
また、デフォルトラベルを既存リソースにも適用する場合は、以下のように設定します。
provider "google" {
# 既存リソースにもデフォルトラベルを適用する。デフォルトは "CREATION_ONLY"
terraform_attribution_label_addition_strategy = "PROACTIVE"
}
name_prefix
の最大長を 37 文字から 54 文字に拡大
インスタンステンプレート(google_compute_instance_template
)等のリソースでは作成時に name_prefix
を使う事で名前の重複を防ぐことができました。
インスタンステンプレートはリリース毎に頻繁に入れ替えるリソースのため、 Terraform の式でユニークな name
を計算するよりも便利です。
ただ、これまで name_prefix
は最大 37 文字までしか入力できない制限がありました。
これが 6.0.0 から 54 文字まで拡大されました。
非互換動作を防ぐため、 name_prefix
が 37 文字以下の場合はこれまでと同じネーミング規則が適用され、 37 文字より大きく 54 文字以下の場合に新しいネーミング規則が適用されます。
この変更は以下のリソースが対象です。
google_compute_instance_template
google_compute_region_instance_template
google_compute_ssl_certificate
google_compute_region_ssl_certificate
削除防止フィールドの追加
以下のリソースに削除防止フィールドが追加されました。
これによって Terraform の記述ミス等による誤削除を防ぐことができます。
google_cloud_run_v2_job
google_cloud_run_v2_service
-
google_active_directory_domain
※ アップグレードガイドではgoogle_domain
と記載されていますが、リリースノートや該当する PR を見る限りはこちらが正しいと思います。 google_folder
google_project
-
google_redis_cluster
※アップグレードガイドには記載されていませんが、こちらも削除防止フィールドが追加されています。
なお、 google_project
は、 deletion_policy
フィールドで削除動作を制御しますが、他のリソースとは異なり bool 値ではなく文字列で設定します。
-
deletion_policy = "PREVENT"
でリソース削除動作を防止します。 (terraform apply
時にエラーが発生します。) -
deletion_policy = "ABANDON"
でterraform apply
時のエラーは発生しませんが、プロジェクトは削除せず State のみ削除します。 -
deletion_policy = "DELETE"
でterraform apply
時にプロジェクトを削除します。
デフォルトは deletion_policy = "PREVENT"
です。
変更点・非互換
広範に変更された非互換について説明します。
ブロック要素の厳格化
バージョン 5.x までは特定のリソースにおいて、過去の設定との互換性のためブロック要素に = []
と設定することを許容していました。(参考)
バージョン 6.0.0 より、以下のリソースについては = []
を設定できなくなりました。
もしこうした設定が残っている場合は、修正が必要です。
google_compute_instance
-
guest_accelerator
フィールド
google_compute_subnetwork
-
secondary_ip_ranges
フィールド
google_composer_environment
-
ip_allocation_policy
フィールド
google_container_cluster
-
guest_accelerator
フィールド -
guest_accelerator.gpu_driver_installation_config
フィールド -
guest_accelerator.gpu_sharing_config
フィールド
google_container_node_pool
-
guest_accelerator
フィールド -
guest_accelerator.gpu_driver_installation_config
フィールド -
guest_accelerator.gpu_sharing_config
フィールド
google_compute_instance_from_template
-
network_interface.alias_ip_range
フィールド -
network_interface.access_config
フィールド -
attached_disk
フィールド -
guest_accelerator
フィールド -
service_account
フィールド -
scratch_disk
フィールド
google_compute_instance_from_machine_image
-
network_interface.alias_ip_range
フィールド -
network_interface.access_config
フィールド -
attached_disk
フィールド -
guest_accelerator
フィールド -
service_account
フィールド -
scratch_disk
フィールド
リソース毎の変更点
以下はリソース毎の変更点や非互換について紹介します。
google_alloy_db_cluster
-
network
フィールドが削除されました。代わりにnetwork_config.network
使用します。
google_bigquery_table
- View を含むテーブルを作成する際に、スキーマを指定し、かつ、そのスキーマに REQUIRED モードのフィールドが含まれている場合、プロバイダがエラーを出すようになりました。
-
allow_resource_tags_on_deletion
フィールドを削除しました。以降は Resource Tag を含むテーブルでも削除可能です。
google_bigquery_reservation
-
multi_region_auxiliary
フィールドを削除しました。
google_billing_project_info
- id フィールドの形式を変更しました。 (
projects/{{project}}/billingInfo
からprojects/{{project}}
)
google_cloud_run_v2_service
-
liveness_probe
で API のデフォルト値を推論しなくなりました。 -
containers.env
は内部データ構造を ARRAY から SET に変更されました。記述順序によらず設定が保持されます。
google_cloud_run_v2_job
-
containers.env
は内部データ構造を ARRAY から SET に変更されました。記述順序によらず設定が保持されます。
google_compute_backend_service, google_compute_region_backend_service
-
iap
フィールドにenable
が追加され、必須属性になりました。 -
connection_draining_timeout_sec
,balancing_mode
,outlier_detection
のデフォルト値が変更されました。-
balancing_mode
がUTILIZATION
に統一され、その値に従う形でいくつかのフィールドのデフォルト値も変更されました。
-
google_compute_managed_ssl_certificate
-
certifcate_id
(Output only)が正しい動作に修正されました。
google_compute_network_endpoints
- id フィールドの形式を変更しました。 (
{{project}}/{{zone}}/{{network_endpoint_group}}/endpoints
から"{{project}}/{{zone}}/{{network_endpoint_group}}
)
google_container_cluster
-
advanced_datapath_observability_config.enable_relay
が必須属性になりました。 -
advanced_datapath_observability_config.relay_mode
が削除されました。代わりにadvanced_datapath_observability_config.enable_relay
を使用します。 -
resource_labels
は non-authoritative な動作に変更され、他のリソースと同様にterraform_labels
とeffective_labels
により設定済みラベルとマージされて反映されます。- ※この動作は Data Resouce の同名リソースでも同様です。
google_datastore_index
-
google_datastore_index
リソースは削除されました。代わりにgoogle_firestore_index
リソースを使用してください。
google_edgenetwork_network, google_edgenetwork_subnet
-
labels
は non-authoritative な動作に変更され、他のリソースと同様にterraform_labels
とeffective_labels
により設定済みラベルとマージされて反映されます。
google_identity_platform_project_default_config
-
google_identity_platform_project_default_config
リソースは削除されました。代わりにgoogle_identity_platform_project_config
リソースを使用してください。
google_pubsub_topic
-
schema_settings
はデフォルト値を推論しなくなりました。スキーマが不要な場合はブロックを削除してください。
google_integrations_client
-
create_sample_workflows
とprovision_gmek
フィールドは削除されました。
google_storage_bucket
-
lifecycle_rule.condition
フィールドにおけるno_age
フィールドは削除されました。
以前は、age = 0
が暗黙のデフォルト値だったため、 デフォルト値の設定を回避する場合にno_age = true
を設定する必要がありました。
バージョン 6.0.0 からはno_age = true
を設定している場合は、代わりにsend_age_if_zero = false
を設定します。また、暗黙のデフォルト値age = 0
を前提にする場合はsend_age_if_zero = true
を設定します。
google_vpc_access_connector
-
max_throughput
とmin_throughput
フィールドにおけるプロバイダ固定のデフォルト値が削除されました。未設定の場合、API が自動設定したデフォルト値を使用します。
※リリースノートではmin_throughput
とmin_instances
フィールドと記載されていますが、ソース差分を見る限りは前述のフィールドが正しいと思います。 -
max_instances
とmax_throughput
フィールドを同時設定するとコンフリクトを検出するように修正されました。同様に、min_instances
とmin_throughput
フィールドも同時設定時にコンフリクトを検出します。
google_workstations_workstation_config
-
host.gce_instance.disable_ssh
フィールドのデフォルト値は True に変更されました。
google_compute_subnetwork
-
reserved_internal_range
とsecondary_ip_ranges[].reserved_internal_range
フィールドが追加されました。
google_sql_database_instance (バージョン 6.0.1)
-
settings.ip_configuration.require_ssl
フィールドは削除されました。代わりにsettings.ip_configuration.ssl_mode
を使用します。
google_vpc_access_connector の非互換の補足
google_vpc_access_connector
リソースの非互換についてはアップグレードガイドで詳しく触れられていないため補足します。
バージョン 5.x 以前において google_vpc_access_connector
リソースを作成する場合、 max_instances と min_instances を設定するときに合わせて max_throughput と min_throughput もあわせて設定が必要でした。
例えば以下のような設定があったとします。
VPC Access コネクタで、最大インスタンス数 5、最小インスタンス数 3 で設定するケースです。
resource "google_compute_subnetwork" "test" {
name = "vpc-access-test"
region = "asia-northeast1"
network = google_compute_network.main.self_link
ip_cidr_range = "10.100.10.0/28"
}
resource "google_vpc_access_connector" "test" {
name = "tf-600-test"
region = google_compute_subnetwork.test.region
subnet {
name = google_compute_subnetwork.test.name
}
machine_type = "e2-micro"
max_instances = 5
min_instances = 3
}
一見正しそうに見えます。実際、この設定の terraform apply
は成功します。
しかし、直後の terraform plan
では以下のような差分を検出し、 force replacement となってしまいます。
# google_vpc_access_connector.test must be replaced
-/+ resource "google_vpc_access_connector" "test" {
~ connected_projects = [] -> (known after apply)
~ id = "projects/example-project/locations/asia-northeast1/connectors/tf-600-test" -> (known after apply)
~ max_throughput = 500 -> 300 # forces replacement
~ min_throughput = 300 -> 200 # forces replacement
name = "tf-600-test"
~ network = "tf-600-test" -> (known after apply)
~ self_link = "projects/example-project/locations/asia-northeast1/connectors/tf-600-test" -> (known after apply)
~ state = "READY" -> (known after apply)
# (6 unchanged attributes hidden)
~ subnet {
name = "vpc-access-test"
~ project_id = "example-project" -> (known after apply)
}
}
これは何故発生するかというと、 Terraform Google Provider で max_throughput と min_throughput の暗黙のデフォルト値が設定されているためです。
max_throughput と min_throughput が未設定の場合は max_throughput = 300
、min_throughput = 200
が設定されます。
そのため、こういった差分を抑制するため、 max_instances と min_instances の値から max_throughput と min_throughput を手計算して明示的に設定するか、 lifecycle.ignore_changes に変更を無視するフィールドにするか、どちらかの設定が必要でした。
例えば、以下のような設定です。
resource "google_compute_subnetwork" "test" {
name = "vpc-access-test"
region = var.region
network = google_compute_network.main.self_link
ip_cidr_range = "10.100.10.0/28"
}
resource "google_vpc_access_connector" "test" {
name = "tf-600-test"
region = google_compute_subnetwork.test.region
subnet {
name = google_compute_subnetwork.test.name
}
machine_type = "e2-micro"
max_instances = 5
min_instances = 3
max_throughput = 500 # 本質的には不要な設定
min_throughput = 300 # 本質的には不要な設定
}
バージョン 6.0.0 からはこうした設定は不要になり、max_throughput と max_instances、 min_instances と min_throughput 同時に設定すると以下のようにエラー停止します。
terraform plan エラーメッセージ
╷
│ Error: Conflicting configuration arguments
│
│ with google_vpc_access_connector.test,
│ on vpc_access_connector.tf line 16, in resource "google_vpc_access_connector" "test":
│ 16: max_instances = 5
│
│ "max_instances": conflicts with max_throughput
╵
╷
│ Error: Conflicting configuration arguments
│
│ with google_vpc_access_connector.test,
│ on vpc_access_connector.tf line 17, in resource "google_vpc_access_connector" "test":
│ 17: min_instances = 3
│
│ "min_instances": conflicts with min_throughput
╵
╷
│ Error: Conflicting configuration arguments
│
│ with google_vpc_access_connector.test,
│ on vpc_access_connector.tf line 18, in resource "google_vpc_access_connector" "test":
│ 18: max_throughput = 500
│
│ "max_throughput": conflicts with max_instances
╵
╷
│ Error: Conflicting configuration arguments
│
│ with google_vpc_access_connector.test,
│ on vpc_access_connector.tf line 19, in resource "google_vpc_access_connector" "test":
│ 19: min_throughput = 300
│
│ "min_throughput": conflicts with min_instances
╵
バージョン 6.0.0 からは、基本的には max_instances と min_instances のみで設定すれば問題ありません。
lifecycle.ignore_changes で無視している場合は特に問題ありませんが、フィールドを同時設定することで対応している場合は修正が必要です。
ちなみに、この google_vpc_access_connector
の動作は以前報告した Issue の修正で、改善されてよかったと思います。
まとめ
Terraform バージョン 6.0.0 (含む 6.0.1) の新機能と変更点について紹介しました。
プロバイダデフォルトラベルは、Terraform で作成したリソースを区別しやすくなり、Terraform 管理外リソースを見つけやすくなったのではないかと思います。
他にも細やかな改善が行われているので、アップグレードを計画していくとよいかと思います。
この記事が皆様の Google Provider アップグレード作業の一助になれば幸いです。
Discussion