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_templategoogle_compute_region_instance_templategoogle_compute_ssl_certificategoogle_compute_region_ssl_certificate
削除防止フィールドの追加
以下のリソースに削除防止フィールドが追加されました。
これによって Terraform の記述ミス等による誤削除を防ぐことができます。
google_cloud_run_v2_jobgoogle_cloud_run_v2_service-
google_active_directory_domain
※ アップグレードガイドではgoogle_domainと記載されていますが、リリースノートや該当する PR を見る限りはこちらが正しいと思います。 google_foldergoogle_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