-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat(backup): add GKE backup configuration in the module #2270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -148,6 +148,10 @@ Then perform the following commands on the root folder: | |
| | 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 | | ||
| | anonymous\_authentication\_config\_mode | Allows users to restrict or enable anonymous access to the cluster. Valid values are `ENABLED` and `LIMITED`. | `string` | `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 [email protected] | `string` | `null` | no | | ||
| | backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. | <pre>object({<br> include_volume_data = optional(bool)<br> include_secrets = optional(bool)<br> })</pre> | <pre>{<br> "include_secrets": true,<br> "include_volume_data": true<br>}</pre> | 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) | <pre>object({<br> enabled = bool<br> autoscaling_profile = string<br> min_cpu_cores = optional(number)<br> max_cpu_cores = optional(number)<br> min_memory_gb = optional(number)<br> max_memory_gb = optional(number)<br> gpu_resources = list(object({ resource_type = string, minimum = number, maximum = number }))<br> auto_repair = bool<br> auto_upgrade = bool<br> disk_size = optional(number)<br> disk_type = optional(string)<br> image_type = optional(string)<br> strategy = optional(string)<br> max_surge = optional(number)<br> max_unavailable = optional(number)<br> node_pool_soak_duration = optional(string)<br> batch_soak_duration = optional(string)<br> batch_percentage = optional(number)<br> batch_node_count = optional(number)<br> enable_secure_boot = optional(bool, false)<br> enable_integrity_monitoring = optional(bool, true)<br> })</pre> | <pre>{<br> "auto_repair": true,<br> "auto_upgrade": true,<br> "autoscaling_profile": "BALANCED",<br> "disk_size": 100,<br> "disk_type": "pd-standard",<br> "enable_integrity_monitoring": true,<br> "enable_secure_boot": false,<br> "enabled": false,<br> "gpu_resources": [],<br> "image_type": "COS_CONTAINERD",<br> "max_cpu_cores": 0,<br> "max_memory_gb": 0,<br> "min_cpu_cores": 0,<br> "min_memory_gb": 0<br>}</pre> | no | | ||
| | cluster\_dns\_domain | The suffix used for all cluster service records. | `string` | `""` | no | | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -933,6 +933,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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| 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." | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -81,6 +81,10 @@ Then perform the following commands on the root folder: | |
| | allow\_net\_admin | (Optional) Enable NET\_ADMIN for the cluster. | `bool` | `null` | no | | ||
| | anonymous\_authentication\_config\_mode | Allows users to restrict or enable anonymous access to the cluster. Valid values are `ENABLED` and `LIMITED`. | `string` | `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 [email protected] | `string` | `null` | no | | ||
| | backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. | <pre>object({<br> include_volume_data = optional(bool)<br> include_secrets = optional(bool)<br> })</pre> | <pre>{<br> "include_secrets": true,<br> "include_volume_data": true<br>}</pre> | 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 | | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -75,6 +75,10 @@ Then perform the following commands on the root folder: | |
| | allow\_net\_admin | (Optional) Enable NET\_ADMIN for the cluster. | `bool` | `null` | no | | ||
| | anonymous\_authentication\_config\_mode | Allows users to restrict or enable anonymous access to the cluster. Valid values are `ENABLED` and `LIMITED`. | `string` | `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 [email protected] | `string` | `null` | no | | ||
| | backup\_config | Defines the backup configuration settings, including volume data and secrets backup options. | <pre>object({<br> include_volume_data = optional(bool)<br> include_secrets = optional(bool)<br> })</pre> | <pre>{<br> "include_secrets": true,<br> "include_volume_data": true<br>}</pre> | 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 | | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of two
dynamic "backup_schedule"blocks is invalid in Terraform and will cause a configuration parsing error, as a resource can only have one dynamic block of a given name. To correctly implement the mutual exclusivity and precedence forcron_scheduleandrpo_config, you should use a singledynamic "backup_schedule"block with nested logic. I've also added a newline at the end of the file, which is a good practice.