Add support for resource policies to compute vm module (#1467)
* instance schedule * snapshot resource policy variable and resource * tfdoc * snapshot schedules
This commit is contained in:
parent
32b347b104
commit
ce647647cc
|
@ -25,6 +25,8 @@ In both modes, an optional service account can be created and assigned to either
|
|||
- [Disk encryption with Cloud KMS](#disk-encryption-with-cloud-kms)
|
||||
- [Instance template](#instance-template)
|
||||
- [Instance group](#instance-group)
|
||||
- [Instance Schedule](#instance-schedule)
|
||||
- [Snapshot Schedules](#snapshot-schedules)
|
||||
|
||||
### Instance using defaults
|
||||
|
||||
|
@ -500,40 +502,132 @@ module "instance-group" {
|
|||
}
|
||||
# tftest modules=1 resources=2 inventory=group.yaml
|
||||
```
|
||||
|
||||
### Instance Schedule
|
||||
|
||||
Instance start and stop schedules can be defined via an existing or auto-created resource policy.
|
||||
|
||||
To use an existing policy pass its id to the `instance_schedule` variable:
|
||||
|
||||
```hcl
|
||||
module "instance" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = "my-project"
|
||||
zone = "europe-west1-b"
|
||||
name = "schedule-test"
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
instance_schedule = {
|
||||
resource_policy_id = "projects/my-project/regions/europe-west1/resourcePolicies/test"
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1 inventory=instance-schedule-id.yaml
|
||||
```
|
||||
|
||||
To create a new policy set its configuration in the `instance_schedule` variable. When removing the policy follow a two-step process by first setting `active = false` in the schedule configuration, which will unattach the policy, then removing the variable so the policy is destroyed.
|
||||
|
||||
```hcl
|
||||
module "instance" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = "my-project"
|
||||
zone = "europe-west1-b"
|
||||
name = "schedule-test"
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
}
|
||||
instance_schedule = {
|
||||
create_config = {
|
||||
vm_start = "0 8 * * *"
|
||||
vm_stop = "0 17 * * *"
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=2 inventory=instance-schedule-create.yaml
|
||||
```
|
||||
|
||||
### Snapshot Schedules
|
||||
|
||||
Snapshot policies can be attached to disks with optional creation managed by the module.
|
||||
|
||||
```hcl
|
||||
module "instance" {
|
||||
source = "./fabric/modules/compute-vm"
|
||||
project_id = "my-project"
|
||||
zone = "europe-west1-b"
|
||||
name = "schedule-test"
|
||||
network_interfaces = [{
|
||||
network = var.vpc.self_link
|
||||
subnetwork = var.subnet.self_link
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
snapshot_schedule = "boot"
|
||||
}
|
||||
attached_disks = [
|
||||
{
|
||||
name = "disk-1"
|
||||
size = 10
|
||||
snapshot_schedule = "generic-vm"
|
||||
}
|
||||
]
|
||||
snapshot_schedules = {
|
||||
boot = {
|
||||
schedule = {
|
||||
daily = {
|
||||
days_in_cycle = 1
|
||||
start_time = "03:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=5 inventory=snapshot-schedule-create.yaml
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [name](variables.tf#L182) | Instance name. | <code>string</code> | ✓ | |
|
||||
| [network_interfaces](variables.tf#L187) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | <code title="list(object({ nat = optional(bool, false) network = string subnetwork = string addresses = optional(object({ internal = optional(string) external = optional(string) }), null) alias_ips = optional(map(string), {}) nic_type = optional(string) }))">list(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L224) | Project id. | <code>string</code> | ✓ | |
|
||||
| [zone](variables.tf#L283) | Compute zone. | <code>string</code> | ✓ | |
|
||||
| [name](variables.tf#L219) | Instance name. | <code>string</code> | ✓ | |
|
||||
| [network_interfaces](variables.tf#L224) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | <code title="list(object({ nat = optional(bool, false) network = string subnetwork = string addresses = optional(object({ internal = optional(string) external = optional(string) }), null) alias_ips = optional(map(string), {}) nic_type = optional(string) }))">list(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L261) | Project id. | <code>string</code> | ✓ | |
|
||||
| [zone](variables.tf#L363) | 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#L38) | 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 = string device_name = optional(string) size = string source = optional(string) source_type = optional(string) options = optional( object({ auto_delete = optional(bool, false) mode = optional(string, "READ_WRITE") replica_zone = 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#L82) | Boot disk properties. | <code title="object({ auto_delete = optional(bool, true) source = optional(string) initialize_params = optional(object({ image = optional(string, "projects/debian-cloud/global/images/family/debian-11") size = optional(number, 10) type = optional(string, "pd-balanced") })) })">object({…})</code> | | <code title="{ initialize_params = {} }">{…}</code> |
|
||||
| [can_ip_forward](variables.tf#L99) | Enable IP forwarding. | <code>bool</code> | | <code>false</code> |
|
||||
| [confidential_compute](variables.tf#L105) | Enable Confidential Compute for these instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [create_template](variables.tf#L111) | Create instance template instead of instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [description](variables.tf#L116) | Description of a Compute Instance. | <code>string</code> | | <code>"Managed by the compute-vm Terraform module."</code> |
|
||||
| [enable_display](variables.tf#L122) | Enable virtual display on the instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [encryption](variables.tf#L128) | 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> |
|
||||
| [group](variables.tf#L138) | 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#L146) | Instance FQDN name. | <code>string</code> | | <code>null</code> |
|
||||
| [iam](variables.tf#L152) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [instance_type](variables.tf#L158) | Instance type. | <code>string</code> | | <code>"f1-micro"</code> |
|
||||
| [labels](variables.tf#L164) | Instance labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [metadata](variables.tf#L170) | Instance metadata. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [min_cpu_platform](variables.tf#L176) | Minimum CPU platform. | <code>string</code> | | <code>null</code> |
|
||||
| [options](variables.tf#L202) | Instance options. | <code title="object({ allow_stopping_for_update = optional(bool, true) deletion_protection = optional(bool, false) 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 }">{…}</code> |
|
||||
| [scratch_disks](variables.tf#L229) | Scratch disks configuration. | <code title="object({ count = number interface = string })">object({…})</code> | | <code title="{ count = 0 interface = "NVME" }">{…}</code> |
|
||||
| [service_account](variables.tf#L241) | Service account email. Unused if service account is auto-created. | <code>string</code> | | <code>null</code> |
|
||||
| [service_account_create](variables.tf#L247) | Auto-create service account. | <code>bool</code> | | <code>false</code> |
|
||||
| [service_account_scopes](variables.tf#L255) | Scopes applied to service account. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [shielded_config](variables.tf#L261) | Shielded VM configuration of the instances. | <code title="object({ enable_secure_boot = bool enable_vtpm = bool enable_integrity_monitoring = bool })">object({…})</code> | | <code>null</code> |
|
||||
| [tag_bindings](variables.tf#L271) | Tag bindings for this instance, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tags](variables.tf#L277) | Instance network tags for firewall rule targets. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [attached_disks](variables.tf#L38) | 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 = string device_name = optional(string) size = string snapshot_schedule = optional(string) source = optional(string) source_type = optional(string) options = optional( object({ auto_delete = optional(bool, false) mode = optional(string, "READ_WRITE") replica_zone = 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#L83) | Boot disk properties. | <code title="object({ auto_delete = optional(bool, true) snapshot_schedule = optional(string) source = optional(string) initialize_params = optional(object({ image = optional(string, "projects/debian-cloud/global/images/family/debian-11") size = optional(number, 10) type = optional(string, "pd-balanced") })) })">object({…})</code> | | <code title="{ initialize_params = {} }">{…}</code> |
|
||||
| [can_ip_forward](variables.tf#L101) | Enable IP forwarding. | <code>bool</code> | | <code>false</code> |
|
||||
| [confidential_compute](variables.tf#L107) | Enable Confidential Compute for these instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [create_template](variables.tf#L113) | Create instance template instead of instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [description](variables.tf#L118) | Description of a Compute Instance. | <code>string</code> | | <code>"Managed by the compute-vm Terraform module."</code> |
|
||||
| [enable_display](variables.tf#L124) | Enable virtual display on the instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [encryption](variables.tf#L130) | 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> |
|
||||
| [group](variables.tf#L140) | 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#L148) | Instance FQDN name. | <code>string</code> | | <code>null</code> |
|
||||
| [iam](variables.tf#L154) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [instance_schedule](variables.tf#L160) | 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({ resource_policy_id = optional(string) create_config = optional(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#L195) | Instance type. | <code>string</code> | | <code>"f1-micro"</code> |
|
||||
| [labels](variables.tf#L201) | Instance labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [metadata](variables.tf#L207) | Instance metadata. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [min_cpu_platform](variables.tf#L213) | Minimum CPU platform. | <code>string</code> | | <code>null</code> |
|
||||
| [options](variables.tf#L239) | Instance options. | <code title="object({ allow_stopping_for_update = optional(bool, true) deletion_protection = optional(bool, false) 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 }">{…}</code> |
|
||||
| [scratch_disks](variables.tf#L266) | Scratch disks configuration. | <code title="object({ count = number interface = string })">object({…})</code> | | <code title="{ count = 0 interface = "NVME" }">{…}</code> |
|
||||
| [service_account](variables.tf#L278) | Service account email. Unused if service account is auto-created. | <code>string</code> | | <code>null</code> |
|
||||
| [service_account_create](variables.tf#L284) | Auto-create service account. | <code>bool</code> | | <code>false</code> |
|
||||
| [service_account_scopes](variables.tf#L292) | Scopes applied to service account. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [shielded_config](variables.tf#L298) | Shielded VM configuration of the instances. | <code title="object({ enable_secure_boot = bool enable_vtpm = bool enable_integrity_monitoring = bool })">object({…})</code> | | <code>null</code> |
|
||||
| [snapshot_schedules](variables.tf#L308) | 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#L351) | Tag bindings for this instance, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [tags](variables.tf#L357) | Instance network tags for firewall rule targets. | <code>list(string)</code> | | <code>[]</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -133,13 +133,18 @@ resource "google_compute_instance" "default" {
|
|||
enable_display = var.enable_display
|
||||
labels = var.labels
|
||||
metadata = var.metadata
|
||||
resource_policies = local.ischedule_attach
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -152,8 +157,12 @@ resource "google_compute_instance" "default" {
|
|||
for_each = local.attached_disks_regional
|
||||
iterator = config
|
||||
content {
|
||||
device_name = config.value.device_name != null ? config.value.device_name : config.value.name
|
||||
mode = config.value.options.mode
|
||||
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
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/**
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
# tfdoc:file:description Resource policies.
|
||||
|
||||
locals {
|
||||
ischedule = try(var.instance_schedule.create_config, null)
|
||||
ischedule_attach = var.instance_schedule == null ? null : (
|
||||
var.instance_schedule.create_config != null
|
||||
# created policy with optional attach to allow policy destroy
|
||||
? (
|
||||
var.instance_schedule.create_config.active
|
||||
? [google_compute_resource_policy.schedule.0.id]
|
||||
: null
|
||||
)
|
||||
# externally managed policy
|
||||
: [var.instance_schedule.resource_policy_id]
|
||||
)
|
||||
}
|
||||
|
||||
resource "google_compute_resource_policy" "schedule" {
|
||||
count = local.ischedule != null ? 1 : 0
|
||||
project = var.project_id
|
||||
region = substr(var.zone, 0, length(var.zone) - 2)
|
||||
name = var.name
|
||||
description = coalesce(
|
||||
local.ischedule.description, "Schedule policy for ${var.name}."
|
||||
)
|
||||
instance_schedule_policy {
|
||||
expiration_time = local.ischedule.expiration_time
|
||||
start_time = local.ischedule.start_time
|
||||
time_zone = local.ischedule.timezone
|
||||
dynamic "vm_start_schedule" {
|
||||
for_each = local.ischedule.vm_start != null ? [""] : []
|
||||
content {
|
||||
schedule = local.ischedule.vm_start
|
||||
}
|
||||
}
|
||||
dynamic "vm_stop_schedule" {
|
||||
for_each = local.ischedule.vm_stop != null ? [""] : []
|
||||
content {
|
||||
schedule = local.ischedule.vm_stop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_resource_policy" "snapshot" {
|
||||
for_each = var.snapshot_schedules
|
||||
project = var.project_id
|
||||
region = substr(var.zone, 0, length(var.zone) - 2)
|
||||
name = "${var.name}-${each.key}"
|
||||
description = coalesce(
|
||||
each.value.description, "Schedule policy ${each.key} for ${var.name}."
|
||||
)
|
||||
snapshot_schedule_policy {
|
||||
schedule {
|
||||
dynamic "daily_schedule" {
|
||||
for_each = each.value.schedule.daily != null ? [""] : []
|
||||
content {
|
||||
days_in_cycle = each.value.schedule.daily.days_in_cycle
|
||||
start_time = each.value.schedule.daily.start_time
|
||||
}
|
||||
}
|
||||
dynamic "hourly_schedule" {
|
||||
for_each = each.value.schedule.hourly != null ? [""] : []
|
||||
content {
|
||||
hours_in_cycle = each.value.schedule.hourly.hours_in_cycle
|
||||
start_time = each.value.schedule.hourly.start_time
|
||||
}
|
||||
}
|
||||
dynamic "weekly_schedule" {
|
||||
for_each = each.value.schedule.weekly != null ? [""] : []
|
||||
content {
|
||||
dynamic "day_of_weeks" {
|
||||
for_each = each.value.schedule.weekly
|
||||
content {
|
||||
day = day_of_weeks.value.day
|
||||
start_time = day_of_weeks.value.start_time
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dynamic "retention_policy" {
|
||||
for_each = each.value.retention_policy != null ? [""] : []
|
||||
content {
|
||||
max_retention_days = each.value.retention_policy.max_retention_days
|
||||
on_source_disk_delete = (
|
||||
each.value.retention_policy.on_source_disk_delete_keep == false
|
||||
? "APPLY_RETENTION_POLICY"
|
||||
: "KEEP_AUTO_SNAPSHOTS"
|
||||
)
|
||||
}
|
||||
}
|
||||
dynamic "snapshot_properties" {
|
||||
for_each = each.value.snapshot_properties != null ? [""] : []
|
||||
content {
|
||||
labels = each.value.snapshot_properties.labels
|
||||
storage_locations = each.value.snapshot_properties.storage_locations
|
||||
guest_flush = each.value.snapshot_properties.guest_flush
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_disk_resource_policy_attachment" "boot" {
|
||||
count = var.boot_disk.snapshot_schedule != null ? 1 : 0
|
||||
project = var.project_id
|
||||
zone = var.zone
|
||||
name = try(
|
||||
google_compute_resource_policy.snapshot[var.boot_disk.snapshot_schedule].name,
|
||||
var.boot_disk.snapshot_schedule
|
||||
)
|
||||
disk = var.name
|
||||
depends_on = [google_compute_instance.default]
|
||||
}
|
||||
|
||||
resource "google_compute_disk_resource_policy_attachment" "attached" {
|
||||
for_each = {
|
||||
for k, v in local.attached_disks_zonal :
|
||||
k => v if v.snapshot_schedule != null
|
||||
}
|
||||
project = var.project_id
|
||||
zone = var.zone
|
||||
name = try(
|
||||
google_compute_resource_policy.snapshot[each.value.snapshot_schedule].name,
|
||||
each.value.snapshot_schedule
|
||||
)
|
||||
disk = (
|
||||
each.value.source_type == "attach"
|
||||
? each.value.source
|
||||
: google_compute_disk.disks[each.key].name
|
||||
)
|
||||
depends_on = [
|
||||
google_compute_instance.default,
|
||||
google_compute_disk.disks
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_compute_region_disk_resource_policy_attachment" "attached" {
|
||||
for_each = {
|
||||
for k, v in local.attached_disks_regional :
|
||||
k => v if v.snapshot_schedule != null
|
||||
}
|
||||
project = var.project_id
|
||||
region = substr(var.zone, 0, length(var.zone) - 2)
|
||||
name = try(
|
||||
google_compute_resource_policy.snapshot[each.value.snapshot_schedule].name,
|
||||
each.value.snapshot_schedule
|
||||
)
|
||||
disk = (
|
||||
each.value.source_type == "attach"
|
||||
? each.value.source
|
||||
: google_compute_region_disk.disks[each.key].name
|
||||
)
|
||||
depends_on = [
|
||||
google_compute_instance.default,
|
||||
google_compute_region_disk.disks
|
||||
]
|
||||
}
|
|
@ -14,6 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
# tfdoc:file:description Tag bindings.
|
||||
|
||||
resource "google_tags_tag_binding" "binding" {
|
||||
for_each = var.create_template ? {} : coalesce(var.tag_bindings, {})
|
||||
parent = "//compute.googleapis.com/${google_compute_instance.default.0.id}"
|
||||
|
|
|
@ -38,11 +38,12 @@ variable "attached_disk_defaults" {
|
|||
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 = string
|
||||
device_name = optional(string)
|
||||
size = string
|
||||
source = optional(string)
|
||||
source_type = optional(string)
|
||||
name = string
|
||||
device_name = optional(string)
|
||||
size = string
|
||||
snapshot_schedule = optional(string)
|
||||
source = optional(string)
|
||||
source_type = optional(string)
|
||||
options = optional(
|
||||
object({
|
||||
auto_delete = optional(bool, false)
|
||||
|
@ -82,8 +83,9 @@ variable "attached_disks" {
|
|||
variable "boot_disk" {
|
||||
description = "Boot disk properties."
|
||||
type = object({
|
||||
auto_delete = optional(bool, true)
|
||||
source = optional(string)
|
||||
auto_delete = optional(bool, true)
|
||||
snapshot_schedule = optional(string)
|
||||
source = optional(string)
|
||||
initialize_params = optional(object({
|
||||
image = optional(string, "projects/debian-cloud/global/images/family/debian-11")
|
||||
size = optional(number, 10)
|
||||
|
@ -155,6 +157,41 @@ variable "iam" {
|
|||
default = {}
|
||||
}
|
||||
|
||||
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."
|
||||
type = object({
|
||||
resource_policy_id = optional(string)
|
||||
create_config = optional(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)
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
validation {
|
||||
condition = (
|
||||
var.instance_schedule == null ||
|
||||
try(var.instance_schedule.resource_policy_id, null) != null ||
|
||||
try(var.instance_schedule.create_config, null) != null
|
||||
)
|
||||
error_message = "A resource policy name or configuration must be specified when not null."
|
||||
}
|
||||
validation {
|
||||
condition = (
|
||||
try(var.instance_schedule.create_config, null) == null ||
|
||||
length(compact([
|
||||
try(var.instance_schedule.create_config.vm_start, null),
|
||||
try(var.instance_schedule.create_config.vm_stop, null)
|
||||
])) > 0
|
||||
)
|
||||
error_message = "A resource policy configuration must contain at least one schedule."
|
||||
}
|
||||
}
|
||||
|
||||
variable "instance_type" {
|
||||
description = "Instance type."
|
||||
type = string
|
||||
|
@ -268,6 +305,49 @@ variable "shielded_config" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "snapshot_schedules" {
|
||||
description = "Snapshot schedule resource policies that can be attached to disks."
|
||||
type = 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))
|
||||
}))
|
||||
}))
|
||||
nullable = false
|
||||
default = {}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in var.snapshot_schedules : (
|
||||
(v.schedule.daily != null ? 1 : 0) +
|
||||
(v.schedule.hourly != null ? 1 : 0) +
|
||||
(v.schedule.weekly != null ? 1 : 0)
|
||||
) == 1
|
||||
])
|
||||
error_message = "Schedule must contain exactly one of daily, hourly, or weekly schedule."
|
||||
}
|
||||
}
|
||||
|
||||
variable "tag_bindings" {
|
||||
description = "Tag bindings for this instance, in key => tag value id format."
|
||||
type = map(string)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.instance.google_compute_resource_policy.schedule[0]:
|
||||
description: Schedule policy for schedule-test.
|
||||
instance_schedule_policy:
|
||||
- expiration_time: null
|
||||
start_time: null
|
||||
time_zone: UTC
|
||||
vm_start_schedule:
|
||||
- schedule: 0 8 * * *
|
||||
vm_stop_schedule:
|
||||
- schedule: 0 17 * * *
|
||||
name: schedule-test
|
||||
region: europe-west1
|
||||
|
||||
counts:
|
||||
google_compute_instance: 1
|
||||
google_compute_resource_policy: 1
|
|
@ -0,0 +1,21 @@
|
|||
# Copyright 2023 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.
|
||||
|
||||
values:
|
||||
module.instance.google_compute_instance.default[0]:
|
||||
resource_policies:
|
||||
- projects/my-project/regions/europe-west1/resourcePolicies/test
|
||||
|
||||
counts:
|
||||
google_compute_instance: 1
|
|
@ -0,0 +1,19 @@
|
|||
# Copyright 2023 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.
|
||||
|
||||
counts:
|
||||
google_compute_disk: 1
|
||||
google_compute_disk_resource_policy_attachment: 2
|
||||
google_compute_instance: 1
|
||||
google_compute_resource_policy: 1
|
Loading…
Reference in New Issue