From cc87595730062fe5cc48e3d756245d892c8da9d3 Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Wed, 22 Apr 2026 13:58:47 +0100 Subject: [PATCH] Allow backup plans to be unset. We (NDSPCDSP) for example don't use DynamoDB, EBS volumes or ParameterStore, so we have no need for those backup plans, and it seems silly to create them no matter what. So to make sure they don't gets created, I want/need to set: ``` module "source" { [...] backup_plan_config = { "enable": false } backup_plan_config_dynamodb = { "enable": false } backup_plan_config_ebsvol = { "enable": false } backup_plan_config_parameter_store = { "enable": false } } ``` All the other `backup_plan_config_*` resources had a `count` to create them or not, but not the "main" one, so add that. That lead to the resources being an array, so make sure they're `moved` automatically. It also required *all* options in the variables to be `optional()`, which should (!?) be ok, since there's defaults. HOWEVER, the `default` is only used if/when the variable is completely unset! NOT if/when some values are missing. As in, TF won't substitute empty/unset values with one from the `default`. That unfortunately lead to those three values required (`selection_tag`, `compliance_resource_types` and `rules` in the case of the "main" config) can't be required anymore. Because they have defaults, there's no way to check (`validation {}`) if they're set or not. Because they always will, wether `enable` is `true` or `false` :(. --- modules/aws-backup-source/backup_framework.tf | 9 +++++++ modules/aws-backup-source/backup_plan.tf | 20 ++++++++++++++-- modules/aws-backup-source/locals.tf | 2 +- modules/aws-backup-source/variables.tf | 24 ++++++++++--------- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/modules/aws-backup-source/backup_framework.tf b/modules/aws-backup-source/backup_framework.tf index 19a2803..25d5e86 100644 --- a/modules/aws-backup-source/backup_framework.tf +++ b/modules/aws-backup-source/backup_framework.tf @@ -1,4 +1,6 @@ resource "aws_backup_framework" "main" { + count = var.backup_plan_config.enable ? 1 : 0 + # must be underscores instead of dashes name = replace("${local.resource_name_prefix}-framework", "-", "_") description = "${var.project_name} Backup Framework" @@ -292,3 +294,10 @@ resource "aws_backup_framework" "parameter_store" { } } } + +# ----- + +moved { + from = aws_backup_framework.main + to = aws_backup_framework.main[0] +} diff --git a/modules/aws-backup-source/backup_plan.tf b/modules/aws-backup-source/backup_plan.tf index 4e7a671..7f7c75d 100644 --- a/modules/aws-backup-source/backup_plan.tf +++ b/modules/aws-backup-source/backup_plan.tf @@ -1,8 +1,10 @@ resource "aws_backup_plan" "default" { + count = var.backup_plan_config.enable ? 1 : 0 + name = "${local.resource_name_prefix}-plan" dynamic "rule" { - for_each = var.backup_plan_config.rules + for_each = var.backup_plan_config.enable ? var.backup_plan_config.rules : [] content { recovery_point_tags = { backup_rule_name = rule.value.name @@ -157,9 +159,11 @@ resource "aws_backup_plan" "parameter_store" { resource "aws_backup_selection" "default" { + count = var.backup_plan_config.enable ? 1 : 0 + iam_role_arn = aws_iam_role.backup.arn name = "${local.resource_name_prefix}-selection" - plan_id = aws_backup_plan.default.id + plan_id = aws_backup_plan.default[0].id selection_tag { key = var.backup_plan_config.selection_tag @@ -255,3 +259,15 @@ resource "aws_backup_selection" "parameter_store" { } } } + +# ----- + +moved { + from = aws_backup_plan.default + to = aws_backup_plan.default[0] +} + +moved { + from = aws_backup_selection.default + to = aws_backup_selection.default[0] +} diff --git a/modules/aws-backup-source/locals.tf b/modules/aws-backup-source/locals.tf index 39d37d0..979bb8a 100644 --- a/modules/aws-backup-source/locals.tf +++ b/modules/aws-backup-source/locals.tf @@ -9,7 +9,7 @@ locals { selection_tag_value_parameter_store_null_checked = (var.backup_plan_config_parameter_store.selection_tag_value == null) ? "True" : var.backup_plan_config_parameter_store.selection_tag_value selection_tags_parameter_store_null_checked = (var.backup_plan_config_parameter_store.selection_tags == null) ? [{ "key" : var.backup_plan_config_parameter_store.selection_tag, "value" : local.selection_tag_value_parameter_store_null_checked }] : var.backup_plan_config_parameter_store.selection_tags framework_arn_list = flatten(concat( - [aws_backup_framework.main.arn], + [var.backup_plan_config.enable ? aws_backup_framework.main[0].arn : []], var.backup_plan_config_ebsvol.enable ? [aws_backup_framework.ebsvol[0].arn] : [], var.backup_plan_config_dynamodb.enable ? [aws_backup_framework.dynamodb[0].arn] : [], var.backup_plan_config_aurora.enable ? [aws_backup_framework.aurora[0].arn] : [], diff --git a/modules/aws-backup-source/variables.tf b/modules/aws-backup-source/variables.tf index d99aa10..b535630 100644 --- a/modules/aws-backup-source/variables.tf +++ b/modules/aws-backup-source/variables.tf @@ -88,14 +88,15 @@ variable "backup_copy_vault_account_id" { variable "backup_plan_config" { description = "Configuration for backup plans" type = object({ - selection_tag = string + enable = bool + selection_tag = optional(string) selection_tag_value = optional(string) selection_tags = optional(list(object({ key = optional(string) value = optional(string) }))) - compliance_resource_types = list(string) - rules = list(object({ + compliance_resource_types = optional(list(string)) + rules = optional(list(object({ name = string schedule = string completion_window = optional(number) @@ -107,9 +108,10 @@ variable "backup_plan_config" { copy_action = optional(object({ delete_after = optional(number) })) - })) + }))) }) default = { + enable = true selection_tag = "BackupLocal" selection_tag_value = "True" selection_tags = [] @@ -165,13 +167,13 @@ variable "backup_plan_config_dynamodb" { description = "Configuration for backup plans with dynamodb" type = object({ enable = bool - selection_tag = string + selection_tag = optional(string) selection_tag_value = optional(string) selection_tags = optional(list(object({ key = optional(string) value = optional(string) }))) - compliance_resource_types = list(string) + compliance_resource_types = optional(list(string)) rules = optional(list(object({ name = string schedule = string @@ -242,13 +244,13 @@ variable "backup_plan_config_ebsvol" { description = "Configuration for backup plans with EBS" type = object({ enable = bool - selection_tag = string + selection_tag = optional(string) selection_tag_value = optional(string) selection_tags = optional(list(object({ key = optional(string) value = optional(string) }))) - compliance_resource_types = list(string) + compliance_resource_types = optional(list(string)) rules = optional(list(object({ name = string schedule = string @@ -306,8 +308,8 @@ variable "backup_plan_config_aurora" { description = "Configuration for backup plans with aurora" type = object({ enable = bool - selection_tag = string - compliance_resource_types = list(string) + selection_tag = optional(string) + compliance_resource_types = optional(list(string)) restore_testing_overrides = optional(string) rules = optional(list(object({ name = string @@ -366,7 +368,7 @@ variable "backup_plan_config_parameter_store" { description = "Configuration for backup plans with parameter store" type = object({ enable = bool - selection_tag = string + selection_tag = optional(string) selection_tag_value = optional(string) selection_tags = optional(list(object({ key = optional(string)