Compute VM module refactor (#3805)
* add ad for compute-vm refactor * Exclue nic_type from validated fields, add split of main.tf and template.tf * boot disk * fix examples and fixtures * attached disks * fix further examples and module-level tests * remove extra file * fix mig examples * finish refactoring variables * align fast and other modules * refactor(compute-vm): align examples and ADR with the newly implemented interface This commit addresses the remaining references of the `instance_type` and `confidential_compute` parameters in the testing environment and updates the ADR. * feat(compute-vm): add network_performance_config to instance and templates This change implements the usage of the `network_performance_tier` variable we added earlier into the actual Terraform resources. --------- Co-authored-by: Wiktor Niesiobędzki <wiktorn@google.com>
This commit is contained in:
committed by
GitHub
parent
2c39df6453
commit
a4eb4d24fd
@@ -151,12 +151,12 @@ module "vm-managed-sa-example2" {
|
||||
|
||||
#### Disk sources
|
||||
|
||||
Attached disks can be created and optionally initialized from a pre-existing source, or attached to VMs when pre-existing. The `source` and `source_type` attributes of the `attached_disks` variable allows several modes of operation:
|
||||
Attached disks can be created and optionally initialized from a pre-existing source, or attached to VMs when pre-existing. The `source` attribute of the `attached_disks` variable allows several modes of operation:
|
||||
|
||||
- `source_type = "image"` can be used with zonal disks in instances and templates, set `source` to the image name or self link
|
||||
- `source_type = "snapshot"` can be used with instances only, set `source` to the snapshot name or self link
|
||||
- `source_type = "attach"` can be used for both instances and templates to attach an existing disk, set source to the name (for zonal disks) or self link (for regional disks) of the existing disk to attach; no disk will be created
|
||||
- `source_type = null` can be used where an empty disk is needed, `source` becomes irrelevant and can be left null
|
||||
- `source.image` can be used with zonal disks in instances and templates, set to the image name or self link
|
||||
- `source.snapshot` can be used with instances only, set to the snapshot name or self link
|
||||
- `source.attach` can be used for both instances and templates to attach an existing disk, set to the name (for zonal disks) or self link (for regional disks) of the existing disk to attach; no disk will be created
|
||||
- `source = null` can be used where an empty disk is needed
|
||||
|
||||
This is an example of attaching a pre-existing regional PD to a new instance:
|
||||
|
||||
@@ -170,15 +170,16 @@ module "vm-disks-example" {
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
attached_disks = [{
|
||||
name = "repd-1"
|
||||
size = 10
|
||||
source_type = "attach"
|
||||
source = "regions/${var.region}/disks/repd-test-1"
|
||||
options = {
|
||||
replica_zone = "${var.region}-c"
|
||||
attached_disks = {
|
||||
repd-1 = {
|
||||
initialize_params = {
|
||||
replica_zone = "${var.region}-c"
|
||||
}
|
||||
source = {
|
||||
attach = "regions/${var.region}/disks/repd-test-1"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -198,15 +199,17 @@ module "vm-disks-example" {
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
attached_disks = [{
|
||||
name = "repd"
|
||||
size = 10
|
||||
source_type = "attach"
|
||||
source = "https://www.googleapis.com/compute/v1/projects/${var.project_id}/regions/${var.region}/disks/repd-test-1"
|
||||
options = {
|
||||
replica_zone = "${var.region}-c"
|
||||
attached_disks = {
|
||||
repd = {
|
||||
auto_delete = false
|
||||
initialize_params = {
|
||||
replica_zone = "${var.region}-c"
|
||||
}
|
||||
source = {
|
||||
attach = "https://www.googleapis.com/compute/v1/projects/${var.project_id}/regions/${var.region}/disks/repd-test-1"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -217,7 +220,7 @@ module "vm-disks-example" {
|
||||
|
||||
#### Disk types and options
|
||||
|
||||
The `attached_disks` variable exposes an `option` attribute that can be used to fine tune the configuration of each disk. The following example shows a VM with multiple disks
|
||||
The `attached_disks` variable exposes an `initialize_params` attribute that can be used to fine tune the configuration of each disk. The following example shows a VM with multiple disks
|
||||
|
||||
```hcl
|
||||
module "vm-disk-options-example" {
|
||||
@@ -229,27 +232,26 @@ module "vm-disk-options-example" {
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
attached_disks = [
|
||||
{
|
||||
name = "data1"
|
||||
size = "10"
|
||||
source_type = "image"
|
||||
source = "image-1"
|
||||
options = {
|
||||
attached_disks = {
|
||||
data1 = {
|
||||
initialize_params = {
|
||||
replica_zone = "${var.region}-c"
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "data2"
|
||||
size = "20"
|
||||
source_type = "snapshot"
|
||||
source = "snapshot-2"
|
||||
options = {
|
||||
type = "pd-ssd"
|
||||
mode = "READ_ONLY"
|
||||
source = {
|
||||
image = "image-1"
|
||||
}
|
||||
}
|
||||
]
|
||||
data2 = {
|
||||
mode = "READ_ONLY"
|
||||
initialize_params = {
|
||||
size = 20
|
||||
type = "pd-ssd"
|
||||
}
|
||||
source = {
|
||||
snapshot = "snapshot-2"
|
||||
}
|
||||
}
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -261,47 +263,51 @@ For hyperdisks there are additional options available to configure performance.
|
||||
|
||||
```hcl
|
||||
module "vm-disk-options-example" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "test"
|
||||
instance_type = "n4-standard-2"
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "test"
|
||||
machine_type = "n4-standard-2"
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
type = "hyperdisk-balanced"
|
||||
}
|
||||
}
|
||||
|
||||
attached_disks = [
|
||||
{
|
||||
name = "data1"
|
||||
size = "10"
|
||||
options = {
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
type = "hyperdisk-balanced"
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "data2"
|
||||
size = "10"
|
||||
source_type = "image"
|
||||
source = "projects/debian-cloud/global/images/family/debian-12"
|
||||
options = {
|
||||
provisioned_iops = 5000
|
||||
provisioned_throughput = 500
|
||||
type = "hyperdisk-balanced"
|
||||
}
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
}
|
||||
}
|
||||
attached_disks = {
|
||||
data1 = {
|
||||
initialize_params = {
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
data2 = {
|
||||
mode = "READ_ONLY"
|
||||
initialize_params = {
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 5000
|
||||
provisioned_throughput = 500
|
||||
}
|
||||
}
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
}
|
||||
}
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -316,24 +322,22 @@ You can use storage pool for better management of storage capacity.
|
||||
```hcl
|
||||
# hyperdisk - with storage pool
|
||||
resource "google_compute_storage_pool" "default" {
|
||||
project = var.project_id
|
||||
name = "storage-pool-basic"
|
||||
|
||||
project = var.project_id
|
||||
name = "storage-pool-basic"
|
||||
pool_provisioned_capacity_gb = "20480"
|
||||
pool_provisioned_iops = "10000"
|
||||
pool_provisioned_throughput = 1024
|
||||
storage_pool_type = "hyperdisk-balanced"
|
||||
zone = "${var.region}-c"
|
||||
|
||||
deletion_protection = false
|
||||
deletion_protection = false
|
||||
}
|
||||
|
||||
module "vm-disk-options-example" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-c"
|
||||
name = "test"
|
||||
instance_type = "c4d-standard-2"
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-c"
|
||||
name = "test"
|
||||
machine_type = "c4d-standard-2"
|
||||
network_interfaces = [
|
||||
{
|
||||
network = var.vpc.self_link
|
||||
@@ -341,40 +345,41 @@ module "vm-disk-options-example" {
|
||||
}
|
||||
]
|
||||
boot_disk = {
|
||||
use_independent_disk = true
|
||||
use_independent_disk = {}
|
||||
initialize_params = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
storage_pool = google_compute_storage_pool.default.id
|
||||
type = "hyperdisk-balanced"
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
storage_pool = google_compute_storage_pool.default.id
|
||||
}
|
||||
}
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
}
|
||||
}
|
||||
|
||||
attached_disks = [
|
||||
{
|
||||
name = "data1"
|
||||
size = "10"
|
||||
options = {
|
||||
# provisioned_iops = 3000
|
||||
# provisioned_throughput = 140
|
||||
storage_pool = google_compute_storage_pool.default.id
|
||||
type = "hyperdisk-balanced"
|
||||
attached_disks = {
|
||||
data1 = {
|
||||
initialize_params = {
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
storage_pool = google_compute_storage_pool.default.id
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "data2"
|
||||
size = "10"
|
||||
source_type = "image"
|
||||
source = "projects/debian-cloud/global/images/family/debian-12"
|
||||
options = {
|
||||
provisioned_iops = 5000
|
||||
provisioned_throughput = 500
|
||||
type = "hyperdisk-balanced"
|
||||
}
|
||||
data2 = {
|
||||
initialize_params = {
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 5000
|
||||
provisioned_throughput = 500
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
}
|
||||
}
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -390,50 +395,51 @@ For hyperdisks there are additional options available to configure performance.
|
||||
|
||||
```hcl
|
||||
module "vm-arm" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-c"
|
||||
name = "test"
|
||||
instance_type = "c4a-standard-1"
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-c"
|
||||
name = "test"
|
||||
machine_type = "c4a-standard-1"
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
architecture = "ARM64"
|
||||
initialize_params = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12-arm64"
|
||||
architecture = "ARM64"
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
type = "hyperdisk-balanced"
|
||||
}
|
||||
}
|
||||
|
||||
attached_disks = [
|
||||
{
|
||||
name = "data1"
|
||||
size = "10"
|
||||
options = {
|
||||
architecture = "ARM64"
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
type = "hyperdisk-balanced"
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "data2"
|
||||
size = "10"
|
||||
source_type = "image"
|
||||
source = "projects/debian-cloud/global/images/family/debian-12-arm64"
|
||||
options = {
|
||||
architecture = "ARM64"
|
||||
provisioned_iops = 5000
|
||||
provisioned_throughput = 500
|
||||
type = "hyperdisk-balanced"
|
||||
}
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12-arm64"
|
||||
}
|
||||
}
|
||||
attached_disks = {
|
||||
data1 = {
|
||||
initialize_params = {
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 3000
|
||||
provisioned_throughput = 140
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
data2 = {
|
||||
initialize_params = {
|
||||
type = "hyperdisk-balanced"
|
||||
hyperdisk = {
|
||||
provisioned_iops = 5000
|
||||
provisioned_throughput = 500
|
||||
}
|
||||
}
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12-arm64"
|
||||
}
|
||||
}
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -445,7 +451,7 @@ module "vm-arm" {
|
||||
|
||||
#### Boot disk as an independent resource
|
||||
|
||||
To create the boot disk as an independent resources instead of as part of the instance creation flow, set `boot_disk.use_independent_disk` to `true` and optionally configure `boot_disk.initialize_params`.
|
||||
To create the boot disk as an independent resources instead of as part of the instance creation flow, set `boot_disk.use_independent_disk` to a non-null object (e.g. `{}`) and optionally configure `boot_disk.initialize_params`.
|
||||
|
||||
This will create the boot disk as its own resource and attach it to the instance, allowing to recreate the instance from Terraform while preserving the boot disk.
|
||||
|
||||
@@ -456,8 +462,7 @@ module "simple-vm-example" {
|
||||
zone = "${var.region}-b"
|
||||
name = "test"
|
||||
boot_disk = {
|
||||
initialize_params = {}
|
||||
use_independent_disk = true
|
||||
use_independent_disk = {}
|
||||
}
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
@@ -536,7 +541,6 @@ resource "google_compute_image" "cos-gvnic" {
|
||||
project = var.project_id
|
||||
name = "my-image"
|
||||
source_image = "https://www.googleapis.com/compute/v1/projects/cos-cloud/global/images/cos-89-16108-534-18"
|
||||
|
||||
guest_os_features {
|
||||
type = "GVNIC"
|
||||
}
|
||||
@@ -558,8 +562,10 @@ module "vm-with-gvnic" {
|
||||
name = "test"
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
type = "pd-ssd"
|
||||
}
|
||||
source = {
|
||||
image = google_compute_image.cos-gvnic.self_link
|
||||
type = "pd-ssd"
|
||||
}
|
||||
}
|
||||
network_interfaces = [{
|
||||
@@ -674,8 +680,8 @@ module "spot-vm-example" {
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "test"
|
||||
options = {
|
||||
spot = true
|
||||
scheduling_config = {
|
||||
provisioning_model = "SPOT"
|
||||
termination_action = "STOP"
|
||||
}
|
||||
network_interfaces = [{
|
||||
@@ -696,10 +702,10 @@ module "vm-confidential-example" {
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "confidential-vm"
|
||||
confidential_compute = true
|
||||
instance_type = "n2d-standard-2"
|
||||
confidential_compute = "SEV"
|
||||
machine_type = "n2d-standard-2"
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
}
|
||||
}
|
||||
@@ -714,11 +720,11 @@ module "template-confidential-example" {
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "confidential-template"
|
||||
confidential_compute = true
|
||||
confidential_compute = "SEV"
|
||||
create_template = {}
|
||||
instance_type = "n2d-standard-2"
|
||||
machine_type = "n2d-standard-2"
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-12"
|
||||
}
|
||||
}
|
||||
@@ -790,10 +796,9 @@ module "kms-vm-example" {
|
||||
network = module.vpc.self_link
|
||||
subnetwork = module.vpc.subnet_self_links["${var.region}/production"]
|
||||
}]
|
||||
attached_disks = [{
|
||||
name = "attached-disk"
|
||||
size = 10
|
||||
}]
|
||||
attached_disks = {
|
||||
attached-disk = {}
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -819,10 +824,9 @@ module "autokey-vm-example" {
|
||||
network = "projects/myhost/global/networks/dev-spoke-0"
|
||||
subnetwork = "projects/myhost/regions/europe-west8/subnetworks/gce"
|
||||
}]
|
||||
attached_disks = [{
|
||||
name = "attached-disk"
|
||||
size = 10
|
||||
}]
|
||||
attached_disks = {
|
||||
attached-disk = {}
|
||||
}
|
||||
service_account = {
|
||||
auto_create = true
|
||||
}
|
||||
@@ -839,7 +843,7 @@ module "autokey-vm-example" {
|
||||
|
||||
### Advanced machine features
|
||||
|
||||
Advanced machine features can be configured via the `options.advanced_machine_features` variable.
|
||||
Advanced machine features can be configured via the `machine_features_config` variable.
|
||||
|
||||
```hcl
|
||||
module "simple-vm-example" {
|
||||
@@ -851,12 +855,10 @@ module "simple-vm-example" {
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
options = {
|
||||
advanced_machine_features = {
|
||||
enable_nested_virtualization = true
|
||||
enable_turbo_mode = true
|
||||
threads_per_core = 2
|
||||
}
|
||||
machine_features_config = {
|
||||
enable_nested_virtualization = true
|
||||
enable_turbo_mode = true
|
||||
threads_per_core = 2
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1
|
||||
@@ -879,13 +881,13 @@ module "cos-test" {
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
}
|
||||
attached_disks = [
|
||||
{ size = 10 }
|
||||
]
|
||||
attached_disks = {
|
||||
disk-0 = {}
|
||||
}
|
||||
service_account = {
|
||||
email = module.iam-service-account.email
|
||||
}
|
||||
@@ -909,13 +911,15 @@ module "cos-test" {
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
}
|
||||
attached_disks = [
|
||||
{ size = 10 }
|
||||
]
|
||||
attached_disks = {
|
||||
disk-0 = {
|
||||
auto_delete = true
|
||||
}
|
||||
}
|
||||
service_account = {
|
||||
email = module.iam-service-account.email
|
||||
}
|
||||
@@ -945,7 +949,7 @@ module "instance-group" {
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
}
|
||||
@@ -976,7 +980,7 @@ module "instance" {
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
}
|
||||
@@ -1019,7 +1023,7 @@ module "instance" {
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
}
|
||||
@@ -1047,21 +1051,19 @@ module "instance" {
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
source = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
snapshot_schedule = ["boot"]
|
||||
}
|
||||
attached_disks = [
|
||||
{
|
||||
name = "disk-1"
|
||||
size = 10
|
||||
options = {
|
||||
attached_disks = {
|
||||
disk-1 = {
|
||||
initialize_params = {
|
||||
replica_zone = "${var.region}-c"
|
||||
}
|
||||
snapshot_schedule = ["data"]
|
||||
}
|
||||
]
|
||||
}
|
||||
snapshot_schedules = {
|
||||
boot = {
|
||||
schedule = {
|
||||
@@ -1141,16 +1143,16 @@ You can add node affinities (and anti-affinity) configurations to allocate the V
|
||||
|
||||
```hcl
|
||||
module "sole-tenancy" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-b"
|
||||
instance_type = "n1-standard-1"
|
||||
name = "test"
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = var.project_id
|
||||
zone = "${var.region}-b"
|
||||
machine_type = "n1-standard-1"
|
||||
name = "test"
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
options = {
|
||||
scheduling_config = {
|
||||
node_affinities = {
|
||||
workload = {
|
||||
values = ["frontend"]
|
||||
@@ -1169,43 +1171,45 @@ module "sole-tenancy" {
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [name](variables.tf#L323) | Instance name. | <code>string</code> | ✓ | |
|
||||
| [network_interfaces](variables.tf#L335) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | <code title="list(object({ network = string subnetwork = string alias_ips = optional(map(string), {}) nat = optional(bool, false) nic_type = optional(string) stack_type = optional(string) addresses = optional(object({ internal = optional(string) external = optional(string) }), null) network_tier = optional(string) }))">list(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L430) | Project id. | <code>string</code> | ✓ | |
|
||||
| [zone](variables.tf#L550) | Compute zone. | <code>string</code> | ✓ | |
|
||||
| [attached_disk_defaults](variables.tf#L17) | Defaults for attached disks options. | <code title="object({ auto_delete = optional(bool, false) mode = string replica_zone = string type = string })">object({…})</code> | | <code title="{ auto_delete = true mode = "READ_WRITE" replica_zone = null type = "pd-balanced" }">{…}</code> |
|
||||
| [attached_disks](variables.tf#L37) | Additional disks, if options is null defaults will be used in its place. Source type is one of 'image' (zonal disks in vms and template), 'snapshot' (vm), 'existing', and null. | <code title="list(object({ name = optional(string) device_name = optional(string) size = string snapshot_schedule = optional(list(string)) source = optional(string) source_type = optional(string) options = optional( object({ architecture = optional(string) auto_delete = optional(bool, false) # applies only to vm templates mode = optional(string, "READ_WRITE") provisioned_iops = optional(number) provisioned_throughput = optional(number) # in MiB/s replica_zone = optional(string) storage_pool = optional(string) type = optional(string, "pd-balanced") }), { auto_delete = true mode = "READ_WRITE" replica_zone = null type = "pd-balanced" } ) }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [boot_disk](variables.tf#L92) | Boot disk properties. Initialize params are ignored when source is set. | <code title="object({ name = optional(string) auto_delete = optional(bool, true) snapshot_schedule = optional(list(string)) source = optional(string) initialize_params = optional(object({ architecture = optional(string) image = optional(string, "projects/debian-cloud/global/images/family/debian-11") provisioned_iops = optional(number) provisioned_throughput = optional(number) # in MiB/s size = optional(number, 10) storage_pool = optional(string) type = optional(string, "pd-balanced") }), {}) use_independent_disk = optional(bool, false) })">object({…})</code> | | <code title="{ initialize_params = {} }">{…}</code> |
|
||||
| [can_ip_forward](variables.tf#L135) | Enable IP forwarding. | <code>bool</code> | | <code>false</code> |
|
||||
| [confidential_compute](variables.tf#L141) | Enable Confidential Compute for these instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [context](variables.tf#L147) | Context-specific interpolations. | <code title="object({ addresses = optional(map(string), {}) custom_roles = optional(map(string), {}) kms_keys = optional(map(string), {}) iam_principals = optional(map(string), {}) locations = optional(map(string), {}) networks = optional(map(string), {}) project_ids = optional(map(string), {}) subnets = optional(map(string), {}) tag_values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [create_template](variables.tf#L164) | Create instance template instead of instances. Defaults to a global template. | <code title="object({ regional = optional(bool, false) })">object({…})</code> | | <code>null</code> |
|
||||
| [description](variables.tf#L173) | Description of a Compute Instance. | <code>string</code> | | <code>"Managed by the compute-vm Terraform module."</code> |
|
||||
| [enable_display](variables.tf#L179) | Enable virtual display on the instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [encryption](variables.tf#L185) | Encryption options. Only one of kms_key_self_link and disk_encryption_key_raw may be set. If needed, you can specify to encrypt or not the boot disk. | <code title="object({ encrypt_boot = optional(bool, false) disk_encryption_key_raw = optional(string) kms_key_self_link = optional(string) })">object({…})</code> | | <code>null</code> |
|
||||
| [gpu](variables.tf#L195) | GPU information. Based on https://cloud.google.com/compute/docs/gpus. | <code title="object({ count = number type = string })">object({…})</code> | | <code>null</code> |
|
||||
| [group](variables.tf#L230) | Define this variable to create an instance group for instances. Disabled for template use. | <code title="object({ named_ports = map(number) })">object({…})</code> | | <code>null</code> |
|
||||
| [hostname](variables.tf#L238) | Instance FQDN name. | <code>string</code> | | <code>null</code> |
|
||||
| [iam](variables.tf#L244) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [instance_schedule](variables.tf#L250) | Assign or create and assign an instance schedule policy. Either resource policy id or create_config must be specified if not null. Set active to null to dtach a policy from vm before destroying. | <code title="object({ active = optional(bool, true) description = optional(string) expiration_time = optional(string) start_time = optional(string) timezone = optional(string, "UTC") vm_start = optional(string) vm_stop = optional(string) })">object({…})</code> | | <code>null</code> |
|
||||
| [instance_type](variables.tf#L274) | Instance type. | <code>string</code> | | <code>"e2-micro"</code> |
|
||||
| [kms_autokeys](variables.tf#L280) | KMS Autokey key handles. If location is not specified it will be inferred from the zone. Key handle names will be added to the kms_keys context with an `autokeys/` prefix. | <code title="map(object({ location = optional(string) resource_type_selector = optional(string, "compute.googleapis.com/Disk") }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L298) | Instance labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [metadata](variables.tf#L304) | Instance metadata. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [metadata_startup_script](variables.tf#L310) | Instance startup script. Will trigger recreation on change, even after importing. | <code>string</code> | | <code>null</code> |
|
||||
| [min_cpu_platform](variables.tf#L317) | Minimum CPU platform. | <code>string</code> | | <code>null</code> |
|
||||
| [network_attached_interfaces](variables.tf#L328) | Network interfaces using network attachments. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [network_tag_bindings](variables.tf#L356) | Resource manager tag bindings in arbitrary key => tag key or value id format. Set on both the instance only for networking purposes, and modifiable without impacting the main resource lifecycle. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [options](variables.tf#L363) | Instance options. | <code title="object({ advanced_machine_features = optional(object({ enable_nested_virtualization = optional(bool) enable_turbo_mode = optional(bool) enable_uefi_networking = optional(bool) performance_monitoring_unit = optional(string) threads_per_core = optional(number) visible_core_count = optional(number) })) allow_stopping_for_update = optional(bool, true) deletion_protection = optional(bool, false) key_revocation_action_type = optional(string) graceful_shutdown = optional(object({ enabled = optional(bool, false) max_duration_secs = optional(number) })) max_run_duration = optional(object({ nanos = optional(number) seconds = number })) node_affinities = optional(map(object({ values = list(string) in = optional(bool, true) })), {}) spot = optional(bool, false) termination_action = optional(string) })">object({…})</code> | | <code title="{ allow_stopping_for_update = true deletion_protection = false spot = false termination_action = null key_revocation_action_type = "NONE" }">{…}</code> |
|
||||
| [project_number](variables.tf#L435) | Project number. Used in tag bindings to avoid a permadiff. | <code>string</code> | | <code>null</code> |
|
||||
| [resource_policies](variables.tf#L441) | Resource policies to attach to the instance or template. | <code>list(string)</code> | | <code>null</code> |
|
||||
| [scratch_disks](variables.tf#L448) | Scratch disks configuration. | <code title="object({ count = number interface = string })">object({…})</code> | | <code title="{ count = 0 interface = "NVME" }">{…}</code> |
|
||||
| [service_account](variables.tf#L460) | Service account email and scopes. If email is null, the default Compute service account will be used unless auto_create is true, in which case a service account will be created. Set the variable to null to avoid attaching a service account. | <code title="object({ auto_create = optional(bool, false) email = optional(string) scopes = optional(list(string)) })">object({…})</code> | | <code>{}</code> |
|
||||
| [shielded_config](variables.tf#L470) | Shielded VM configuration of the instances. | <code title="object({ enable_secure_boot = optional(bool, true) enable_vtpm = optional(bool, true) enable_integrity_monitoring = optional(bool, true) })">object({…})</code> | | <code>null</code> |
|
||||
| [snapshot_schedules](variables.tf#L480) | Snapshot schedule resource policies that can be attached to disks. | <code title="map(object({ schedule = object({ daily = optional(object({ days_in_cycle = number start_time = string })) hourly = optional(object({ hours_in_cycle = number start_time = string })) weekly = optional(list(object({ day = string start_time = string }))) }) description = optional(string) retention_policy = optional(object({ max_retention_days = number on_source_disk_delete_keep = optional(bool) })) snapshot_properties = optional(object({ chain_name = optional(string) guest_flush = optional(bool) labels = optional(map(string)) storage_locations = optional(list(string)) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L523) | Resource manager tag bindings in arbitrary key => tag key or value id format. Set on both the instance and zonal disks, and modifiable without impacting the main resource lifecycle. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [tag_bindings_immutable](variables.tf#L530) | Immutable resource manager tag bindings, in tagKeys/id => tagValues/id format. These are set on the instance or instance template at creation time, and trigger recreation if changed. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tags](variables.tf#L544) | Instance network tags for firewall rule targets. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [name](variables.tf#L353) | Instance name. | <code>string</code> | ✓ | |
|
||||
| [network_interfaces](variables.tf#L365) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | <code title="list(object({ network = string subnetwork = string alias_ips = optional(map(string), {}) nat = optional(bool, false) network_tier = optional(string) nic_type = optional(string) stack_type = optional(string) queue_count = optional(number) # NEW internal_ipv6_prefix_length = optional(number) # NEW addresses = optional(object({ internal = optional(string) external = optional(string) }), null) }))">list(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L405) | Project id. | <code>string</code> | ✓ | |
|
||||
| [zone](variables.tf#L562) | Compute zone. | <code>string</code> | ✓ | |
|
||||
| [attached_disks](variables.tf#L17) | Additional disks. Source type is one of 'image' (zonal disks in vms and template), 'snapshot' (vm), 'existing', and null. | <code title="map(object({ auto_delete = optional(bool, true) # applies only to vm templates device_name = optional(string) force_attach = optional(bool) mode = optional(string, "READ_WRITE") name = optional(string) initialize_params = optional(object({ replica_zone = optional(string) size = optional(number, 10) type = optional(string, "pd-balanced") hyperdisk = optional(object({ provisioned_iops = optional(number) provisioned_throughput = optional(number) # in MiB/s storage_pool = optional(string) }), {}) }), {}) snapshot_schedule = optional(list(string)) source = optional(object({ attach = optional(string) image = optional(string) # not supported yet for repd snapshot = optional(string) }), {}) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [boot_disk](variables.tf#L56) | Boot disk properties. | <code title="object({ architecture = optional(string) auto_delete = optional(bool, true) force_attach = optional(bool) snapshot_schedule = optional(list(string)) initialize_params = optional(object({ size = optional(number, 10) type = optional(string, "pd-balanced") hyperdisk = optional(object({ provisioned_iops = optional(number) provisioned_throughput = optional(number) # in MiB/s storage_pool = optional(string) }), {}) }), {}) source = optional(object({ attach = optional(string) disk = optional(string) image = optional(string) snapshot = optional(string) }), { image = "debian-cloud/debian-13" }) use_independent_disk = optional(object({ name = optional(string) })) })">object({…})</code> | | <code>{}</code> |
|
||||
| [can_ip_forward](variables.tf#L113) | Enable IP forwarding. | <code>bool</code> | | <code>false</code> |
|
||||
| [confidential_compute](variables.tf#L119) | Confidential Compute configuration. Set to 'SEV' or 'SEV_SNP' to enable. | <code>string</code> | | <code>null</code> |
|
||||
| [context](variables.tf#L129) | Context-specific interpolations. | <code title="object({ addresses = optional(map(string), {}) custom_roles = optional(map(string), {}) kms_keys = optional(map(string), {}) iam_principals = optional(map(string), {}) locations = optional(map(string), {}) networks = optional(map(string), {}) project_ids = optional(map(string), {}) subnets = optional(map(string), {}) tag_values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [create_template](variables.tf#L146) | Create instance template instead of instances. Defaults to a global template. | <code title="object({ regional = optional(bool, false) })">object({…})</code> | | <code>null</code> |
|
||||
| [description](variables.tf#L155) | Description of a Compute Instance. | <code>string</code> | | <code>"Managed by the compute-vm Terraform module."</code> |
|
||||
| [enable_display](variables.tf#L161) | Enable virtual display on the instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [encryption](variables.tf#L167) | Encryption options. Only one of kms_key_self_link and disk_encryption_key_raw may be set. If needed, you can specify to encrypt or not the boot disk. | <code title="object({ encrypt_boot = optional(bool, false) disk_encryption_key_raw = optional(string) kms_key_self_link = optional(string) })">object({…})</code> | | <code>null</code> |
|
||||
| [gpu](variables.tf#L178) | GPU information. Based on https://cloud.google.com/compute/docs/gpus. | <code title="object({ count = number type = string })">object({…})</code> | | <code>null</code> |
|
||||
| [group](variables.tf#L213) | Instance group configuration. Set 'named_ports' to create a new unmanaged instance group, or provide an existing group self_link/id in 'membership' to join one. | <code title="object({ membership = optional(string) # ID of an existing unmanaged group to join named_ports = optional(map(number), {}) })">object({…})</code> | | <code>null</code> |
|
||||
| [hostname](variables.tf#L222) | Instance FQDN name. | <code>string</code> | | <code>null</code> |
|
||||
| [iam](variables.tf#L228) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [instance_schedule](variables.tf#L234) | Assign or create and assign an instance schedule policy. Set active to null to detach a policy from vm before destroying. | <code title="object({ active = optional(bool, true) description = optional(string) expiration_time = optional(string) start_time = optional(string) timezone = optional(string, "UTC") vm_start = optional(string) vm_stop = optional(string) })">object({…})</code> | | <code>null</code> |
|
||||
| [kms_autokeys](variables.tf#L258) | KMS Autokey key handles. If location is not specified it will be inferred from the zone. Key handle names will be added to the kms_keys context with an `autokeys/` prefix. | <code title="map(object({ location = optional(string) resource_type_selector = optional(string, "compute.googleapis.com/Disk") }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L276) | Instance labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [lifecycle_config](variables.tf#L282) | Instance lifecycle and operational configurations. | <code title="object({ allow_stopping_for_update = optional(bool, true) deletion_protection = optional(bool, false) key_revocation_action_type = optional(string, "NONE") graceful_shutdown = optional(object({ enabled = optional(bool, false) max_duration_secs = optional(number) })) })">object({…})</code> | | <code>{}</code> |
|
||||
| [machine_features_config](variables.tf#L304) | Machine-level configuration. | <code title="object({ enable_nested_virtualization = optional(bool) enable_turbo_mode = optional(bool) enable_uefi_networking = optional(bool) performance_monitoring_unit = optional(string) threads_per_core = optional(number) visible_core_count = optional(number) })">object({…})</code> | | <code>{}</code> |
|
||||
| [machine_type](variables.tf#L328) | Machine type. | <code>string</code> | | <code>"e2-micro"</code> |
|
||||
| [metadata](variables.tf#L334) | Instance metadata. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [metadata_startup_script](variables.tf#L340) | Instance startup script. Will trigger recreation on change, even after importing. | <code>string</code> | | <code>null</code> |
|
||||
| [min_cpu_platform](variables.tf#L347) | Minimum CPU platform. | <code>string</code> | | <code>null</code> |
|
||||
| [network_attached_interfaces](variables.tf#L358) | Network interfaces using network attachments. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [network_performance_tier](variables.tf#L388) | Network performance total egress bandwidth tier. | <code>string</code> | | <code>null</code> |
|
||||
| [network_tag_bindings](variables.tf#L398) | Resource manager tag bindings in arbitrary key => tag key or value id format. Set on both the instance only for networking purposes, and modifiable without impacting the main resource lifecycle. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [project_number](variables.tf#L410) | Project number. Used in tag bindings to avoid a permadiff. | <code>string</code> | | <code>null</code> |
|
||||
| [resource_policies](variables.tf#L416) | Resource policies to attach to the instance or template. | <code>list(string)</code> | | <code>null</code> |
|
||||
| [scheduling_config](variables.tf#L423) | Scheduling configuration for the instance. | <code title="object({ automatic_restart = optional(bool) # Defaults to !spot maintenance_interval = optional(string) # NEW min_node_cpus = optional(number) # NEW on_host_maintenance = optional(string) # Defaults to MIGRATE or TERMINATE based on GPU/Spot provisioning_model = optional(string) # "SPOT" or "STANDARD" termination_action = optional(string) local_ssd_recovery_timeout = optional(object({ # NEW nanos = optional(number) seconds = number })) max_run_duration = optional(object({ nanos = optional(number) seconds = number })) node_affinities = optional(map(object({ values = list(string) in = optional(bool, true) })), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [scratch_disks](variables.tf#L458) | Scratch disks configuration. | <code title="object({ count = number interface = string })">object({…})</code> | | <code title="{ count = 0 interface = "NVME" }">{…}</code> |
|
||||
| [service_account](variables.tf#L471) | Service account email and scopes. If email is null, the default Compute service account will be used unless auto_create is true, in which case a service account will be created. Set the variable to null to avoid attaching a service account. | <code title="object({ auto_create = optional(bool, false) email = optional(string) scopes = optional(list(string)) })">object({…})</code> | | <code>{}</code> |
|
||||
| [shielded_config](variables.tf#L482) | Shielded VM configuration of the instances. | <code title="object({ enable_secure_boot = optional(bool, true) enable_vtpm = optional(bool, true) enable_integrity_monitoring = optional(bool, true) })">object({…})</code> | | <code>null</code> |
|
||||
| [snapshot_schedules](variables.tf#L492) | Snapshot schedule resource policies that can be attached to disks. | <code title="map(object({ schedule = object({ daily = optional(object({ days_in_cycle = number start_time = string })) hourly = optional(object({ hours_in_cycle = number start_time = string })) weekly = optional(list(object({ day = string start_time = string }))) }) description = optional(string) retention_policy = optional(object({ max_retention_days = number on_source_disk_delete_keep = optional(bool) })) snapshot_properties = optional(object({ chain_name = optional(string) guest_flush = optional(bool) labels = optional(map(string)) storage_locations = optional(list(string)) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L535) | Resource manager tag bindings in arbitrary key => tag key or value id format. Set on both the instance and zonal disks, and modifiable without impacting the main resource lifecycle. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [tag_bindings_immutable](variables.tf#L542) | Immutable resource manager tag bindings, in tagKeys/id => tagValues/id format. These are set on the instance or instance template at creation time, and trigger recreation if changed. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tags](variables.tf#L556) | Instance network tags for firewall rule targets. | <code>list(string)</code> | | <code>[]</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
||||
127
modules/compute-vm/disks.tf
Normal file
127
modules/compute-vm/disks.tf
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright 2026 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
locals {
|
||||
attached_disks_regional = {
|
||||
for k, v in var.attached_disks : k => v
|
||||
if v.initialize_params.replica_zone != null
|
||||
}
|
||||
attached_disks_zonal = {
|
||||
for k, v in var.attached_disks : k => v
|
||||
if v.initialize_params.replica_zone == null
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_disk" "boot" {
|
||||
count = (
|
||||
!local.is_template && var.boot_disk.use_independent_disk != null ? 1 : 0
|
||||
)
|
||||
project = local.project_id
|
||||
zone = local.zone
|
||||
# by default, GCP creates boot disks with the same name as the instance
|
||||
# the deviation here is kept for backwards compatibility
|
||||
name = coalesce(
|
||||
var.boot_disk.use_independent_disk.name, "${var.name}-boot"
|
||||
)
|
||||
image = var.boot_disk.source.image
|
||||
architecture = var.boot_disk.architecture
|
||||
type = var.boot_disk.initialize_params.type
|
||||
size = var.boot_disk.initialize_params.size
|
||||
provisioned_iops = var.boot_disk.initialize_params.hyperdisk.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.hyperdisk.provisioned_throughput
|
||||
storage_pool = var.boot_disk.initialize_params.hyperdisk.storage_pool
|
||||
labels = merge(var.labels, {
|
||||
disk_name = "boot"
|
||||
disk_type = var.boot_disk.initialize_params.type
|
||||
})
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
raw_key = var.encryption.disk_encryption_key_raw
|
||||
kms_key_self_link = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_disk" "disks" {
|
||||
for_each = local.is_template ? {} : {
|
||||
for k, v in local.attached_disks_zonal :
|
||||
k => v if v.source.attach == null
|
||||
}
|
||||
project = local.project_id
|
||||
zone = local.zone
|
||||
name = coalesce(each.value.name, "${var.name}-${each.key}")
|
||||
type = each.value.initialize_params.type
|
||||
size = each.value.initialize_params.size
|
||||
architecture = var.boot_disk.architecture
|
||||
image = each.value.source.image
|
||||
provisioned_iops = each.value.initialize_params.hyperdisk.provisioned_iops
|
||||
provisioned_throughput = each.value.initialize_params.hyperdisk.provisioned_throughput
|
||||
snapshot = each.value.source.snapshot
|
||||
storage_pool = each.value.initialize_params.hyperdisk.storage_pool
|
||||
labels = merge(var.labels, {
|
||||
disk_name = coalesce(each.value.name, each.key)
|
||||
disk_type = each.value.initialize_params.type
|
||||
})
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
raw_key = var.encryption.disk_encryption_key_raw
|
||||
kms_key_self_link = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_region_disk" "disks" {
|
||||
for_each = local.is_template ? {} : {
|
||||
for k, v in local.attached_disks_regional :
|
||||
k => v if v.source.attach == null
|
||||
}
|
||||
project = local.project_id
|
||||
region = local.region
|
||||
replica_zones = [local.zone, each.value.initialize_params.replica_zone]
|
||||
name = coalesce(each.value.name, "${var.name}-${each.key}")
|
||||
type = each.value.initialize_params.type
|
||||
size = each.value.initialize_params.size
|
||||
# image = each.value.source.image
|
||||
snapshot = each.value.source.snapshot
|
||||
labels = merge(var.labels, {
|
||||
disk_name = coalesce(each.value.name, each.key)
|
||||
disk_type = each.value.initialize_params.type
|
||||
})
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
raw_key = var.encryption.disk_encryption_key_raw
|
||||
# TODO: check if self link works here
|
||||
kms_key_name = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
311
modules/compute-vm/instance.tf
Normal file
311
modules/compute-vm/instance.tf
Normal file
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* Copyright 2026 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
resource "google_compute_instance" "default" {
|
||||
provider = google-beta
|
||||
count = local.is_template ? 0 : 1
|
||||
project = local.project_id
|
||||
zone = local.zone
|
||||
name = var.name
|
||||
hostname = var.hostname
|
||||
description = var.description
|
||||
tags = var.tags
|
||||
machine_type = var.machine_type
|
||||
min_cpu_platform = var.min_cpu_platform
|
||||
can_ip_forward = var.can_ip_forward
|
||||
allow_stopping_for_update = var.lifecycle_config.allow_stopping_for_update
|
||||
deletion_protection = var.lifecycle_config.deletion_protection
|
||||
key_revocation_action_type = var.lifecycle_config.key_revocation_action_type
|
||||
enable_display = var.enable_display
|
||||
labels = var.labels
|
||||
metadata = var.metadata
|
||||
metadata_startup_script = var.metadata_startup_script
|
||||
resource_policies = (
|
||||
var.resource_policies == null && var.instance_schedule == null
|
||||
? null
|
||||
: concat(
|
||||
coalesce(var.resource_policies, []),
|
||||
coalesce(local.ischedule, [])
|
||||
)
|
||||
)
|
||||
|
||||
dynamic "advanced_machine_features" {
|
||||
for_each = local.advanced_mf ? [""] : []
|
||||
content {
|
||||
enable_nested_virtualization = var.machine_features_config.enable_nested_virtualization
|
||||
enable_uefi_networking = var.machine_features_config.enable_uefi_networking
|
||||
performance_monitoring_unit = var.machine_features_config.performance_monitoring_unit
|
||||
threads_per_core = var.machine_features_config.threads_per_core
|
||||
turbo_mode = (
|
||||
var.machine_features_config.enable_turbo_mode == true ? "ALL_CORE_MAX" : null
|
||||
)
|
||||
visible_core_count = var.machine_features_config.visible_core_count
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "attached_disk" {
|
||||
for_each = local.attached_disks_zonal
|
||||
iterator = disk
|
||||
content {
|
||||
device_name = coalesce(
|
||||
disk.value.device_name, disk.value.name, disk.key
|
||||
)
|
||||
force_attach = disk.value.force_attach
|
||||
mode = disk.value.mode
|
||||
source = (
|
||||
disk.value.source.attach != null
|
||||
? disk.value.source.attach
|
||||
: google_compute_disk.disks[disk.key].name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "attached_disk" {
|
||||
for_each = local.attached_disks_regional
|
||||
iterator = disk
|
||||
content {
|
||||
device_name = coalesce(
|
||||
disk.value.device_name, disk.value.name, disk.key
|
||||
)
|
||||
force_attach = disk.value.force_attach
|
||||
mode = disk.value.mode
|
||||
source = (
|
||||
disk.value.source.attach != null
|
||||
? disk.value.source.attach
|
||||
: google_compute_region_disk.disks[disk.key].id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
boot_disk {
|
||||
auto_delete = (
|
||||
var.boot_disk.use_independent_disk != null
|
||||
? false
|
||||
: var.boot_disk.auto_delete
|
||||
)
|
||||
force_attach = var.boot_disk.force_attach
|
||||
source = (
|
||||
var.boot_disk.use_independent_disk != null
|
||||
? google_compute_disk.boot[0].id
|
||||
: try(coalesce(
|
||||
var.boot_disk.source.snapshot,
|
||||
var.boot_disk.source.attach
|
||||
), null)
|
||||
)
|
||||
disk_encryption_key_raw = (
|
||||
var.encryption != null ?
|
||||
try(
|
||||
local.ctx_kms_keys[var.encryption.disk_encryption_key_raw],
|
||||
var.encryption.disk_encryption_key_raw
|
||||
)
|
||||
: null
|
||||
)
|
||||
kms_key_self_link = (
|
||||
var.encryption != null
|
||||
? try(
|
||||
local.ctx_kms_keys[var.encryption.kms_key_self_link],
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
: null
|
||||
)
|
||||
dynamic "initialize_params" {
|
||||
for_each = (
|
||||
var.boot_disk.initialize_params == null
|
||||
||
|
||||
var.boot_disk.use_independent_disk != null
|
||||
|| (
|
||||
var.boot_disk.source.snapshot != null &&
|
||||
var.boot_disk.source.attach != null
|
||||
)
|
||||
? []
|
||||
: [""]
|
||||
)
|
||||
content {
|
||||
architecture = var.boot_disk.architecture
|
||||
image = var.boot_disk.source.image
|
||||
size = var.boot_disk.initialize_params.size
|
||||
type = var.boot_disk.initialize_params.type
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
provisioned_iops = var.boot_disk.initialize_params.hyperdisk.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.hyperdisk.provisioned_throughput
|
||||
storage_pool = var.boot_disk.initialize_params.hyperdisk.storage_pool
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "confidential_instance_config" {
|
||||
for_each = var.confidential_compute != null ? [""] : []
|
||||
content {
|
||||
enable_confidential_compute = true
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "network_interface" {
|
||||
for_each = var.network_interfaces
|
||||
iterator = config
|
||||
content {
|
||||
network = lookup(
|
||||
local.ctx.networks, config.value.network, config.value.network
|
||||
)
|
||||
subnetwork = lookup(
|
||||
local.ctx.subnets, config.value.subnetwork, config.value.subnetwork
|
||||
)
|
||||
network_ip = try(
|
||||
local.ctx.addresses[config.value.addresses.internal],
|
||||
config.value.addresses.internal,
|
||||
null
|
||||
)
|
||||
nic_type = config.value.nic_type
|
||||
stack_type = config.value.stack_type
|
||||
queue_count = config.value.queue_count
|
||||
internal_ipv6_prefix_length = config.value.internal_ipv6_prefix_length
|
||||
dynamic "access_config" {
|
||||
for_each = config.value.nat || config.value.network_tier != null ? [""] : []
|
||||
content {
|
||||
nat_ip = try(
|
||||
local.ctx.addresses[config.value.addresses.external],
|
||||
config.value.addresses.external,
|
||||
null
|
||||
)
|
||||
network_tier = try(config.value.network_tier, null)
|
||||
}
|
||||
}
|
||||
dynamic "alias_ip_range" {
|
||||
for_each = config.value.alias_ips
|
||||
iterator = config_alias
|
||||
content {
|
||||
subnetwork_range_name = config_alias.key
|
||||
ip_cidr_range = config_alias.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "network_interface" {
|
||||
for_each = var.network_attached_interfaces
|
||||
content {
|
||||
network_attachment = network_interface.value
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "network_performance_config" {
|
||||
for_each = var.network_performance_tier != null ? [""] : []
|
||||
content {
|
||||
total_egress_bandwidth_tier = var.network_performance_tier
|
||||
}
|
||||
}
|
||||
|
||||
scheduling {
|
||||
automatic_restart = coalesce(
|
||||
var.scheduling_config.automatic_restart, var.scheduling_config.provisioning_model != "SPOT"
|
||||
)
|
||||
instance_termination_action = local.termination_action
|
||||
on_host_maintenance = local.on_host_maintenance
|
||||
preemptible = var.scheduling_config.provisioning_model == "SPOT"
|
||||
provisioning_model = coalesce(var.scheduling_config.provisioning_model, "STANDARD")
|
||||
min_node_cpus = var.scheduling_config.min_node_cpus
|
||||
maintenance_interval = var.scheduling_config.maintenance_interval
|
||||
|
||||
dynamic "max_run_duration" {
|
||||
for_each = var.scheduling_config.max_run_duration == null ? [] : [""]
|
||||
content {
|
||||
nanos = var.scheduling_config.max_run_duration.nanos
|
||||
seconds = var.scheduling_config.max_run_duration.seconds
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "local_ssd_recovery_timeout" {
|
||||
for_each = var.scheduling_config.local_ssd_recovery_timeout == null ? [] : [""]
|
||||
content {
|
||||
nanos = var.scheduling_config.local_ssd_recovery_timeout.nanos
|
||||
seconds = var.scheduling_config.local_ssd_recovery_timeout.seconds
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "node_affinities" {
|
||||
for_each = var.scheduling_config.node_affinities
|
||||
iterator = affinity
|
||||
content {
|
||||
key = affinity.key
|
||||
operator = affinity.value.in ? "IN" : "NOT_IN"
|
||||
values = affinity.value.values
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "graceful_shutdown" {
|
||||
for_each = var.lifecycle_config.graceful_shutdown != null ? [""] : []
|
||||
content {
|
||||
enabled = var.lifecycle_config.graceful_shutdown.enabled
|
||||
dynamic "max_duration" {
|
||||
for_each = (
|
||||
var.lifecycle_config.graceful_shutdown.enabled == true &&
|
||||
var.lifecycle_config.graceful_shutdown.max_duration_secs != null
|
||||
? [""]
|
||||
: []
|
||||
)
|
||||
content {
|
||||
seconds = var.lifecycle_config.graceful_shutdown.max_duration_secs
|
||||
nanos = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dynamic "scratch_disk" {
|
||||
for_each = [
|
||||
for i in range(0, var.scratch_disks.count) : var.scratch_disks.interface
|
||||
]
|
||||
iterator = config
|
||||
content {
|
||||
interface = config.value
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "service_account" {
|
||||
for_each = var.service_account == null ? [] : [""]
|
||||
content {
|
||||
email = local.service_account.email
|
||||
scopes = local.service_account.scopes
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "shielded_instance_config" {
|
||||
for_each = var.shielded_config != null ? [var.shielded_config] : []
|
||||
iterator = config
|
||||
content {
|
||||
enable_secure_boot = config.value.enable_secure_boot
|
||||
enable_vtpm = config.value.enable_vtpm
|
||||
enable_integrity_monitoring = config.value.enable_integrity_monitoring
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "params" {
|
||||
for_each = var.tag_bindings_immutable == null ? [] : [""]
|
||||
content {
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "guest_accelerator" {
|
||||
for_each = local.gpu ? [var.gpu] : []
|
||||
content {
|
||||
type = guest_accelerator.value.type
|
||||
count = guest_accelerator.value.count
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,22 +15,10 @@
|
||||
*/
|
||||
|
||||
locals {
|
||||
_region = join("-", slice(split("-", local.zone), 0, 2))
|
||||
advanced_mf = var.options.advanced_machine_features
|
||||
attached_disks = {
|
||||
for i, disk in var.attached_disks :
|
||||
coalesce(disk.name, disk.device_name, "disk-${i}") => merge(disk, {
|
||||
options = disk.options == null ? var.attached_disk_defaults : disk.options
|
||||
})
|
||||
}
|
||||
attached_disks_regional = {
|
||||
for k, v in local.attached_disks :
|
||||
k => v if try(v.options.replica_zone, null) != null
|
||||
}
|
||||
attached_disks_zonal = {
|
||||
for k, v in local.attached_disks :
|
||||
k => v if try(v.options.replica_zone, null) == null
|
||||
}
|
||||
_region = join("-", slice(split("-", local.zone), 0, 2))
|
||||
advanced_mf = anytrue([
|
||||
for k, v in var.machine_features_config : v != null
|
||||
])
|
||||
ctx = {
|
||||
for k, v in var.context : k => {
|
||||
for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv
|
||||
@@ -42,10 +30,13 @@ locals {
|
||||
})
|
||||
ctx_p = "$"
|
||||
gpu = var.gpu != null
|
||||
on_host_maintenance = (
|
||||
var.options.spot || var.confidential_compute || local.gpu
|
||||
? "TERMINATE"
|
||||
: "MIGRATE"
|
||||
on_host_maintenance = coalesce(
|
||||
var.scheduling_config.on_host_maintenance,
|
||||
(
|
||||
var.scheduling_config.provisioning_model == "SPOT" ||
|
||||
var.confidential_compute != null ||
|
||||
local.gpu
|
||||
) ? "TERMINATE" : "MIGRATE"
|
||||
)
|
||||
project_id = lookup(local.ctx.project_ids, var.project_id, var.project_id)
|
||||
region = lookup(local.ctx.locations, local._region, local._region)
|
||||
@@ -75,7 +66,9 @@ locals {
|
||||
)
|
||||
}
|
||||
termination_action = (
|
||||
var.options.spot || var.options.max_run_duration != null ? coalesce(var.options.termination_action, "STOP") : null
|
||||
var.scheduling_config.provisioning_model == "SPOT" || var.scheduling_config.max_run_duration != null
|
||||
? coalesce(var.scheduling_config.termination_action, "STOP")
|
||||
: null
|
||||
)
|
||||
zone = lookup(local.ctx.locations, var.zone, var.zone)
|
||||
}
|
||||
@@ -92,366 +85,6 @@ resource "google_kms_key_handle" "default" {
|
||||
resource_type_selector = each.value.resource_type_selector
|
||||
}
|
||||
|
||||
resource "google_compute_disk" "boot" {
|
||||
count = !local.template_create && var.boot_disk.use_independent_disk ? 1 : 0
|
||||
project = local.project_id
|
||||
zone = local.zone
|
||||
# by default, GCP creates boot disks with the same name as instance, the deviation here is kept for backwards
|
||||
# compatibility
|
||||
name = coalesce(var.boot_disk.name, "${var.name}-boot")
|
||||
type = var.boot_disk.initialize_params.type
|
||||
size = var.boot_disk.initialize_params.size
|
||||
architecture = var.boot_disk.initialize_params.architecture
|
||||
image = var.boot_disk.initialize_params.image
|
||||
provisioned_iops = var.boot_disk.initialize_params.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.provisioned_throughput
|
||||
storage_pool = var.boot_disk.initialize_params.storage_pool
|
||||
labels = merge(var.labels, {
|
||||
disk_name = "boot"
|
||||
disk_type = var.boot_disk.initialize_params.type
|
||||
})
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
raw_key = var.encryption.disk_encryption_key_raw
|
||||
kms_key_self_link = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_disk" "disks" {
|
||||
for_each = local.template_create ? {} : {
|
||||
for k, v in local.attached_disks_zonal :
|
||||
k => v if v.source_type != "attach"
|
||||
}
|
||||
project = local.project_id
|
||||
zone = local.zone
|
||||
name = "${var.name}-${each.key}"
|
||||
type = each.value.options.type
|
||||
size = each.value.size
|
||||
architecture = each.value.options.architecture
|
||||
image = each.value.source_type == "image" ? each.value.source : null
|
||||
provisioned_iops = each.value.options.provisioned_iops
|
||||
provisioned_throughput = each.value.options.provisioned_throughput
|
||||
snapshot = each.value.source_type == "snapshot" ? each.value.source : null
|
||||
storage_pool = each.value.options.storage_pool
|
||||
labels = merge(var.labels, {
|
||||
disk_name = each.value.name
|
||||
disk_type = each.value.options.type
|
||||
})
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
raw_key = var.encryption.disk_encryption_key_raw
|
||||
kms_key_self_link = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_region_disk" "disks" {
|
||||
provider = google-beta
|
||||
for_each = local.template_create ? {} : {
|
||||
for k, v in local.attached_disks_regional :
|
||||
k => v if v.source_type != "attach"
|
||||
}
|
||||
project = local.project_id
|
||||
region = local.region
|
||||
replica_zones = [local.zone, each.value.options.replica_zone]
|
||||
name = "${var.name}-${each.key}"
|
||||
type = each.value.options.type
|
||||
size = each.value.size
|
||||
# image = each.value.source_type == "image" ? each.value.source : null
|
||||
snapshot = each.value.source_type == "snapshot" ? each.value.source : null
|
||||
labels = merge(var.labels, {
|
||||
disk_name = each.value.name
|
||||
disk_type = each.value.options.type
|
||||
})
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
raw_key = var.encryption.disk_encryption_key_raw
|
||||
# TODO: check if self link works here
|
||||
kms_key_name = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance" "default" {
|
||||
provider = google-beta
|
||||
count = local.template_create ? 0 : 1
|
||||
project = local.project_id
|
||||
zone = local.zone
|
||||
name = var.name
|
||||
hostname = var.hostname
|
||||
description = var.description
|
||||
tags = var.tags
|
||||
machine_type = var.instance_type
|
||||
min_cpu_platform = var.min_cpu_platform
|
||||
can_ip_forward = var.can_ip_forward
|
||||
allow_stopping_for_update = var.options.allow_stopping_for_update
|
||||
deletion_protection = var.options.deletion_protection
|
||||
key_revocation_action_type = var.options.key_revocation_action_type
|
||||
enable_display = var.enable_display
|
||||
labels = var.labels
|
||||
metadata = var.metadata
|
||||
metadata_startup_script = var.metadata_startup_script
|
||||
resource_policies = (
|
||||
var.resource_policies == null && var.instance_schedule == null
|
||||
? null
|
||||
: concat(
|
||||
coalesce(var.resource_policies, []),
|
||||
coalesce(local.ischedule, [])
|
||||
)
|
||||
)
|
||||
|
||||
dynamic "advanced_machine_features" {
|
||||
for_each = local.advanced_mf != null ? [""] : []
|
||||
content {
|
||||
enable_nested_virtualization = local.advanced_mf.enable_nested_virtualization
|
||||
enable_uefi_networking = local.advanced_mf.enable_uefi_networking
|
||||
performance_monitoring_unit = local.advanced_mf.performance_monitoring_unit
|
||||
threads_per_core = local.advanced_mf.threads_per_core
|
||||
turbo_mode = (
|
||||
local.advanced_mf.enable_turbo_mode ? "ALL_CORE_MAX" : null
|
||||
)
|
||||
visible_core_count = local.advanced_mf.visible_core_count
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "attached_disk" {
|
||||
for_each = local.attached_disks_zonal
|
||||
iterator = config
|
||||
content {
|
||||
device_name = (
|
||||
config.value.device_name != null
|
||||
? config.value.device_name
|
||||
: config.value.name
|
||||
)
|
||||
mode = config.value.options.mode
|
||||
source = (
|
||||
config.value.source_type == "attach"
|
||||
? config.value.source
|
||||
: google_compute_disk.disks[config.key].name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "attached_disk" {
|
||||
for_each = local.attached_disks_regional
|
||||
iterator = config
|
||||
content {
|
||||
device_name = coalesce(
|
||||
config.value.device_name, config.value.name, config.key
|
||||
)
|
||||
mode = config.value.options.mode
|
||||
source = (
|
||||
config.value.source_type == "attach"
|
||||
? config.value.source
|
||||
: google_compute_region_disk.disks[config.key].id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
boot_disk {
|
||||
auto_delete = (
|
||||
var.boot_disk.use_independent_disk
|
||||
? false
|
||||
: var.boot_disk.auto_delete
|
||||
)
|
||||
source = (
|
||||
var.boot_disk.use_independent_disk
|
||||
? google_compute_disk.boot[0].id
|
||||
: var.boot_disk.source
|
||||
)
|
||||
disk_encryption_key_raw = (
|
||||
var.encryption != null ?
|
||||
try(
|
||||
local.ctx_kms_keys[var.encryption.disk_encryption_key_raw],
|
||||
var.encryption.disk_encryption_key_raw
|
||||
)
|
||||
: null
|
||||
)
|
||||
kms_key_self_link = (
|
||||
var.encryption != null
|
||||
? try(
|
||||
local.ctx_kms_keys[var.encryption.kms_key_self_link],
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
: null
|
||||
)
|
||||
dynamic "initialize_params" {
|
||||
for_each = (
|
||||
var.boot_disk.initialize_params == null
|
||||
||
|
||||
var.boot_disk.use_independent_disk
|
||||
||
|
||||
var.boot_disk.source != null
|
||||
? []
|
||||
: [""]
|
||||
)
|
||||
content {
|
||||
architecture = var.boot_disk.initialize_params.architecture
|
||||
image = var.boot_disk.initialize_params.image
|
||||
size = var.boot_disk.initialize_params.size
|
||||
type = var.boot_disk.initialize_params.type
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
provisioned_iops = var.boot_disk.initialize_params.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.provisioned_throughput
|
||||
storage_pool = var.boot_disk.initialize_params.storage_pool
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "confidential_instance_config" {
|
||||
for_each = var.confidential_compute ? [""] : []
|
||||
content {
|
||||
enable_confidential_compute = true
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "network_interface" {
|
||||
for_each = var.network_interfaces
|
||||
iterator = config
|
||||
content {
|
||||
network = lookup(
|
||||
local.ctx.networks, config.value.network, config.value.network
|
||||
)
|
||||
subnetwork = lookup(
|
||||
local.ctx.subnets, config.value.subnetwork, config.value.subnetwork
|
||||
)
|
||||
network_ip = try(
|
||||
local.ctx.addresses[config.value.addresses.internal],
|
||||
config.value.addresses.internal,
|
||||
null
|
||||
)
|
||||
nic_type = config.value.nic_type
|
||||
stack_type = config.value.stack_type
|
||||
dynamic "access_config" {
|
||||
for_each = config.value.nat || config.value.network_tier != null ? [""] : []
|
||||
content {
|
||||
nat_ip = try(
|
||||
local.ctx.addresses[config.value.addresses.external],
|
||||
config.value.addresses.external,
|
||||
null
|
||||
)
|
||||
network_tier = try(config.value.network_tier, null)
|
||||
}
|
||||
}
|
||||
dynamic "alias_ip_range" {
|
||||
for_each = config.value.alias_ips
|
||||
iterator = config_alias
|
||||
content {
|
||||
subnetwork_range_name = config_alias.key
|
||||
ip_cidr_range = config_alias.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "network_interface" {
|
||||
for_each = var.network_attached_interfaces
|
||||
content {
|
||||
network_attachment = network_interface.value
|
||||
}
|
||||
}
|
||||
|
||||
scheduling {
|
||||
automatic_restart = !var.options.spot
|
||||
instance_termination_action = local.termination_action
|
||||
on_host_maintenance = local.on_host_maintenance
|
||||
preemptible = var.options.spot
|
||||
provisioning_model = var.options.spot ? "SPOT" : "STANDARD"
|
||||
dynamic "max_run_duration" {
|
||||
for_each = var.options.max_run_duration == null ? [] : [""]
|
||||
content {
|
||||
nanos = var.options.max_run_duration.nanos
|
||||
seconds = var.options.max_run_duration.seconds
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "node_affinities" {
|
||||
for_each = var.options.node_affinities
|
||||
iterator = affinity
|
||||
content {
|
||||
key = affinity.key
|
||||
operator = affinity.value.in ? "IN" : "NOT_IN"
|
||||
values = affinity.value.values
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "graceful_shutdown" {
|
||||
for_each = var.options.graceful_shutdown != null ? [""] : []
|
||||
content {
|
||||
enabled = var.options.graceful_shutdown.enabled
|
||||
dynamic "max_duration" {
|
||||
for_each = var.options.graceful_shutdown.enabled == true && var.options.graceful_shutdown.max_duration_secs != null ? [""] : []
|
||||
content {
|
||||
seconds = var.options.graceful_shutdown.max_duration_secs
|
||||
nanos = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dynamic "scratch_disk" {
|
||||
for_each = [
|
||||
for i in range(0, var.scratch_disks.count) : var.scratch_disks.interface
|
||||
]
|
||||
iterator = config
|
||||
content {
|
||||
interface = config.value
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "service_account" {
|
||||
for_each = var.service_account == null ? [] : [""]
|
||||
content {
|
||||
email = local.service_account.email
|
||||
scopes = local.service_account.scopes
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "shielded_instance_config" {
|
||||
for_each = var.shielded_config != null ? [var.shielded_config] : []
|
||||
iterator = config
|
||||
content {
|
||||
enable_secure_boot = config.value.enable_secure_boot
|
||||
enable_vtpm = config.value.enable_vtpm
|
||||
enable_integrity_monitoring = config.value.enable_integrity_monitoring
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "params" {
|
||||
for_each = var.tag_bindings_immutable == null ? [] : [""]
|
||||
content {
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "guest_accelerator" {
|
||||
for_each = local.gpu ? [var.gpu] : []
|
||||
content {
|
||||
type = guest_accelerator.value.type
|
||||
count = guest_accelerator.value.count
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_iam_binding" "default" {
|
||||
project = local.project_id
|
||||
for_each = var.iam
|
||||
@@ -465,7 +98,7 @@ resource "google_compute_instance_iam_binding" "default" {
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group" "unmanaged" {
|
||||
count = var.group != null && !local.template_create ? 1 : 0
|
||||
count = var.group != null && !local.is_template ? 1 : 0
|
||||
project = local.project_id
|
||||
network = (
|
||||
length(var.network_interfaces) > 0
|
||||
|
||||
@@ -21,23 +21,21 @@ locals {
|
||||
google_compute_resource_policy.schedule[0].id
|
||||
]
|
||||
disk_zonal_schedule_attachments = flatten([
|
||||
for disk_key, disk_data in local.attached_disks_zonal :
|
||||
disk_data.snapshot_schedule != null ? [
|
||||
for schedule in disk_data.snapshot_schedule : {
|
||||
disk_key = disk_key
|
||||
source_type = disk_data.source_type
|
||||
source = disk_data.source
|
||||
for k, v in local.attached_disks_zonal :
|
||||
v.snapshot_schedule != null ? [
|
||||
for schedule in v.snapshot_schedule : {
|
||||
disk_key = k
|
||||
source = v.source
|
||||
snapshot_schedule = schedule
|
||||
}
|
||||
] : []
|
||||
])
|
||||
disk_regional_schedule_attachments = flatten([
|
||||
for disk_key, disk_data in try(local.attached_disks_regional, []) :
|
||||
disk_data.snapshot_schedule != null ? [
|
||||
for schedule in disk_data.snapshot_schedule : {
|
||||
disk_key = disk_key
|
||||
source_type = disk_data.source_type
|
||||
source = disk_data.source
|
||||
for k, v in try(local.attached_disks_regional, []) :
|
||||
v.snapshot_schedule != null ? [
|
||||
for schedule in v.snapshot_schedule : {
|
||||
disk_key = k
|
||||
source = v.source
|
||||
snapshot_schedule = schedule
|
||||
}
|
||||
] : []
|
||||
@@ -140,7 +138,7 @@ resource "google_compute_disk_resource_policy_attachment" "boot" {
|
||||
)
|
||||
# if independent disk is used for boot disk it will have a different name compared to when created implicitly
|
||||
disk = (
|
||||
!local.template_create && var.boot_disk.use_independent_disk
|
||||
!local.is_template && var.boot_disk.use_independent_disk != null
|
||||
? google_compute_disk.boot[0].name
|
||||
: var.name
|
||||
)
|
||||
@@ -160,8 +158,8 @@ resource "google_compute_disk_resource_policy_attachment" "attached" {
|
||||
each.value.snapshot_schedule
|
||||
)
|
||||
disk = (
|
||||
each.value.source_type == "attach"
|
||||
? each.value.source
|
||||
each.value.source.attach != null
|
||||
? each.value.source.attach
|
||||
: google_compute_disk.disks[each.value.disk_key].name
|
||||
)
|
||||
depends_on = [
|
||||
@@ -182,8 +180,8 @@ resource "google_compute_region_disk_resource_policy_attachment" "attached" {
|
||||
each.value.snapshot_schedule
|
||||
)
|
||||
disk = (
|
||||
each.value.source_type == "attach"
|
||||
? each.value.source
|
||||
each.value.source.attach != null
|
||||
? each.value.source.attach
|
||||
: google_compute_region_disk.disks[each.value.disk_key].name
|
||||
)
|
||||
depends_on = [
|
||||
|
||||
@@ -53,7 +53,7 @@ locals {
|
||||
# use a different resource to avoid overlapping key issues
|
||||
|
||||
resource "google_tags_location_tag_binding" "network" {
|
||||
for_each = local.template_create ? {} : var.network_tag_bindings
|
||||
for_each = local.is_template ? {} : var.network_tag_bindings
|
||||
parent = (
|
||||
"${local.tag_parent_base}/zones/${local.zone}/instances/${google_compute_instance.default[0].instance_id}"
|
||||
)
|
||||
@@ -62,7 +62,7 @@ resource "google_tags_location_tag_binding" "network" {
|
||||
}
|
||||
|
||||
resource "google_tags_location_tag_binding" "instance" {
|
||||
for_each = local.template_create ? {} : var.tag_bindings
|
||||
for_each = local.is_template ? {} : var.tag_bindings
|
||||
parent = (
|
||||
"${local.tag_parent_base}/zones/${local.zone}/instances/${google_compute_instance.default[0].instance_id}"
|
||||
)
|
||||
@@ -72,7 +72,7 @@ resource "google_tags_location_tag_binding" "instance" {
|
||||
|
||||
resource "google_tags_location_tag_binding" "boot_disks" {
|
||||
for_each = (
|
||||
local.template_create ? {} : { for v in local.boot_disk_tags : v.key => v }
|
||||
local.is_template ? {} : { for v in local.boot_disk_tags : v.key => v }
|
||||
)
|
||||
parent = (
|
||||
"${local.tag_parent_base}/zones/${local.zone}/disks/${each.value.disk_id}"
|
||||
@@ -83,7 +83,7 @@ resource "google_tags_location_tag_binding" "boot_disks" {
|
||||
|
||||
resource "google_tags_location_tag_binding" "disks" {
|
||||
for_each = (
|
||||
local.template_create ? {} : { for v in local.disk_tags : v.key => v }
|
||||
local.is_template ? {} : { for v in local.disk_tags : v.key => v }
|
||||
)
|
||||
parent = (
|
||||
"${local.tag_parent_base}/zones/${local.zone}/disks/${each.value.disk_id}"
|
||||
@@ -94,7 +94,7 @@ resource "google_tags_location_tag_binding" "disks" {
|
||||
|
||||
resource "google_tags_location_tag_binding" "disks_regional" {
|
||||
for_each = (
|
||||
local.template_create ? {} : { for v in local.region_disk_tags : v.key => v }
|
||||
local.is_template ? {} : { for v in local.region_disk_tags : v.key => v }
|
||||
)
|
||||
parent = (
|
||||
"${local.tag_parent_base}/regions/${local.region}/disks/${each.value.disk_id}"
|
||||
@@ -106,7 +106,7 @@ resource "google_tags_location_tag_binding" "disks_regional" {
|
||||
# TODO: enable once the template id is available
|
||||
|
||||
# resource "google_tags_location_tag_binding" "template" {
|
||||
# for_each = local.template_create ? var.tag_bindings : {}
|
||||
# for_each = local.is_template ? var.tag_bindings : {}
|
||||
# parent = (
|
||||
# "${local.tag_parent_base}/regions/${local.region}/instanceTemplates/${google_compute_instance_template.default[0].instance_id}"
|
||||
# )
|
||||
|
||||
@@ -15,26 +15,26 @@
|
||||
*/
|
||||
|
||||
locals {
|
||||
template_create = var.create_template != null
|
||||
is_template = var.create_template != null
|
||||
template_regional = try(var.create_template.regional, null) == true
|
||||
}
|
||||
|
||||
resource "google_compute_instance_template" "default" {
|
||||
provider = google-beta
|
||||
count = local.template_create && !local.template_regional ? 1 : 0
|
||||
count = local.is_template && !local.template_regional ? 1 : 0
|
||||
project = local.project_id
|
||||
region = local.region
|
||||
name_prefix = "${var.name}-"
|
||||
description = var.description
|
||||
tags = var.tags
|
||||
machine_type = var.instance_type
|
||||
machine_type = var.machine_type
|
||||
min_cpu_platform = var.min_cpu_platform
|
||||
can_ip_forward = var.can_ip_forward
|
||||
metadata = var.metadata
|
||||
metadata_startup_script = var.metadata_startup_script
|
||||
labels = var.labels
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
key_revocation_action_type = var.options.key_revocation_action_type
|
||||
key_revocation_action_type = var.lifecycle_config.key_revocation_action_type
|
||||
resource_policies = (
|
||||
var.resource_policies == null && var.instance_schedule == null
|
||||
? null
|
||||
@@ -44,29 +44,29 @@ resource "google_compute_instance_template" "default" {
|
||||
)
|
||||
)
|
||||
dynamic "advanced_machine_features" {
|
||||
for_each = local.advanced_mf != null ? [""] : []
|
||||
for_each = local.advanced_mf ? [""] : []
|
||||
content {
|
||||
enable_nested_virtualization = local.advanced_mf.enable_nested_virtualization
|
||||
enable_uefi_networking = local.advanced_mf.enable_uefi_networking
|
||||
performance_monitoring_unit = local.advanced_mf.performance_monitoring_unit
|
||||
threads_per_core = local.advanced_mf.threads_per_core
|
||||
enable_nested_virtualization = var.machine_features_config.enable_nested_virtualization
|
||||
enable_uefi_networking = var.machine_features_config.enable_uefi_networking
|
||||
performance_monitoring_unit = var.machine_features_config.performance_monitoring_unit
|
||||
threads_per_core = var.machine_features_config.threads_per_core
|
||||
turbo_mode = (
|
||||
local.advanced_mf.enable_turbo_mode ? "ALL_CORE_MAX" : null
|
||||
var.machine_features_config.enable_turbo_mode == true ? "ALL_CORE_MAX" : null
|
||||
)
|
||||
visible_core_count = local.advanced_mf.visible_core_count
|
||||
visible_core_count = var.machine_features_config.visible_core_count
|
||||
}
|
||||
}
|
||||
|
||||
disk {
|
||||
architecture = var.boot_disk.initialize_params.architecture
|
||||
auto_delete = var.boot_disk.auto_delete
|
||||
boot = true
|
||||
architecture = var.boot_disk.architecture
|
||||
auto_delete = var.boot_disk.auto_delete
|
||||
disk_size_gb = var.boot_disk.initialize_params.size
|
||||
disk_type = var.boot_disk.initialize_params.type
|
||||
provisioned_iops = var.boot_disk.initialize_params.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.provisioned_throughput
|
||||
source_image = var.boot_disk.source.image
|
||||
provisioned_iops = var.boot_disk.initialize_params.hyperdisk.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.hyperdisk.provisioned_throughput
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
source_image = var.boot_disk.initialize_params.image
|
||||
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
@@ -81,7 +81,7 @@ resource "google_compute_instance_template" "default" {
|
||||
}
|
||||
|
||||
dynamic "confidential_instance_config" {
|
||||
for_each = var.confidential_compute ? [""] : []
|
||||
for_each = var.confidential_compute != null ? [""] : []
|
||||
content {
|
||||
enable_confidential_compute = true
|
||||
}
|
||||
@@ -95,36 +95,39 @@ resource "google_compute_instance_template" "default" {
|
||||
}
|
||||
}
|
||||
dynamic "disk" {
|
||||
for_each = local.attached_disks
|
||||
iterator = config
|
||||
for_each = var.attached_disks
|
||||
content {
|
||||
architecture = config.value.options.architecture
|
||||
auto_delete = config.value.options.auto_delete
|
||||
device_name = coalesce(
|
||||
config.value.device_name, config.value.name, config.key
|
||||
architecture = var.boot_disk.architecture
|
||||
auto_delete = disk.value.mode == "READ_ONLY" ? null : disk.value.auto_delete
|
||||
device_name = coalesce(disk.value.device_name, disk.value.name, disk.key)
|
||||
disk_name = (
|
||||
disk.value.source.attach == null
|
||||
? coalesce(disk.value.name, disk.key)
|
||||
: null
|
||||
)
|
||||
mode = disk.value.mode
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
source_image = disk.value.source.image
|
||||
source = disk.value.source.attach
|
||||
type = "PERSISTENT"
|
||||
# Cannot use `source` with any of the fields in
|
||||
# [disk_size_gb disk_name disk_type source_image labels]
|
||||
disk_type = (
|
||||
config.value.source_type != "attach" ? config.value.options.type : null
|
||||
disk.value.source.attach == null
|
||||
? disk.value.initialize_params.type
|
||||
: null
|
||||
)
|
||||
disk_size_gb = (
|
||||
config.value.source_type != "attach" ? config.value.size : null
|
||||
disk.value.source.attach == null
|
||||
? disk.value.initialize_params.size
|
||||
: null
|
||||
)
|
||||
mode = config.value.options.mode
|
||||
provisioned_iops = config.value.options.provisioned_iops
|
||||
provisioned_throughput = config.value.options.provisioned_throughput
|
||||
source_image = (
|
||||
config.value.source_type == "image" ? config.value.source : null
|
||||
provisioned_iops = (
|
||||
disk.value.initialize_params.hyperdisk.provisioned_iops
|
||||
)
|
||||
source = (
|
||||
config.value.source_type == "attach" ? config.value.source : null
|
||||
provisioned_throughput = (
|
||||
disk.value.initialize_params.hyperdisk.provisioned_throughput
|
||||
)
|
||||
disk_name = (
|
||||
config.value.source_type != "attach" ? config.value.name : null
|
||||
)
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
type = "PERSISTENT"
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
@@ -153,8 +156,10 @@ resource "google_compute_instance_template" "default" {
|
||||
config.value.addresses.internal,
|
||||
null
|
||||
)
|
||||
nic_type = config.value.nic_type
|
||||
stack_type = config.value.stack_type
|
||||
nic_type = config.value.nic_type
|
||||
stack_type = config.value.stack_type
|
||||
queue_count = config.value.queue_count
|
||||
internal_ipv6_prefix_length = config.value.internal_ipv6_prefix_length
|
||||
dynamic "access_config" {
|
||||
for_each = config.value.nat || config.value.network_tier != null ? [""] : []
|
||||
content {
|
||||
@@ -184,22 +189,42 @@ resource "google_compute_instance_template" "default" {
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "network_performance_config" {
|
||||
for_each = var.network_performance_tier != null ? [""] : []
|
||||
content {
|
||||
total_egress_bandwidth_tier = var.network_performance_tier
|
||||
}
|
||||
}
|
||||
|
||||
scheduling {
|
||||
automatic_restart = !var.options.spot
|
||||
automatic_restart = coalesce(
|
||||
var.scheduling_config.automatic_restart, var.scheduling_config.provisioning_model != "SPOT"
|
||||
)
|
||||
instance_termination_action = local.termination_action
|
||||
on_host_maintenance = local.on_host_maintenance
|
||||
preemptible = var.options.spot
|
||||
provisioning_model = var.options.spot ? "SPOT" : "STANDARD"
|
||||
preemptible = var.scheduling_config.provisioning_model == "SPOT"
|
||||
provisioning_model = coalesce(var.scheduling_config.provisioning_model, "STANDARD")
|
||||
min_node_cpus = var.scheduling_config.min_node_cpus
|
||||
maintenance_interval = var.scheduling_config.maintenance_interval
|
||||
|
||||
dynamic "max_run_duration" {
|
||||
for_each = var.options.max_run_duration == null ? [] : [""]
|
||||
for_each = var.scheduling_config.max_run_duration == null ? [] : [""]
|
||||
content {
|
||||
nanos = var.options.max_run_duration.nanos
|
||||
seconds = var.options.max_run_duration.seconds
|
||||
nanos = var.scheduling_config.max_run_duration.nanos
|
||||
seconds = var.scheduling_config.max_run_duration.seconds
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "local_ssd_recovery_timeout" {
|
||||
for_each = var.scheduling_config.local_ssd_recovery_timeout == null ? [] : [""]
|
||||
content {
|
||||
nanos = var.scheduling_config.local_ssd_recovery_timeout.nanos
|
||||
seconds = var.scheduling_config.local_ssd_recovery_timeout.seconds
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "node_affinities" {
|
||||
for_each = var.options.node_affinities
|
||||
for_each = var.scheduling_config.node_affinities
|
||||
iterator = affinity
|
||||
content {
|
||||
key = affinity.key
|
||||
@@ -209,13 +234,18 @@ resource "google_compute_instance_template" "default" {
|
||||
}
|
||||
|
||||
dynamic "graceful_shutdown" {
|
||||
for_each = var.options.graceful_shutdown != null ? [""] : []
|
||||
for_each = var.lifecycle_config.graceful_shutdown != null ? [""] : []
|
||||
content {
|
||||
enabled = var.options.graceful_shutdown.enabled
|
||||
enabled = var.lifecycle_config.graceful_shutdown.enabled
|
||||
dynamic "max_duration" {
|
||||
for_each = var.options.graceful_shutdown.enabled == true && var.options.graceful_shutdown.max_duration_secs != null ? [""] : []
|
||||
for_each = (
|
||||
var.lifecycle_config.graceful_shutdown.enabled == true &&
|
||||
var.lifecycle_config.graceful_shutdown.max_duration_secs != null
|
||||
? [""]
|
||||
: []
|
||||
)
|
||||
content {
|
||||
seconds = var.options.graceful_shutdown.max_duration_secs
|
||||
seconds = var.lifecycle_config.graceful_shutdown.max_duration_secs
|
||||
nanos = 0
|
||||
}
|
||||
}
|
||||
@@ -248,20 +278,20 @@ resource "google_compute_instance_template" "default" {
|
||||
|
||||
resource "google_compute_region_instance_template" "default" {
|
||||
provider = google-beta
|
||||
count = local.template_create && local.template_regional ? 1 : 0
|
||||
count = local.is_template && local.template_regional ? 1 : 0
|
||||
project = local.project_id
|
||||
region = local.region
|
||||
name_prefix = "${var.name}-"
|
||||
description = var.description
|
||||
tags = var.tags
|
||||
machine_type = var.instance_type
|
||||
machine_type = var.machine_type
|
||||
min_cpu_platform = var.min_cpu_platform
|
||||
can_ip_forward = var.can_ip_forward
|
||||
metadata = var.metadata
|
||||
metadata_startup_script = var.metadata_startup_script
|
||||
labels = var.labels
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
key_revocation_action_type = var.options.key_revocation_action_type
|
||||
key_revocation_action_type = var.lifecycle_config.key_revocation_action_type
|
||||
resource_policies = (
|
||||
var.resource_policies == null && var.instance_schedule == null
|
||||
? null
|
||||
@@ -271,35 +301,36 @@ resource "google_compute_region_instance_template" "default" {
|
||||
)
|
||||
)
|
||||
dynamic "advanced_machine_features" {
|
||||
for_each = local.advanced_mf != null ? [""] : []
|
||||
for_each = local.advanced_mf ? [""] : []
|
||||
content {
|
||||
enable_nested_virtualization = local.advanced_mf.enable_nested_virtualization
|
||||
enable_uefi_networking = local.advanced_mf.enable_uefi_networking
|
||||
performance_monitoring_unit = local.advanced_mf.performance_monitoring_unit
|
||||
threads_per_core = local.advanced_mf.threads_per_core
|
||||
enable_nested_virtualization = var.machine_features_config.enable_nested_virtualization
|
||||
enable_uefi_networking = var.machine_features_config.enable_uefi_networking
|
||||
performance_monitoring_unit = var.machine_features_config.performance_monitoring_unit
|
||||
threads_per_core = var.machine_features_config.threads_per_core
|
||||
turbo_mode = (
|
||||
local.advanced_mf.enable_turbo_mode ? "ALL_CORE_MAX" : null
|
||||
var.machine_features_config.enable_turbo_mode == true ? "ALL_CORE_MAX" : null
|
||||
)
|
||||
visible_core_count = local.advanced_mf.visible_core_count
|
||||
visible_core_count = var.machine_features_config.visible_core_count
|
||||
}
|
||||
}
|
||||
|
||||
disk {
|
||||
architecture = var.boot_disk.initialize_params.architecture
|
||||
auto_delete = var.boot_disk.auto_delete
|
||||
boot = true
|
||||
architecture = var.boot_disk.architecture
|
||||
auto_delete = var.boot_disk.auto_delete
|
||||
disk_size_gb = var.boot_disk.initialize_params.size
|
||||
disk_type = var.boot_disk.initialize_params.type
|
||||
provisioned_iops = var.boot_disk.initialize_params.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.provisioned_throughput
|
||||
source_image = var.boot_disk.source.image
|
||||
provisioned_iops = var.boot_disk.initialize_params.hyperdisk.provisioned_iops
|
||||
provisioned_throughput = var.boot_disk.initialize_params.hyperdisk.provisioned_throughput
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
source_image = var.boot_disk.initialize_params.image
|
||||
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
kms_key_self_link = try(
|
||||
local.ctx_kms_keys[var.encryption.kms_key_self_link],
|
||||
kms_key_self_link = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
}
|
||||
@@ -307,7 +338,7 @@ resource "google_compute_region_instance_template" "default" {
|
||||
}
|
||||
|
||||
dynamic "confidential_instance_config" {
|
||||
for_each = var.confidential_compute ? [""] : []
|
||||
for_each = var.confidential_compute != null ? [""] : []
|
||||
content {
|
||||
enable_confidential_compute = true
|
||||
}
|
||||
@@ -320,42 +351,47 @@ resource "google_compute_region_instance_template" "default" {
|
||||
count = guest_accelerator.value.count
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "disk" {
|
||||
for_each = local.attached_disks
|
||||
iterator = config
|
||||
for_each = var.attached_disks
|
||||
content {
|
||||
architecture = config.value.options.architecture
|
||||
auto_delete = config.value.options.auto_delete
|
||||
device_name = coalesce(
|
||||
config.value.device_name, config.value.name, config.key
|
||||
architecture = var.boot_disk.architecture
|
||||
auto_delete = disk.value.mode == "READ_ONLY" ? null : disk.value.auto_delete
|
||||
device_name = coalesce(disk.value.device_name, disk.value.name, disk.key)
|
||||
disk_name = (
|
||||
disk.value.source.attach == null
|
||||
? coalesce(disk.value.name, disk.key)
|
||||
: null
|
||||
)
|
||||
mode = disk.value.mode
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
source_image = disk.value.source.image
|
||||
source = disk.value.source.attach
|
||||
type = "PERSISTENT"
|
||||
# Cannot use `source` with any of the fields in
|
||||
# [disk_size_gb disk_name disk_type source_image labels]
|
||||
disk_type = (
|
||||
config.value.source_type != "attach" ? config.value.options.type : null
|
||||
disk.value.source.attach == null
|
||||
? disk.value.initialize_params.type
|
||||
: null
|
||||
)
|
||||
disk_size_gb = (
|
||||
config.value.source_type != "attach" ? config.value.size : null
|
||||
disk.value.source.attach == null
|
||||
? disk.value.initialize_params.size
|
||||
: null
|
||||
)
|
||||
mode = config.value.options.mode
|
||||
provisioned_iops = config.value.options.provisioned_iops
|
||||
provisioned_throughput = config.value.options.provisioned_throughput
|
||||
source_image = (
|
||||
config.value.source_type == "image" ? config.value.source : null
|
||||
provisioned_iops = (
|
||||
disk.value.initialize_params.hyperdisk.provisioned_iops
|
||||
)
|
||||
source = (
|
||||
config.value.source_type == "attach" ? config.value.source : null
|
||||
provisioned_throughput = (
|
||||
disk.value.initialize_params.hyperdisk.provisioned_throughput
|
||||
)
|
||||
disk_name = (
|
||||
config.value.source_type != "attach" ? config.value.name : null
|
||||
)
|
||||
resource_manager_tags = var.tag_bindings_immutable
|
||||
type = "PERSISTENT"
|
||||
dynamic "disk_encryption_key" {
|
||||
for_each = var.encryption != null ? [""] : []
|
||||
content {
|
||||
kms_key_self_link = try(
|
||||
local.ctx_kms_keys[var.encryption.kms_key_self_link],
|
||||
kms_key_self_link = lookup(
|
||||
local.ctx_kms_keys,
|
||||
var.encryption.kms_key_self_link,
|
||||
var.encryption.kms_key_self_link
|
||||
)
|
||||
}
|
||||
@@ -378,8 +414,10 @@ resource "google_compute_region_instance_template" "default" {
|
||||
config.value.addresses.internal,
|
||||
null
|
||||
)
|
||||
nic_type = config.value.nic_type
|
||||
stack_type = config.value.stack_type
|
||||
nic_type = config.value.nic_type
|
||||
stack_type = config.value.stack_type
|
||||
queue_count = config.value.queue_count
|
||||
internal_ipv6_prefix_length = config.value.internal_ipv6_prefix_length
|
||||
dynamic "access_config" {
|
||||
for_each = config.value.nat || config.value.network_tier != null ? [""] : []
|
||||
content {
|
||||
@@ -403,21 +441,34 @@ resource "google_compute_region_instance_template" "default" {
|
||||
}
|
||||
|
||||
scheduling {
|
||||
automatic_restart = !var.options.spot
|
||||
automatic_restart = coalesce(
|
||||
var.scheduling_config.automatic_restart, var.scheduling_config.provisioning_model != "SPOT"
|
||||
)
|
||||
instance_termination_action = local.termination_action
|
||||
on_host_maintenance = local.on_host_maintenance
|
||||
preemptible = var.options.spot
|
||||
provisioning_model = var.options.spot ? "SPOT" : "STANDARD"
|
||||
preemptible = var.scheduling_config.provisioning_model == "SPOT"
|
||||
provisioning_model = coalesce(var.scheduling_config.provisioning_model, "STANDARD")
|
||||
min_node_cpus = var.scheduling_config.min_node_cpus
|
||||
maintenance_interval = var.scheduling_config.maintenance_interval
|
||||
|
||||
dynamic "max_run_duration" {
|
||||
for_each = var.options.max_run_duration == null ? [] : [""]
|
||||
for_each = var.scheduling_config.max_run_duration == null ? [] : [""]
|
||||
content {
|
||||
nanos = var.options.max_run_duration.nanos
|
||||
seconds = var.options.max_run_duration.seconds
|
||||
nanos = var.scheduling_config.max_run_duration.nanos
|
||||
seconds = var.scheduling_config.max_run_duration.seconds
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "local_ssd_recovery_timeout" {
|
||||
for_each = var.scheduling_config.local_ssd_recovery_timeout == null ? [] : [""]
|
||||
content {
|
||||
nanos = var.scheduling_config.local_ssd_recovery_timeout.nanos
|
||||
seconds = var.scheduling_config.local_ssd_recovery_timeout.seconds
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "node_affinities" {
|
||||
for_each = var.options.node_affinities
|
||||
for_each = var.scheduling_config.node_affinities
|
||||
iterator = affinity
|
||||
content {
|
||||
key = affinity.key
|
||||
@@ -427,13 +478,18 @@ resource "google_compute_region_instance_template" "default" {
|
||||
}
|
||||
|
||||
dynamic "graceful_shutdown" {
|
||||
for_each = var.options.graceful_shutdown != null ? [""] : []
|
||||
for_each = var.lifecycle_config.graceful_shutdown != null ? [""] : []
|
||||
content {
|
||||
enabled = var.options.graceful_shutdown.enabled
|
||||
enabled = var.lifecycle_config.graceful_shutdown.enabled
|
||||
dynamic "max_duration" {
|
||||
for_each = var.options.graceful_shutdown.enabled == true && var.options.graceful_shutdown.max_duration_secs != null ? [""] : []
|
||||
for_each = (
|
||||
var.lifecycle_config.graceful_shutdown.enabled == true &&
|
||||
var.lifecycle_config.graceful_shutdown.max_duration_secs != null
|
||||
? [""]
|
||||
: []
|
||||
)
|
||||
content {
|
||||
seconds = var.options.graceful_shutdown.max_duration_secs
|
||||
seconds = var.lifecycle_config.graceful_shutdown.max_duration_secs
|
||||
nanos = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
project_id = "tf-playground-svpc-gce"
|
||||
zone = "europe-west8-b"
|
||||
name = "test-sa"
|
||||
instance_type = "e2-small"
|
||||
network_interfaces = [{
|
||||
network = "https://www.googleapis.com/compute/v1/projects/ldj-dev-net-spoke-0/global/networks/dev-spoke-0"
|
||||
subnetwork = "https://www.googleapis.com/compute/v1/projects/ldj-dev-net-spoke-0/regions/europe-west8/subnetworks/gce"
|
||||
}]
|
||||
# service_account = null
|
||||
@@ -14,110 +14,88 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "attached_disk_defaults" {
|
||||
description = "Defaults for attached disks options."
|
||||
type = object({
|
||||
auto_delete = optional(bool, false)
|
||||
mode = string
|
||||
replica_zone = string
|
||||
type = string
|
||||
})
|
||||
default = {
|
||||
auto_delete = true
|
||||
mode = "READ_WRITE"
|
||||
replica_zone = null
|
||||
type = "pd-balanced"
|
||||
}
|
||||
validation {
|
||||
condition = var.attached_disk_defaults.mode == "READ_WRITE" || !var.attached_disk_defaults.auto_delete
|
||||
error_message = "auto_delete can only be specified on READ_WRITE disks."
|
||||
}
|
||||
}
|
||||
|
||||
variable "attached_disks" {
|
||||
description = "Additional disks, if options is null defaults will be used in its place. Source type is one of 'image' (zonal disks in vms and template), 'snapshot' (vm), 'existing', and null."
|
||||
type = list(object({
|
||||
name = optional(string)
|
||||
device_name = optional(string)
|
||||
# TODO: size can be null when source_type is attach
|
||||
size = string
|
||||
snapshot_schedule = optional(list(string))
|
||||
source = optional(string)
|
||||
source_type = optional(string)
|
||||
options = optional(
|
||||
object({
|
||||
architecture = optional(string)
|
||||
auto_delete = optional(bool, false) # applies only to vm templates
|
||||
mode = optional(string, "READ_WRITE")
|
||||
description = "Additional disks. Source type is one of 'image' (zonal disks in vms and template), 'snapshot' (vm), 'existing', and null."
|
||||
type = map(object({
|
||||
auto_delete = optional(bool, true) # applies only to vm templates
|
||||
device_name = optional(string)
|
||||
force_attach = optional(bool)
|
||||
# auto_delete can only be specified for READ_WRITE, force null otherwise
|
||||
mode = optional(string, "READ_WRITE")
|
||||
name = optional(string)
|
||||
initialize_params = optional(object({
|
||||
replica_zone = optional(string)
|
||||
size = optional(number, 10)
|
||||
type = optional(string, "pd-balanced")
|
||||
hyperdisk = optional(object({
|
||||
provisioned_iops = optional(number)
|
||||
provisioned_throughput = optional(number) # in MiB/s
|
||||
replica_zone = optional(string)
|
||||
storage_pool = optional(string)
|
||||
type = optional(string, "pd-balanced")
|
||||
}),
|
||||
{
|
||||
auto_delete = true
|
||||
mode = "READ_WRITE"
|
||||
replica_zone = null
|
||||
type = "pd-balanced"
|
||||
}
|
||||
)
|
||||
}), {})
|
||||
}), {})
|
||||
snapshot_schedule = optional(list(string))
|
||||
source = optional(object({
|
||||
attach = optional(string)
|
||||
# disk = optional(string)
|
||||
image = optional(string) # not supported yet for repd
|
||||
# instant_snapshot = optional(string)
|
||||
snapshot = optional(string)
|
||||
}), {})
|
||||
}))
|
||||
default = []
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = length([
|
||||
for d in var.attached_disks : d if(
|
||||
d.source_type == null
|
||||
||
|
||||
contains(["image", "snapshot", "attach"], coalesce(d.source_type, "1"))
|
||||
)
|
||||
]) == length(var.attached_disks)
|
||||
error_message = "Source type must be one of 'image', 'snapshot', 'attach', null."
|
||||
}
|
||||
validation {
|
||||
condition = length([
|
||||
for d in var.attached_disks : d if d.options == null ||
|
||||
d.options.mode == "READ_WRITE" || !d.options.auto_delete
|
||||
]) == length(var.attached_disks)
|
||||
error_message = "auto_delete can only be specified on READ_WRITE disks."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for d in var.attached_disks :
|
||||
(d.options.architecture == null || contains(["ARM64", "X86_64"], d.options.architecture))
|
||||
condition = alltrue([
|
||||
for k, v in var.attached_disks :
|
||||
contains(["READ_WRITE", "READ_ONLY"], v.mode)
|
||||
])
|
||||
error_message = "Architecture can be null, 'X86_64' or 'ARM64'."
|
||||
error_message = "Allowed values for 'mode' are 'READ_WRITE', 'READ_ONLY'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "boot_disk" {
|
||||
description = "Boot disk properties. Initialize params are ignored when source is set."
|
||||
description = "Boot disk properties."
|
||||
type = object({
|
||||
name = optional(string)
|
||||
architecture = optional(string)
|
||||
auto_delete = optional(bool, true)
|
||||
force_attach = optional(bool)
|
||||
snapshot_schedule = optional(list(string))
|
||||
source = optional(string)
|
||||
initialize_params = optional(object({
|
||||
architecture = optional(string)
|
||||
image = optional(string, "projects/debian-cloud/global/images/family/debian-11")
|
||||
provisioned_iops = optional(number)
|
||||
provisioned_throughput = optional(number) # in MiB/s
|
||||
size = optional(number, 10)
|
||||
storage_pool = optional(string)
|
||||
type = optional(string, "pd-balanced")
|
||||
size = optional(number, 10)
|
||||
type = optional(string, "pd-balanced")
|
||||
hyperdisk = optional(object({
|
||||
provisioned_iops = optional(number)
|
||||
provisioned_throughput = optional(number) # in MiB/s
|
||||
storage_pool = optional(string)
|
||||
}), {})
|
||||
}), {})
|
||||
use_independent_disk = optional(bool, false)
|
||||
source = optional(object({
|
||||
attach = optional(string)
|
||||
disk = optional(string)
|
||||
image = optional(string)
|
||||
# instant_snapshot = optional(string)
|
||||
snapshot = optional(string)
|
||||
}), { image = "debian-cloud/debian-13" })
|
||||
use_independent_disk = optional(object({
|
||||
name = optional(string)
|
||||
}))
|
||||
})
|
||||
default = {
|
||||
initialize_params = {}
|
||||
}
|
||||
default = {}
|
||||
nullable = false
|
||||
validation {
|
||||
condition = var.boot_disk.source != null || var.boot_disk.initialize_params != null
|
||||
error_message = "You can only have one of boot disk source or initialize params."
|
||||
condition = (
|
||||
var.boot_disk.initialize_params == null ||
|
||||
(
|
||||
var.boot_disk.source.attach == null &&
|
||||
var.boot_disk.source.snapshot == null &&
|
||||
var.boot_disk.source.disk == null
|
||||
)
|
||||
)
|
||||
error_message = "Initialize params cannot be used when attaching an existing disk or creating from a snapshot."
|
||||
}
|
||||
validation {
|
||||
condition = (
|
||||
var.boot_disk.use_independent_disk != true
|
||||
var.boot_disk.use_independent_disk == null
|
||||
||
|
||||
var.boot_disk.initialize_params != null
|
||||
)
|
||||
@@ -125,8 +103,8 @@ variable "boot_disk" {
|
||||
}
|
||||
validation {
|
||||
condition = (
|
||||
var.boot_disk.initialize_params.architecture == null ||
|
||||
contains(["ARM64", "X86_64"], var.boot_disk.initialize_params.architecture)
|
||||
var.boot_disk.architecture == null ||
|
||||
contains(["ARM64", "X86_64"], var.boot_disk.architecture)
|
||||
)
|
||||
error_message = "Architecture can be null, 'X86_64' or 'ARM64'."
|
||||
}
|
||||
@@ -139,9 +117,13 @@ variable "can_ip_forward" {
|
||||
}
|
||||
|
||||
variable "confidential_compute" {
|
||||
description = "Enable Confidential Compute for these instances."
|
||||
type = bool
|
||||
default = false
|
||||
description = "Confidential Compute configuration. Set to 'SEV' or 'SEV_SNP' to enable."
|
||||
type = string
|
||||
default = null
|
||||
validation {
|
||||
condition = var.confidential_compute == null || contains(["SEV", "SEV_SNP"], var.confidential_compute)
|
||||
error_message = "Allowed values are 'SEV' or 'SEV_SNP'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "context" {
|
||||
@@ -184,6 +166,7 @@ variable "enable_display" {
|
||||
|
||||
variable "encryption" {
|
||||
description = "Encryption options. Only one of kms_key_self_link and disk_encryption_key_raw may be set. If needed, you can specify to encrypt or not the boot disk."
|
||||
# TODO: Add validation to enforce exclusivity of kms_key_self_link and disk_encryption_key_raw
|
||||
type = object({
|
||||
encrypt_boot = optional(bool, false)
|
||||
disk_encryption_key_raw = optional(string)
|
||||
@@ -228,9 +211,10 @@ variable "gpu" {
|
||||
}
|
||||
|
||||
variable "group" {
|
||||
description = "Define this variable to create an instance group for instances. Disabled for template use."
|
||||
description = "Instance group configuration. Set 'named_ports' to create a new unmanaged instance group, or provide an existing group self_link/id in 'membership' to join one."
|
||||
type = object({
|
||||
named_ports = map(number)
|
||||
membership = optional(string) # ID of an existing unmanaged group to join
|
||||
named_ports = optional(map(number), {})
|
||||
})
|
||||
default = null
|
||||
}
|
||||
@@ -248,7 +232,7 @@ variable "iam" {
|
||||
}
|
||||
|
||||
variable "instance_schedule" {
|
||||
description = "Assign or create and assign an instance schedule policy. Either resource policy id or create_config must be specified if not null. Set active to null to dtach a policy from vm before destroying."
|
||||
description = "Assign or create and assign an instance schedule policy. Set active to null to detach a policy from vm before destroying."
|
||||
type = object({
|
||||
active = optional(bool, true)
|
||||
description = optional(string)
|
||||
@@ -271,12 +255,6 @@ variable "instance_schedule" {
|
||||
}
|
||||
}
|
||||
|
||||
variable "instance_type" {
|
||||
description = "Instance type."
|
||||
type = string
|
||||
default = "e2-micro"
|
||||
}
|
||||
|
||||
variable "kms_autokeys" {
|
||||
description = "KMS Autokey key handles. If location is not specified it will be inferred from the zone. Key handle names will be added to the kms_keys context with an `autokeys/` prefix."
|
||||
type = map(object({
|
||||
@@ -301,6 +279,58 @@ variable "labels" {
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "lifecycle_config" {
|
||||
description = "Instance lifecycle and operational configurations."
|
||||
type = object({
|
||||
allow_stopping_for_update = optional(bool, true)
|
||||
deletion_protection = optional(bool, false)
|
||||
key_revocation_action_type = optional(string, "NONE")
|
||||
graceful_shutdown = optional(object({
|
||||
enabled = optional(bool, false)
|
||||
max_duration_secs = optional(number)
|
||||
}))
|
||||
})
|
||||
default = {}
|
||||
validation {
|
||||
condition = (
|
||||
var.lifecycle_config.key_revocation_action_type == null || contains(
|
||||
["NONE", "STOP"], var.lifecycle_config.key_revocation_action_type
|
||||
)
|
||||
)
|
||||
error_message = "Allowed values for key_revocation_action_type are 'NONE' or 'STOP'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "machine_features_config" {
|
||||
description = "Machine-level configuration."
|
||||
type = object({
|
||||
enable_nested_virtualization = optional(bool)
|
||||
enable_turbo_mode = optional(bool)
|
||||
enable_uefi_networking = optional(bool)
|
||||
performance_monitoring_unit = optional(string)
|
||||
threads_per_core = optional(number)
|
||||
visible_core_count = optional(number)
|
||||
})
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = (
|
||||
try(var.machine_features_config.performance_monitoring_unit, null) == null ||
|
||||
contains(
|
||||
["ARCHITECTURAL", "ENHANCED", "STANDARD"],
|
||||
coalesce(try(var.machine_features_config.performance_monitoring_unit, null), "-")
|
||||
)
|
||||
)
|
||||
error_message = "Allowed values for performance_monitoring_unit are ARCHITECTURAL', 'ENHANCED', 'STANDARD' and null."
|
||||
}
|
||||
}
|
||||
|
||||
variable "machine_type" {
|
||||
description = "Machine type."
|
||||
type = string
|
||||
default = "e2-micro"
|
||||
}
|
||||
|
||||
variable "metadata" {
|
||||
description = "Instance metadata."
|
||||
type = map(string)
|
||||
@@ -335,17 +365,19 @@ variable "network_attached_interfaces" {
|
||||
variable "network_interfaces" {
|
||||
description = "Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed."
|
||||
type = list(object({
|
||||
network = string
|
||||
subnetwork = string
|
||||
alias_ips = optional(map(string), {})
|
||||
nat = optional(bool, false)
|
||||
nic_type = optional(string)
|
||||
stack_type = optional(string)
|
||||
network = string
|
||||
subnetwork = string
|
||||
alias_ips = optional(map(string), {})
|
||||
nat = optional(bool, false)
|
||||
network_tier = optional(string)
|
||||
nic_type = optional(string)
|
||||
stack_type = optional(string)
|
||||
queue_count = optional(number) # NEW
|
||||
internal_ipv6_prefix_length = optional(number) # NEW
|
||||
addresses = optional(object({
|
||||
internal = optional(string)
|
||||
external = optional(string)
|
||||
}), null)
|
||||
network_tier = optional(string)
|
||||
}))
|
||||
validation {
|
||||
condition = alltrue([for v in var.network_interfaces : contains(["STANDARD", "PREMIUM"], coalesce(v.network_tier, "PREMIUM"))])
|
||||
@@ -353,6 +385,16 @@ variable "network_interfaces" {
|
||||
}
|
||||
}
|
||||
|
||||
variable "network_performance_tier" {
|
||||
description = "Network performance total egress bandwidth tier."
|
||||
type = string
|
||||
default = null
|
||||
validation {
|
||||
condition = var.network_performance_tier == null || contains(["DEFAULT", "TIER_1"], coalesce(var.network_performance_tier, "-"))
|
||||
error_message = "Allowed values are 'DEFAULT' or 'TIER_1'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "network_tag_bindings" {
|
||||
description = "Resource manager tag bindings in arbitrary key => tag key or value id format. Set on both the instance only for networking purposes, and modifiable without impacting the main resource lifecycle."
|
||||
type = map(string)
|
||||
@@ -360,73 +402,6 @@ variable "network_tag_bindings" {
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "options" {
|
||||
description = "Instance options."
|
||||
type = object({
|
||||
advanced_machine_features = optional(object({
|
||||
enable_nested_virtualization = optional(bool)
|
||||
enable_turbo_mode = optional(bool)
|
||||
enable_uefi_networking = optional(bool)
|
||||
performance_monitoring_unit = optional(string)
|
||||
threads_per_core = optional(number)
|
||||
visible_core_count = optional(number)
|
||||
}))
|
||||
allow_stopping_for_update = optional(bool, true)
|
||||
deletion_protection = optional(bool, false)
|
||||
key_revocation_action_type = optional(string)
|
||||
graceful_shutdown = optional(object({
|
||||
enabled = optional(bool, false)
|
||||
max_duration_secs = optional(number)
|
||||
}))
|
||||
max_run_duration = optional(object({
|
||||
nanos = optional(number)
|
||||
seconds = number
|
||||
}))
|
||||
node_affinities = optional(map(object({
|
||||
values = list(string)
|
||||
in = optional(bool, true)
|
||||
})), {})
|
||||
spot = optional(bool, false)
|
||||
termination_action = optional(string)
|
||||
})
|
||||
default = {
|
||||
allow_stopping_for_update = true
|
||||
deletion_protection = false
|
||||
spot = false
|
||||
termination_action = null
|
||||
key_revocation_action_type = "NONE"
|
||||
}
|
||||
validation {
|
||||
condition = (
|
||||
var.options.termination_action == null
|
||||
||
|
||||
contains(["STOP", "DELETE"], coalesce(var.options.termination_action, "1"))
|
||||
)
|
||||
error_message = "Allowed values for options.termination_action are 'STOP', 'DELETE' and null."
|
||||
}
|
||||
validation {
|
||||
condition = (
|
||||
try(var.options.advanced_machine_features.performance_monitoring_unit, null) == null
|
||||
||
|
||||
contains(["ARCHITECTURAL", "ENHANCED", "STANDARD"], coalesce(
|
||||
try(
|
||||
var.options.advanced_machine_features.performance_monitoring_unit, null
|
||||
), "-"
|
||||
)
|
||||
)
|
||||
)
|
||||
error_message = "Allowed values for options.advanced_machine_features.performance_monitoring_unit are ARCHITECTURAL', 'ENHANCED', 'STANDARD' and null."
|
||||
}
|
||||
validation {
|
||||
condition = (
|
||||
var.options.key_revocation_action_type == null
|
||||
||
|
||||
contains(["NONE", "STOP"], var.options.key_revocation_action_type)
|
||||
)
|
||||
error_message = "Allowed values for options.key_revocation_action_type are 'NONE' or 'STOP'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project id."
|
||||
type = string
|
||||
@@ -445,6 +420,41 @@ variable "resource_policies" {
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "scheduling_config" {
|
||||
description = "Scheduling configuration for the instance."
|
||||
type = object({
|
||||
automatic_restart = optional(bool) # Defaults to !spot
|
||||
maintenance_interval = optional(string) # NEW
|
||||
min_node_cpus = optional(number) # NEW
|
||||
on_host_maintenance = optional(string) # Defaults to MIGRATE or TERMINATE based on GPU/Spot
|
||||
provisioning_model = optional(string) # "SPOT" or "STANDARD"
|
||||
termination_action = optional(string)
|
||||
local_ssd_recovery_timeout = optional(object({ # NEW
|
||||
nanos = optional(number)
|
||||
seconds = number
|
||||
}))
|
||||
max_run_duration = optional(object({
|
||||
nanos = optional(number)
|
||||
seconds = number
|
||||
}))
|
||||
node_affinities = optional(map(object({
|
||||
values = list(string)
|
||||
in = optional(bool, true)
|
||||
})), {})
|
||||
})
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = (
|
||||
var.scheduling_config.termination_action == null || contains(
|
||||
["STOP", "DELETE"], coalesce(var.scheduling_config.termination_action, "1"
|
||||
)
|
||||
)
|
||||
)
|
||||
error_message = "Allowed values for termination_action are 'STOP', 'DELETE' and null."
|
||||
}
|
||||
}
|
||||
|
||||
variable "scratch_disks" {
|
||||
description = "Scratch disks configuration."
|
||||
type = object({
|
||||
@@ -457,6 +467,7 @@ variable "scratch_disks" {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
variable "service_account" {
|
||||
description = "Service account email and scopes. If email is null, the default Compute service account will be used unless auto_create is true, in which case a service account will be created. Set the variable to null to avoid attaching a service account."
|
||||
type = object({
|
||||
@@ -467,6 +478,7 @@ variable "service_account" {
|
||||
default = {}
|
||||
}
|
||||
|
||||
|
||||
variable "shielded_config" {
|
||||
description = "Shielded VM configuration of the instances."
|
||||
type = object({
|
||||
|
||||
Reference in New Issue
Block a user