From acb8692f0a1bc9dbfaf440fda5b6b11ff97eacbd Mon Sep 17 00:00:00 2001 From: Antoine Meausoone <592978+Ameausoone@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:48:03 +0100 Subject: [PATCH] feat(backup): add GKE backup configuration variables Introduce new variables for GKE backup configuration, including `backup_cron_schedule`, `backup_rpo_target_in_minutes`, `backup_config`, and `backup_retain_days`. These new settings enable backup schedule definition, RPO configuration, volume data and secrets backup options, and backup retention period definition. --- README.md | 4 ++ autogen/main/backup.tf.tmpl | 36 ++++++++++++++++++ autogen/main/variables.tf.tmpl | 38 +++++++++++++++++++ backup.tf | 37 ++++++++++++++++++ .../beta-autopilot-private-cluster/README.md | 4 ++ .../beta-autopilot-private-cluster/backup.tf | 37 ++++++++++++++++++ .../variables.tf | 38 +++++++++++++++++++ .../beta-autopilot-public-cluster/README.md | 4 ++ .../beta-autopilot-public-cluster/backup.tf | 37 ++++++++++++++++++ .../variables.tf | 38 +++++++++++++++++++ .../README.md | 4 ++ .../backup.tf | 37 ++++++++++++++++++ .../variables.tf | 38 +++++++++++++++++++ modules/beta-private-cluster/README.md | 4 ++ modules/beta-private-cluster/backup.tf | 37 ++++++++++++++++++ modules/beta-private-cluster/variables.tf | 38 +++++++++++++++++++ .../README.md | 4 ++ .../backup.tf | 37 ++++++++++++++++++ .../variables.tf | 38 +++++++++++++++++++ modules/beta-public-cluster/README.md | 4 ++ modules/beta-public-cluster/backup.tf | 37 ++++++++++++++++++ modules/beta-public-cluster/variables.tf | 38 +++++++++++++++++++ .../private-cluster-update-variant/README.md | 4 ++ .../private-cluster-update-variant/backup.tf | 37 ++++++++++++++++++ .../variables.tf | 38 +++++++++++++++++++ modules/private-cluster/README.md | 4 ++ modules/private-cluster/backup.tf | 37 ++++++++++++++++++ modules/private-cluster/variables.tf | 38 +++++++++++++++++++ variables.tf | 38 +++++++++++++++++++ 29 files changed, 785 insertions(+) create mode 100644 autogen/main/backup.tf.tmpl create mode 100644 backup.tf create mode 100644 modules/beta-autopilot-private-cluster/backup.tf create mode 100644 modules/beta-autopilot-public-cluster/backup.tf create mode 100644 modules/beta-private-cluster-update-variant/backup.tf create mode 100644 modules/beta-private-cluster/backup.tf create mode 100644 modules/beta-public-cluster-update-variant/backup.tf create mode 100644 modules/beta-public-cluster/backup.tf create mode 100644 modules/private-cluster-update-variant/backup.tf create mode 100644 modules/private-cluster/backup.tf diff --git a/README.md b/README.md index 22c14254b..870bbd4a5 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | additive\_vpc\_scope\_dns\_domain | This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work cluster\_dns = `CLOUD_DNS` and cluster\_dns\_scope = `CLUSTER_SCOPE` must both be set as well. | `string` | `""` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cluster\_autoscaling | Cluster autoscaling configuration. See [more details](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#clusterautoscaling) |
object({
enabled = bool
autoscaling_profile = string
min_cpu_cores = number
max_cpu_cores = number
min_memory_gb = number
max_memory_gb = number
gpu_resources = list(object({ resource_type = string, minimum = number, maximum = number }))
auto_repair = bool
auto_upgrade = bool
disk_size = optional(number)
disk_type = optional(string)
image_type = optional(string)
strategy = optional(string)
max_surge = optional(number)
max_unavailable = optional(number)
node_pool_soak_duration = optional(string)
batch_soak_duration = optional(string)
batch_percentage = optional(number)
batch_node_count = optional(number)
enable_secure_boot = optional(bool, false)
enable_integrity_monitoring = optional(bool, true)
})
|
{
"auto_repair": true,
"auto_upgrade": true,
"autoscaling_profile": "BALANCED",
"disk_size": 100,
"disk_type": "pd-standard",
"enable_integrity_monitoring": true,
"enable_secure_boot": false,
"enabled": false,
"gpu_resources": [],
"image_type": "COS_CONTAINERD",
"max_cpu_cores": 0,
"max_memory_gb": 0,
"min_cpu_cores": 0,
"min_memory_gb": 0
}
| no | | cluster\_dns\_domain | The suffix used for all cluster service records. | `string` | `""` | no | diff --git a/autogen/main/backup.tf.tmpl b/autogen/main/backup.tf.tmpl new file mode 100644 index 000000000..7aee37c68 --- /dev/null +++ b/autogen/main/backup.tf.tmpl @@ -0,0 +1,36 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule ==null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/autogen/main/variables.tf.tmpl b/autogen/main/variables.tf.tmpl index c7f85ea6a..b73ac69f8 100644 --- a/autogen/main/variables.tf.tmpl +++ b/autogen/main/variables.tf.tmpl @@ -822,6 +822,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/backup.tf b/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/beta-autopilot-private-cluster/README.md b/modules/beta-autopilot-private-cluster/README.md index 75e5b470b..497554fae 100644 --- a/modules/beta-autopilot-private-cluster/README.md +++ b/modules/beta-autopilot-private-cluster/README.md @@ -77,6 +77,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | allow\_net\_admin | (Optional) Enable NET\_ADMIN for the cluster. | `bool` | `null` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cluster\_ipv4\_cidr | The IP address range of the kubernetes pods in this cluster. Default is an automatically assigned CIDR. | `string` | `null` | no | | cluster\_resource\_labels | The GCE resource labels (a map of key/value pairs) to be applied to the cluster | `map(string)` | `{}` | no | diff --git a/modules/beta-autopilot-private-cluster/backup.tf b/modules/beta-autopilot-private-cluster/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/beta-autopilot-private-cluster/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/beta-autopilot-private-cluster/variables.tf b/modules/beta-autopilot-private-cluster/variables.tf index 6e71292b8..e1942aa12 100644 --- a/modules/beta-autopilot-private-cluster/variables.tf +++ b/modules/beta-autopilot-private-cluster/variables.tf @@ -495,6 +495,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/modules/beta-autopilot-public-cluster/README.md b/modules/beta-autopilot-public-cluster/README.md index 9161fac80..ab001e8a1 100644 --- a/modules/beta-autopilot-public-cluster/README.md +++ b/modules/beta-autopilot-public-cluster/README.md @@ -72,6 +72,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | allow\_net\_admin | (Optional) Enable NET\_ADMIN for the cluster. | `bool` | `null` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cluster\_ipv4\_cidr | The IP address range of the kubernetes pods in this cluster. Default is an automatically assigned CIDR. | `string` | `null` | no | | cluster\_resource\_labels | The GCE resource labels (a map of key/value pairs) to be applied to the cluster | `map(string)` | `{}` | no | diff --git a/modules/beta-autopilot-public-cluster/backup.tf b/modules/beta-autopilot-public-cluster/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/beta-autopilot-public-cluster/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/beta-autopilot-public-cluster/variables.tf b/modules/beta-autopilot-public-cluster/variables.tf index 470009e33..adde72bcf 100644 --- a/modules/beta-autopilot-public-cluster/variables.tf +++ b/modules/beta-autopilot-public-cluster/variables.tf @@ -459,6 +459,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/modules/beta-private-cluster-update-variant/README.md b/modules/beta-private-cluster-update-variant/README.md index 4c4da6a7e..8b841307a 100644 --- a/modules/beta-private-cluster-update-variant/README.md +++ b/modules/beta-private-cluster-update-variant/README.md @@ -174,6 +174,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | additive\_vpc\_scope\_dns\_domain | This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work cluster\_dns = `CLOUD_DNS` and cluster\_dns\_scope = `CLUSTER_SCOPE` must both be set as well. | `string` | `""` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cloudrun | (Beta) Enable CloudRun addon | `bool` | `false` | no | | cloudrun\_load\_balancer\_type | (Beta) Configure the Cloud Run load balancer type. External by default. Set to `LOAD_BALANCER_TYPE_INTERNAL` to configure as an internal load balancer. | `string` | `""` | no | diff --git a/modules/beta-private-cluster-update-variant/backup.tf b/modules/beta-private-cluster-update-variant/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/beta-private-cluster-update-variant/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/beta-private-cluster-update-variant/variables.tf b/modules/beta-private-cluster-update-variant/variables.tf index 0dbb0d64e..1d64c54d0 100644 --- a/modules/beta-private-cluster-update-variant/variables.tf +++ b/modules/beta-private-cluster-update-variant/variables.tf @@ -788,6 +788,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/modules/beta-private-cluster/README.md b/modules/beta-private-cluster/README.md index b48fd2786..45ce71819 100644 --- a/modules/beta-private-cluster/README.md +++ b/modules/beta-private-cluster/README.md @@ -152,6 +152,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | additive\_vpc\_scope\_dns\_domain | This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work cluster\_dns = `CLOUD_DNS` and cluster\_dns\_scope = `CLUSTER_SCOPE` must both be set as well. | `string` | `""` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cloudrun | (Beta) Enable CloudRun addon | `bool` | `false` | no | | cloudrun\_load\_balancer\_type | (Beta) Configure the Cloud Run load balancer type. External by default. Set to `LOAD_BALANCER_TYPE_INTERNAL` to configure as an internal load balancer. | `string` | `""` | no | diff --git a/modules/beta-private-cluster/backup.tf b/modules/beta-private-cluster/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/beta-private-cluster/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/beta-private-cluster/variables.tf b/modules/beta-private-cluster/variables.tf index 0dbb0d64e..1d64c54d0 100644 --- a/modules/beta-private-cluster/variables.tf +++ b/modules/beta-private-cluster/variables.tf @@ -788,6 +788,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/modules/beta-public-cluster-update-variant/README.md b/modules/beta-public-cluster-update-variant/README.md index bfb0e162f..13c1218da 100644 --- a/modules/beta-public-cluster-update-variant/README.md +++ b/modules/beta-public-cluster-update-variant/README.md @@ -169,6 +169,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | additive\_vpc\_scope\_dns\_domain | This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work cluster\_dns = `CLOUD_DNS` and cluster\_dns\_scope = `CLUSTER_SCOPE` must both be set as well. | `string` | `""` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cloudrun | (Beta) Enable CloudRun addon | `bool` | `false` | no | | cloudrun\_load\_balancer\_type | (Beta) Configure the Cloud Run load balancer type. External by default. Set to `LOAD_BALANCER_TYPE_INTERNAL` to configure as an internal load balancer. | `string` | `""` | no | diff --git a/modules/beta-public-cluster-update-variant/backup.tf b/modules/beta-public-cluster-update-variant/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/beta-public-cluster-update-variant/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/beta-public-cluster-update-variant/variables.tf b/modules/beta-public-cluster-update-variant/variables.tf index 972309520..b1f63c5aa 100644 --- a/modules/beta-public-cluster-update-variant/variables.tf +++ b/modules/beta-public-cluster-update-variant/variables.tf @@ -752,6 +752,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/modules/beta-public-cluster/README.md b/modules/beta-public-cluster/README.md index e6e879034..e7254b14f 100644 --- a/modules/beta-public-cluster/README.md +++ b/modules/beta-public-cluster/README.md @@ -147,6 +147,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | additive\_vpc\_scope\_dns\_domain | This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work cluster\_dns = `CLOUD_DNS` and cluster\_dns\_scope = `CLUSTER_SCOPE` must both be set as well. | `string` | `""` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cloudrun | (Beta) Enable CloudRun addon | `bool` | `false` | no | | cloudrun\_load\_balancer\_type | (Beta) Configure the Cloud Run load balancer type. External by default. Set to `LOAD_BALANCER_TYPE_INTERNAL` to configure as an internal load balancer. | `string` | `""` | no | diff --git a/modules/beta-public-cluster/backup.tf b/modules/beta-public-cluster/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/beta-public-cluster/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/beta-public-cluster/variables.tf b/modules/beta-public-cluster/variables.tf index 972309520..b1f63c5aa 100644 --- a/modules/beta-public-cluster/variables.tf +++ b/modules/beta-public-cluster/variables.tf @@ -752,6 +752,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/modules/private-cluster-update-variant/README.md b/modules/private-cluster-update-variant/README.md index 670b8db6c..cde8d9fa2 100644 --- a/modules/private-cluster-update-variant/README.md +++ b/modules/private-cluster-update-variant/README.md @@ -171,6 +171,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | additive\_vpc\_scope\_dns\_domain | This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work cluster\_dns = `CLOUD_DNS` and cluster\_dns\_scope = `CLUSTER_SCOPE` must both be set as well. | `string` | `""` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cluster\_autoscaling | Cluster autoscaling configuration. See [more details](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#clusterautoscaling) |
object({
enabled = bool
autoscaling_profile = string
min_cpu_cores = number
max_cpu_cores = number
min_memory_gb = number
max_memory_gb = number
gpu_resources = list(object({ resource_type = string, minimum = number, maximum = number }))
auto_repair = bool
auto_upgrade = bool
disk_size = optional(number)
disk_type = optional(string)
image_type = optional(string)
strategy = optional(string)
max_surge = optional(number)
max_unavailable = optional(number)
node_pool_soak_duration = optional(string)
batch_soak_duration = optional(string)
batch_percentage = optional(number)
batch_node_count = optional(number)
enable_secure_boot = optional(bool, false)
enable_integrity_monitoring = optional(bool, true)
})
|
{
"auto_repair": true,
"auto_upgrade": true,
"autoscaling_profile": "BALANCED",
"disk_size": 100,
"disk_type": "pd-standard",
"enable_integrity_monitoring": true,
"enable_secure_boot": false,
"enabled": false,
"gpu_resources": [],
"image_type": "COS_CONTAINERD",
"max_cpu_cores": 0,
"max_memory_gb": 0,
"min_cpu_cores": 0,
"min_memory_gb": 0
}
| no | | cluster\_dns\_domain | The suffix used for all cluster service records. | `string` | `""` | no | diff --git a/modules/private-cluster-update-variant/backup.tf b/modules/private-cluster-update-variant/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/private-cluster-update-variant/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/private-cluster-update-variant/variables.tf b/modules/private-cluster-update-variant/variables.tf index ba5b694e7..8bca33b7e 100644 --- a/modules/private-cluster-update-variant/variables.tf +++ b/modules/private-cluster-update-variant/variables.tf @@ -770,6 +770,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/modules/private-cluster/README.md b/modules/private-cluster/README.md index 1bd34d556..b3fa5d3f7 100644 --- a/modules/private-cluster/README.md +++ b/modules/private-cluster/README.md @@ -149,6 +149,10 @@ Then perform the following commands on the root folder: | additional\_ip\_range\_pods | List of _names_ of the additional secondary subnet ip ranges to use for pods | `list(string)` | `[]` | no | | additive\_vpc\_scope\_dns\_domain | This will enable Cloud DNS additive VPC scope. Must provide a domain name that is unique within the VPC. For this to work cluster\_dns = `CLOUD_DNS` and cluster\_dns\_scope = `CLUSTER_SCOPE` must both be set as well. | `string` | `""` | no | | authenticator\_security\_group | The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com | `string` | `null` | no | +| backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. |
object({
include_volume_data = optional(bool)
include_secrets = optional(bool)
})
|
{
"include_secrets": true,
"include_volume_data": true
}
| no | +| backup\_cron\_schedule | Defines the GKE backup schedule. Mutually exclusive with backup\_rpo\_target\_in\_minutes; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `string` | `null` | no | +| backup\_retain\_days | The number of days to retain backups. Must be between 1 and 35. Defaults to 7. | `number` | `7` | no | +| backup\_rpo\_target\_in\_minutes | Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup\_cron\_schedule; backup\_cron\_schedule takes precedence if both are set. Configure at least one to enable backup. | `number` | `null` | no | | boot\_disk\_kms\_key | The Customer Managed Encryption Key used to encrypt the boot disk attached to each node in the node pool, if not overridden in `node_pools`. This should be of the form projects/[KEY\_PROJECT\_ID]/locations/[LOCATION]/keyRings/[RING\_NAME]/cryptoKeys/[KEY\_NAME]. For more information about protecting resources with Cloud KMS Keys please see: https://cloud.google.com/compute/docs/disks/customer-managed-encryption | `string` | `null` | no | | cluster\_autoscaling | Cluster autoscaling configuration. See [more details](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters#clusterautoscaling) |
object({
enabled = bool
autoscaling_profile = string
min_cpu_cores = number
max_cpu_cores = number
min_memory_gb = number
max_memory_gb = number
gpu_resources = list(object({ resource_type = string, minimum = number, maximum = number }))
auto_repair = bool
auto_upgrade = bool
disk_size = optional(number)
disk_type = optional(string)
image_type = optional(string)
strategy = optional(string)
max_surge = optional(number)
max_unavailable = optional(number)
node_pool_soak_duration = optional(string)
batch_soak_duration = optional(string)
batch_percentage = optional(number)
batch_node_count = optional(number)
enable_secure_boot = optional(bool, false)
enable_integrity_monitoring = optional(bool, true)
})
|
{
"auto_repair": true,
"auto_upgrade": true,
"autoscaling_profile": "BALANCED",
"disk_size": 100,
"disk_type": "pd-standard",
"enable_integrity_monitoring": true,
"enable_secure_boot": false,
"enabled": false,
"gpu_resources": [],
"image_type": "COS_CONTAINERD",
"max_cpu_cores": 0,
"max_memory_gb": 0,
"min_cpu_cores": 0,
"min_memory_gb": 0
}
| no | | cluster\_dns\_domain | The suffix used for all cluster service records. | `string` | `""` | no | diff --git a/modules/private-cluster/backup.tf b/modules/private-cluster/backup.tf new file mode 100644 index 000000000..f8549a4ff --- /dev/null +++ b/modules/private-cluster/backup.tf @@ -0,0 +1,37 @@ +resource "google_gke_backup_backup_plan" "backup" { + count = (var.backup_cron_schedule != null || var.backup_rpo_target_in_minutes != null) && var.gke_backup_agent_config ? 1 : 0 + + # Plan name and cluster identification + name = "${google_container_cluster.primary.name}-backup-plan" + cluster = google_container_cluster.primary.id + + # Location (fallback to region or derived from zones) + location = try(var.region, substr(var.zones[0], 0, length(var.zones[0]) - 2)) + + backup_config { + include_volume_data = try(var.backup_config.include_volume_data, true) + include_secrets = try(var.backup_config.include_secrets, true) + all_namespaces = true + } + + dynamic "backup_schedule" { + for_each = var.backup_cron_schedule != null ? [var.backup_cron_schedule] : [] + content { + cron_schedule = backup_schedule.value + } + } + + dynamic "backup_schedule" { + # If both backup_schedule and rpo_config are specified, backup_schedule have the precedence + for_each = var.backup_rpo_target_in_minutes != null && var.backup_cron_schedule == null ? [var.backup_rpo_target_in_minutes] : [] + content { + rpo_config { + target_rpo_minutes = backup_schedule.value + } + } + } + + retention_policy { + backup_retain_days = var.backup_retain_days + } +} \ No newline at end of file diff --git a/modules/private-cluster/variables.tf b/modules/private-cluster/variables.tf index ba5b694e7..8bca33b7e 100644 --- a/modules/private-cluster/variables.tf +++ b/modules/private-cluster/variables.tf @@ -770,6 +770,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster." diff --git a/variables.tf b/variables.tf index 7bec53d7c..02b5535d3 100644 --- a/variables.tf +++ b/variables.tf @@ -734,6 +734,44 @@ variable "gke_backup_agent_config" { default = false } +variable "backup_cron_schedule" { + description = "Defines the GKE backup schedule. Mutually exclusive with backup_rpo_target_in_minutes; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = string + default = null +} + +variable "backup_rpo_target_in_minutes" { + description = "Configuration for Recovery Point Objective (RPO), specifying the target RPO in minutes. Must be between 60 and 86400. Mutually exclusive with backup_cron_schedule; backup_cron_schedule takes precedence if both are set. Configure at least one to enable backup." + type = number + default = null + validation { + condition = var.backup_rpo_target_in_minutes == null || try(var.backup_rpo_target_in_minutes >= 60 && var.backup_rpo_target_in_minutes <= 86400, false) + error_message = "backup_rpo_target_in_minutes must be between 60 and 86400." + } +} + +variable "backup_config" { + description = "Defines the backup configuration settings, including volume data and secrets backup options." + type = object({ + include_volume_data = optional(bool) + include_secrets = optional(bool) + }) + default = { + include_volume_data = true + include_secrets = true + } +} + +variable "backup_retain_days" { + description = "The number of days to retain backups. Must be between 1 and 35. Defaults to 7." + type = number + default = 7 + validation { + condition = var.backup_retain_days >= 1 && var.backup_retain_days <= 35 + error_message = "backup_retain_days must be between 1 and 35." + } +} + variable "stateful_ha" { type = bool description = "Whether the Stateful HA Addon is enabled for this cluster."