From 13d19ca8eb1de5352c195933ff67c1db3340f1b0 Mon Sep 17 00:00:00 2001
From: frits-v <4488681+frits-v@users.noreply.github.com>
Date: Tue, 9 Dec 2025 08:59:08 -0800
Subject: [PATCH] feat(compute-mig): add instance_lifecycle_policy support
(#3577)
Fixes #3576
---
modules/compute-mig/README.md | 25 +++++++++++++------------
modules/compute-mig/main.tf | 24 ++++++++++++++++++++++++
modules/compute-mig/variables.tf | 21 +++++++++++++++++++++
3 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/modules/compute-mig/README.md b/modules/compute-mig/README.md
index dae1d76e8..83545289f 100644
--- a/modules/compute-mig/README.md
+++ b/modules/compute-mig/README.md
@@ -465,10 +465,10 @@ module "nginx-mig" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [instance_template](variables.tf#L191) | Instance template for the default version. | string | ✓ | |
-| [location](variables.tf#L196) | Compute zone or region. | string | ✓ | |
-| [name](variables.tf#L201) | Managed group name. | string | ✓ | |
-| [project_id](variables.tf#L212) | Project id. | string | ✓ | |
+| [instance_template](variables.tf#L212) | Instance template for the default version. | string | ✓ | |
+| [location](variables.tf#L217) | Compute zone or region. | string | ✓ | |
+| [name](variables.tf#L222) | Managed group name. | string | ✓ | |
+| [project_id](variables.tf#L233) | Project id. | string | ✓ | |
| [all_instances_config](variables.tf#L17) | Metadata and labels set to all instances in the group. | object({…}) | | null |
| [auto_healing_policies](variables.tf#L26) | Auto-healing policies for this group. | object({…}) | | null |
| [autoscaler_config](variables.tf#L35) | Optional autoscaler configuration. | object({…}) | | null |
@@ -477,14 +477,15 @@ module "nginx-mig" {
| [distribution_policy](variables.tf#L95) | Distribution policy for regional MIG. | object({…}) | | null |
| [health_check_config](variables.tf#L104) | Optional auto-created health check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | object({…}) | | null |
| [instance_flexibility_policy_selections](variables.tf#L177) | Instance flexibility policy selections. Only applicable to regional instances. | map(object({…})) | | {} |
-| [named_ports](variables.tf#L206) | Named ports. | map(number) | | null |
-| [stateful_config](variables.tf#L217) | Stateful configuration for individual instances. | map(object({…})) | | {} |
-| [stateful_disks](variables.tf#L236) | Stateful disk configuration applied at the MIG level to all instances, in device name => on permanent instance delete rule as boolean. | map(bool) | | {} |
-| [target_pools](variables.tf#L243) | Optional list of URLs for target pools to which new instances in the group are added. | list(string) | | [] |
-| [target_size](variables.tf#L249) | Group target size, leave null when using an autoscaler. | number | | null |
-| [update_policy](variables.tf#L255) | Update policy. Minimal action and type are required. | object({…}) | | null |
-| [versions](variables.tf#L276) | Additional application versions, target_size is optional. | map(object({…})) | | {} |
-| [wait_for_instances](variables.tf#L289) | Wait for all instances to be created/updated before returning. | object({…}) | | null |
+| [instance_lifecycle_policy](variables.tf#L191) | The instance lifecycle policy for the MIG. | object({…}) | | null |
+| [named_ports](variables.tf#L227) | Named ports. | map(number) | | null |
+| [stateful_config](variables.tf#L238) | Stateful configuration for individual instances. | map(object({…})) | | {} |
+| [stateful_disks](variables.tf#L257) | Stateful disk configuration applied at the MIG level to all instances, in device name => on permanent instance delete rule as boolean. | map(bool) | | {} |
+| [target_pools](variables.tf#L264) | Optional list of URLs for target pools to which new instances in the group are added. | list(string) | | [] |
+| [target_size](variables.tf#L270) | Group target size, leave null when using an autoscaler. | number | | null |
+| [update_policy](variables.tf#L276) | Update policy. Minimal action and type are required. | object({…}) | | null |
+| [versions](variables.tf#L297) | Additional application versions, target_size is optional. | map(object({…})) | | {} |
+| [wait_for_instances](variables.tf#L310) | Wait for all instances to be created/updated before returning. | object({…}) | | null |
## Outputs
diff --git a/modules/compute-mig/main.tf b/modules/compute-mig/main.tf
index c9328b3c4..7a914dcc2 100644
--- a/modules/compute-mig/main.tf
+++ b/modules/compute-mig/main.tf
@@ -36,6 +36,15 @@ resource "google_compute_instance_group_manager" "default" {
wait_for_instances = try(var.wait_for_instances.enabled, null)
wait_for_instances_status = try(var.wait_for_instances.status, null)
+ dynamic "instance_lifecycle_policy" {
+ for_each = var.instance_lifecycle_policy == null ? [] : [""]
+ content {
+ default_action_on_failure = try(var.instance_lifecycle_policy.default_action_on_failure, null)
+ force_update_on_repair = try(var.instance_lifecycle_policy.on_repair.force_update, null)
+ on_failed_health_check = try(var.instance_lifecycle_policy.on_failed_health_check, null)
+ }
+ }
+
dynamic "all_instances_config" {
for_each = var.all_instances_config == null ? [] : [""]
content {
@@ -126,6 +135,21 @@ resource "google_compute_region_instance_group_manager" "default" {
wait_for_instances = try(var.wait_for_instances.enabled, null)
wait_for_instances_status = try(var.wait_for_instances.status, null)
+ dynamic "instance_lifecycle_policy" {
+ for_each = var.instance_lifecycle_policy == null ? [] : [""]
+ content {
+ default_action_on_failure = try(var.instance_lifecycle_policy.default_action_on_failure, null)
+ force_update_on_repair = try(var.instance_lifecycle_policy.on_repair.force_update, null)
+ on_failed_health_check = try(var.instance_lifecycle_policy.on_failed_health_check, null)
+ dynamic "on_repair" {
+ for_each = try(var.instance_lifecycle_policy.on_repair, null) == null ? [] : [""]
+ content {
+ allow_changing_zone = try(var.instance_lifecycle_policy.on_repair, null)
+ }
+ }
+ }
+ }
+
dynamic "all_instances_config" {
for_each = var.all_instances_config == null ? [] : [""]
content {
diff --git a/modules/compute-mig/variables.tf b/modules/compute-mig/variables.tf
index f36abb732..7815aebe4 100644
--- a/modules/compute-mig/variables.tf
+++ b/modules/compute-mig/variables.tf
@@ -188,6 +188,27 @@ variable "instance_flexibility_policy_selections" {
}
}
+variable "instance_lifecycle_policy" {
+ description = "The instance lifecycle policy for the MIG."
+ type = object({
+ default_action_on_failure = optional(string)
+ on_failed_health_check = optional(string)
+ on_repair = optional(object({
+ allow_changing_zone = optional(string)
+ force_update = optional(string)
+ }))
+ })
+ default = null
+ nullable = true
+ validation {
+ condition = (
+ try(var.instance_lifecycle_policy.on_repair.allow_changing_zone, null) == null
+ || length(split("-", var.location)) == 2
+ )
+ error_message = "Allow changing zone on repair is only supported for regional MIGs."
+ }
+}
+
variable "instance_template" {
description = "Instance template for the default version."
type = string