From 299956b4876ecbfdea83abbd9f280a3837a7e53a Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Wed, 22 Apr 2026 15:24:10 +0100 Subject: [PATCH 01/10] Allow to include environment name in resource names. If we're going to be able to have all resources for multiple environments in one account (PR pending), we must make sure that all resources have the environment name in them, so they can be separated. --- modules/aws-backup-source/backup_report_plan.tf | 8 ++++---- modules/aws-backup-source/backup_restore_testing.tf | 2 +- modules/aws-backup-source/iam.tf | 2 +- modules/aws-backup-source/kms.tf | 2 +- modules/aws-backup-source/locals.tf | 2 +- modules/aws-backup-source/variables.tf | 6 ++++++ 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/modules/aws-backup-source/backup_report_plan.tf b/modules/aws-backup-source/backup_report_plan.tf index cdb1d1c..a736884 100644 --- a/modules/aws-backup-source/backup_report_plan.tf +++ b/modules/aws-backup-source/backup_report_plan.tf @@ -1,6 +1,6 @@ # Create the reports resource "aws_backup_report_plan" "backup_jobs" { - name = var.name_prefix != null ? "${var.name_prefix}_backup_jobs" : "backup_jobs" + name = var.name_prefix != null ? "${replace(local.resource_name_prefix, "-", "_")}_backup_jobs" : "backup_jobs" description = "Report for showing whether backups ran successfully in the last 24 hours" report_delivery_channel { @@ -18,7 +18,7 @@ resource "aws_backup_report_plan" "backup_jobs" { # Create the restore testing completion reports resource "aws_backup_report_plan" "backup_restore_testing_jobs" { - name = var.name_prefix != null ? "${var.name_prefix}_backup_restore_testing_jobs" : "backup_restore_testing_jobs" + name = var.name_prefix != null ? "${replace(local.resource_name_prefix, "-", "_")}_backup_restore_testing_jobs" : "backup_restore_testing_jobs" description = "Report for showing whether backup restore test ran successfully in the last 24 hours" report_delivery_channel { @@ -35,7 +35,7 @@ resource "aws_backup_report_plan" "backup_restore_testing_jobs" { } resource "aws_backup_report_plan" "resource_compliance" { - name = var.name_prefix != null ? "${var.name_prefix}_resource_compliance" : "resource_compliance" + name = var.name_prefix != null ? "${replace(local.resource_name_prefix, "-", "_")}_resource_compliance" : "resource_compliance" description = "Report for showing whether resources are compliant with the framework" report_delivery_channel { @@ -55,7 +55,7 @@ resource "aws_backup_report_plan" "resource_compliance" { resource "aws_backup_report_plan" "copy_jobs" { count = var.backup_copy_vault_arn != "" && var.backup_copy_vault_account_id != "" ? 1 : 0 - name = var.name_prefix != null ? "${var.name_prefix}_copy_jobs" : "copy_jobs" + name = var.name_prefix != null ? "${replace(local.resource_name_prefix, "-", "_")}_copy_jobs" : "copy_jobs" description = "Report for showing whether copies ran successfully in the last 24 hours" report_delivery_channel { diff --git a/modules/aws-backup-source/backup_restore_testing.tf b/modules/aws-backup-source/backup_restore_testing.tf index b6389fc..0c64c08 100644 --- a/modules/aws-backup-source/backup_restore_testing.tf +++ b/modules/aws-backup-source/backup_restore_testing.tf @@ -1,5 +1,5 @@ resource "awscc_backup_restore_testing_plan" "backup_restore_testing_plan" { - restore_testing_plan_name = var.name_prefix != null ? "${var.name_prefix}_backup_restore_testing_plan" : "backup_restore_testing_plan" + restore_testing_plan_name = var.name_prefix != null ? "${replace(local.resource_name_prefix, "-", "_")}_backup_restore_testing_plan" : "backup_restore_testing_plan" schedule_expression = var.restore_testing_plan_scheduled_expression start_window_hours = var.restore_testing_plan_start_window recovery_point_selection = { diff --git a/modules/aws-backup-source/iam.tf b/modules/aws-backup-source/iam.tf index 3b81513..384f746 100644 --- a/modules/aws-backup-source/iam.tf +++ b/modules/aws-backup-source/iam.tf @@ -12,7 +12,7 @@ data "aws_iam_policy_document" "assume_role" { } resource "aws_iam_role" "backup" { - name = "${var.project_name}BackupRole" + name = "${var.include_environment_in_resource_names ? "${var.project_name}-${var.environment_name}" : var.project_name}BackupRole" assume_role_policy = data.aws_iam_policy_document.assume_role.json permissions_boundary = length(var.iam_role_permissions_boundary) > 0 ? var.iam_role_permissions_boundary : null } diff --git a/modules/aws-backup-source/kms.tf b/modules/aws-backup-source/kms.tf index e8a07a2..a36e37a 100644 --- a/modules/aws-backup-source/kms.tf +++ b/modules/aws-backup-source/kms.tf @@ -6,7 +6,7 @@ resource "aws_kms_key" "aws_backup_key" { } resource "aws_kms_alias" "backup_key" { - name = var.name_prefix != null ? "alias/${var.name_prefix}/backup-key" : "alias/${var.environment_name}/backup-key" + name = var.name_prefix != null ? "alias/${var.include_environment_in_resource_names ? "${local.resource_name_prefix}" : var.name_prefix}/backup-key" : "alias/${var.environment_name}/backup-key" target_key_id = aws_kms_key.aws_backup_key.key_id } diff --git a/modules/aws-backup-source/locals.tf b/modules/aws-backup-source/locals.tf index 39d37d0..a55be65 100644 --- a/modules/aws-backup-source/locals.tf +++ b/modules/aws-backup-source/locals.tf @@ -1,5 +1,5 @@ locals { - resource_name_prefix = var.name_prefix != null ? var.name_prefix : "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-backup" + resource_name_prefix = var.name_prefix != null ? (var.include_environment_in_resource_names ? "${var.name_prefix}-${var.environment_name}" : var.name_prefix) : (var.include_environment_in_resource_names ? "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-${var.environment_name}-backup" : "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-backup") selection_tag_value_null_checked = (var.backup_plan_config.selection_tag_value == null) ? "True" : var.backup_plan_config.selection_tag_value selection_tag_value_dynamodb_null_checked = (var.backup_plan_config_dynamodb.selection_tag_value == null) ? "True" : var.backup_plan_config_dynamodb.selection_tag_value selection_tags_null_checked = (var.backup_plan_config.selection_tags == null) ? [{ "key" : var.backup_plan_config.selection_tag, "value" : local.selection_tag_value_null_checked }] : var.backup_plan_config.selection_tags diff --git a/modules/aws-backup-source/variables.tf b/modules/aws-backup-source/variables.tf index d99aa10..7b0fba0 100644 --- a/modules/aws-backup-source/variables.tf +++ b/modules/aws-backup-source/variables.tf @@ -520,3 +520,9 @@ variable "lambda_restore_to_s3_max_wait_minutes" { type = number default = 5 } + +variable "include_environment_in_resource_names" { + description = "Should the environment name be included in resource names. Required for 'all resources in the same account'" + type = bool + default = false +} From af74023e2132e9a450fa63d93972b432e1d62871 Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Thu, 23 Apr 2026 15:50:30 +0100 Subject: [PATCH 02/10] Allow creating resources for multiple environments in the same account. The AWSBackup/Framework must be unique in the account. As in, it's not possible to create the framework with the same rules etc. Instead, we "import" the "base" framework, and use that where needed. --- modules/aws-backup-source/backup_framework.tf | 43 +++++++++++++++++-- modules/aws-backup-source/locals.tf | 22 ++++++---- modules/aws-backup-source/variables.tf | 10 +++++ 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/modules/aws-backup-source/backup_framework.tf b/modules/aws-backup-source/backup_framework.tf index 19a2803..7435777 100644 --- a/modules/aws-backup-source/backup_framework.tf +++ b/modules/aws-backup-source/backup_framework.tf @@ -1,4 +1,16 @@ +# There can be only one [framework with x controls in one account]! +# +# For the frameworks of the other envs in the account, we "import" +# them using a `data` record, looking for the environment name set +# in the `resources_in_same_account` variable. + +data "aws_backup_framework" "main" { + count = var.backup_plan_config.enable && var.resources_in_same_account != "" ? 1 : 0 + name = replace("${var.name_prefix}-${var.resources_in_same_account}-framework", "-", "_") +} resource "aws_backup_framework" "main" { + count = var.backup_plan_config.enable && var.resources_in_same_account == "" ? 1 : 0 + # must be underscores instead of dashes name = replace("${local.resource_name_prefix}-framework", "-", "_") description = "${var.project_name} Backup Framework" @@ -131,8 +143,12 @@ resource "aws_backup_framework" "main" { } } +data "aws_backup_framework" "dynamodb" { + count = var.backup_plan_config_dynamodb.enable && var.resources_in_same_account != "" ? 1 : 0 + name = replace("${var.name_prefix}-${var.resources_in_same_account}-dynamodb-framework", "-", "_") +} resource "aws_backup_framework" "dynamodb" { - count = var.backup_plan_config_dynamodb.enable ? 1 : 0 + count = var.backup_plan_config_dynamodb.enable && var.resources_in_same_account == "" ? 1 : 0 # must be underscores instead of dashes name = replace("${local.resource_name_prefix}-dynamodb-framework", "-", "_") description = "${var.project_name} DynamoDB Backup Framework" @@ -172,8 +188,12 @@ resource "aws_backup_framework" "dynamodb" { } } +data "aws_backup_framework" "ebsvol" { + count = var.backup_plan_config_ebsvol.enable && var.resources_in_same_account != "" ? 1 : 0 + name = replace("${var.name_prefix}-${var.resources_in_same_account}-ebsvol-framework", "-", "_") +} resource "aws_backup_framework" "ebsvol" { - count = var.backup_plan_config_ebsvol.enable ? 1 : 0 + count = var.backup_plan_config_ebsvol.enable && var.resources_in_same_account == "" ? 1 : 0 # must be underscores instead of dashes name = replace("${local.resource_name_prefix}-ebsvol-framework", "-", "_") description = "${var.project_name} EBS Backup Framework" @@ -213,8 +233,12 @@ resource "aws_backup_framework" "ebsvol" { } } +data "aws_backup_framework" "aurora" { + count = var.backup_plan_config_aurora.enable && var.resources_in_same_account != "" ? 1 : 0 + name = replace("${var.name_prefix}-${var.resources_in_same_account}-aurora-framework", "-", "_") +} resource "aws_backup_framework" "aurora" { - count = var.backup_plan_config_aurora.enable ? 1 : 0 + count = var.backup_plan_config_aurora.enable && var.resources_in_same_account == "" ? 1 : 0 # must be underscores instead of dashes name = replace("${local.resource_name_prefix}-aurora-framework", "-", "_") description = "${var.project_name} Aurora Backup Framework" @@ -253,8 +277,12 @@ resource "aws_backup_framework" "aurora" { } } +data "aws_backup_framework" "parameter_store" { + count = var.backup_plan_config_parameter_store.enable && var.resources_in_same_account != "" ? 1 : 0 + name = replace("${var.name_prefix}-${var.resources_in_same_account}-parameter-store-framework", "-", "_") +} resource "aws_backup_framework" "parameter_store" { - count = var.backup_plan_config_parameter_store.enable ? 1 : 0 + count = var.backup_plan_config_parameter_store.enable && var.resources_in_same_account == "" ? 1 : 0 # must be underscores instead of dashes name = replace("${local.resource_name_prefix}-parameter-store-framework", "-", "_") description = "${var.project_name} Parameter Store Backup Framework" @@ -292,3 +320,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/locals.tf b/modules/aws-backup-source/locals.tf index a55be65..750d779 100644 --- a/modules/aws-backup-source/locals.tf +++ b/modules/aws-backup-source/locals.tf @@ -1,21 +1,27 @@ locals { resource_name_prefix = var.name_prefix != null ? (var.include_environment_in_resource_names ? "${var.name_prefix}-${var.environment_name}" : var.name_prefix) : (var.include_environment_in_resource_names ? "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-${var.environment_name}-backup" : "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-backup") + selection_tag_value_null_checked = (var.backup_plan_config.selection_tag_value == null) ? "True" : var.backup_plan_config.selection_tag_value + selection_tag_value_aurora_null_checked = (var.backup_plan_config_aurora.selection_tag_value == null) ? "True" : var.backup_plan_config_aurora.selection_tag_value selection_tag_value_dynamodb_null_checked = (var.backup_plan_config_dynamodb.selection_tag_value == null) ? "True" : var.backup_plan_config_dynamodb.selection_tag_value + selection_tag_value_ebsvol_null_checked = (var.backup_plan_config_ebsvol.selection_tag_value == null) ? "True" : var.backup_plan_config_ebsvol.selection_tag_value + 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_null_checked = (var.backup_plan_config.selection_tags == null) ? [{ "key" : var.backup_plan_config.selection_tag, "value" : local.selection_tag_value_null_checked }] : var.backup_plan_config.selection_tags + selection_tags_aurora_null_checked = (var.backup_plan_config_aurora.selection_tags == null) ? [{ "key" : var.backup_plan_config_aurora.selection_tag, "value" : local.selection_tag_value_aurora_null_checked }] : var.backup_plan_config_aurora.selection_tags selection_tags_dynamodb_null_checked = (var.backup_plan_config_dynamodb.selection_tags == null) ? [{ "key" : var.backup_plan_config_dynamodb.selection_tag, "value" : local.selection_tag_value_dynamodb_null_checked }] : var.backup_plan_config_dynamodb.selection_tags - selection_tag_value_ebsvol_null_checked = (var.backup_plan_config_ebsvol.selection_tag_value == null) ? "True" : var.backup_plan_config_ebsvol.selection_tag_value selection_tags_ebsvol_null_checked = (var.backup_plan_config_ebsvol.selection_tags == null) ? [{ "key" : var.backup_plan_config_ebsvol.selection_tag, "value" : local.selection_tag_value_ebsvol_null_checked }] : var.backup_plan_config_ebsvol.selection_tags - 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_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] : [], - var.backup_plan_config_parameter_store.enable ? [aws_backup_framework.parameter_store[0].arn] : [] + framework_arn_list = flatten(concat( + var.backup_plan_config.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.main[0].arn : aws_backup_framework.main[0].arn] : [], + var.backup_plan_config_ebsvol.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.ebsvol[0].arn : data.aws_backup_framework.ebsvol[0].arn] : [], + var.backup_plan_config_dynamodb.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.dynamodb[0].arn : data.aws_backup_framework.dynamodb[0].arn] : [], + var.backup_plan_config_aurora.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.aurora[0].arn : data.aws_backup_framework.aurora[0].arn] : [], + var.backup_plan_config_parameter_store.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.parameter_store[0].arn : data.aws_backup_framework.parameter_store[0].arn] : [] )) + aurora_overrides = var.backup_plan_config_aurora.restore_testing_overrides == null ? null : jsondecode(var.backup_plan_config_aurora.restore_testing_overrides) + terraform_role_arns = length(var.terraform_role_arns) > 0 ? var.terraform_role_arns : [var.terraform_role_arn] } diff --git a/modules/aws-backup-source/variables.tf b/modules/aws-backup-source/variables.tf index 7b0fba0..1f8efa6 100644 --- a/modules/aws-backup-source/variables.tf +++ b/modules/aws-backup-source/variables.tf @@ -526,3 +526,13 @@ variable "include_environment_in_resource_names" { type = bool default = false } + +# Plans etc are _account_ specific, not _environment_ specific, so we only want to create some resources +# once. As in, when this is `""` (empty string). For additional envs in the account, set this to the environment +# where the "base" resources are (for example `dev`). +# NOTE: Require `include_environment_in_resource_names` set to `true` for this to work! +variable "resources_in_same_account" { + description = "Should all resources be created in the same account. Set to 'true' if base resources already exists in the account, and they should be reused." + type = string + default = "" +} From f71f2b4f582e9a26e8b13a7c30c7f1c631de96cb Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Thu, 23 Apr 2026 15:51:51 +0100 Subject: [PATCH 03/10] Improve the selection process by utilising the `selection_tags` variable. It was included in the main variable for all types, but Aurora. With a value of: ``` module "source" { [...] backup_plan_config_XXX = { [...] "selection_tags" : [ { "key": "Environment" "value": var.environment }, { "key": "Stack" "value": "rds-cluster" }, { "key": "ManagedBy" "value": "Terraform" } ] [...] } [...] } ``` We narrow down the list of resources that the plan etc will find to only that of the environment (tag `Environment=dev` for example). Before this commit, it would only look for `selection_tag=selection_tag_value`, which would catch all resources with that tag set. One could set different tags for different environments, but that would be confusing in the long run. Better to have the same tag for the backup, but specify the environment as well. --- modules/aws-backup-source/backup_plan.tf | 44 +++++++++++++++--- .../backup_restore_testing.tf | 45 ++++++++++++++----- modules/aws-backup-source/variables.tf | 10 ++++- 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/modules/aws-backup-source/backup_plan.tf b/modules/aws-backup-source/backup_plan.tf index 4e7a671..3a7755e 100644 --- a/modules/aws-backup-source/backup_plan.tf +++ b/modules/aws-backup-source/backup_plan.tf @@ -168,7 +168,12 @@ resource "aws_backup_selection" "default" { } condition { dynamic "string_equals" { - for_each = local.selection_tags_null_checked + for_each = concat(local.selection_tags_null_checked, [ + { + "key": var.backup_plan_config.selection_tag, + "value": var.backup_plan_config.selection_tag_value != null ? var.backup_plan_config.selection_tag_value : "True" + } + ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" value = try(string_equals.value.value, null) @@ -190,7 +195,12 @@ resource "aws_backup_selection" "dynamodb" { } condition { dynamic "string_equals" { - for_each = local.selection_tags_dynamodb_null_checked + for_each = concat(local.selection_tags_dynamodb_null_checked, [ + { + "key": var.backup_plan_config_dynamodb.selection_tag, + "value": var.backup_plan_config_dynamodb.selection_tag_value != null ? var.backup_plan_config_dynamodb.selection_tag_value : "True" + } + ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" value = try(string_equals.value.value, null) @@ -212,7 +222,12 @@ resource "aws_backup_selection" "ebsvol" { } condition { dynamic "string_equals" { - for_each = local.selection_tags_ebsvol_null_checked + for_each = concat(local.selection_tags_ebsvol_null_checked, [ + { + "key": var.backup_plan_config_ebsvol.selection_tag, + "value": var.backup_plan_config_ebsvol.selection_tag_value != null ? var.backup_plan_config_ebsvol.selection_tag_value : "True" + } + ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" value = try(string_equals.value.value, null) @@ -230,7 +245,21 @@ resource "aws_backup_selection" "aurora" { selection_tag { key = var.backup_plan_config_aurora.selection_tag type = "STRINGEQUALS" - value = "True" + value = (var.backup_plan_config_aurora.selection_tag_value == null) ? "True" : var.backup_plan_config_aurora.selection_tag_value + } + condition { + dynamic "string_equals" { + for_each = concat(local.selection_tags_aurora_null_checked, [ + { + "key": var.backup_plan_config_aurora.selection_tag, + "value": var.backup_plan_config_aurora.selection_tag_value != null ? var.backup_plan_config_aurora.selection_tag_value : "True" + } + ]) + content { + key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" + value = try(string_equals.value.value, null) + } + } } } @@ -247,7 +276,12 @@ resource "aws_backup_selection" "parameter_store" { } condition { dynamic "string_equals" { - for_each = local.selection_tags_parameter_store_null_checked + for_each = concat(local.selection_tags_parameter_store_null_checked, [ + { + "key": var.backup_plan_config_parameter_store.selection_tag, + "value": var.backup_plan_config_parameter_store.selection_tag_value != null ? var.backup_plan_config_parameter_store.selection_tag_value : "True" + } + ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" value = try(string_equals.value.value, null) diff --git a/modules/aws-backup-source/backup_restore_testing.tf b/modules/aws-backup-source/backup_restore_testing.tf index 0c64c08..7ddba1c 100644 --- a/modules/aws-backup-source/backup_restore_testing.tf +++ b/modules/aws-backup-source/backup_restore_testing.tf @@ -18,10 +18,17 @@ resource "awscc_backup_restore_testing_selection" "backup_restore_testing_select restore_testing_selection_name = "backup_restore_testing_selection_dynamodb" protected_resource_arns = ["*"] protected_resource_conditions = { - string_equals = [{ - key = "aws:ResourceTag/${var.backup_plan_config_dynamodb.selection_tag}" - value = "True" - }] + string_equals = concat([ + { + key = "aws:ResourceTag/${var.backup_plan_config_dynamodb.selection_tag}" + value = "True" + } + ], [ + for tag in local.selection_tags_dynamodb_null_checked: { + key = "aws:ResourceTag/${tag.key}", + value = tag.value + } + ]) } } @@ -34,10 +41,17 @@ resource "awscc_backup_restore_testing_selection" "backup_restore_testing_select restore_testing_selection_name = "backup_restore_testing_selection_ebsvol" protected_resource_arns = ["*"] protected_resource_conditions = { - string_equals = [{ - key = "aws:ResourceTag/${var.backup_plan_config_ebsvol.selection_tag}" - value = "True" - }] + string_equals = concat([ + { + key = "aws:ResourceTag/${var.backup_plan_config_ebsvol.selection_tag}" + value = "True" + } + ], [ + for tag in local.selection_tags_ebsvol_null_checked: { + key = "aws:ResourceTag/${tag.key}", + value = tag.value + } + ]) } } @@ -49,10 +63,17 @@ resource "awscc_backup_restore_testing_selection" "backup_restore_testing_select restore_testing_selection_name = "backup_restore_testing_selection_aurora" protected_resource_arns = ["*"] protected_resource_conditions = { - string_equals = [{ - key = "aws:ResourceTag/${var.backup_plan_config_aurora.selection_tag}" - value = "True" - }] + string_equals = concat([ + { + key = "aws:ResourceTag/${var.backup_plan_config_aurora.selection_tag}" + value = "True" + } + ], [ + for tag in local.selection_tags_aurora_null_checked: { + key = "aws:ResourceTag/${tag.key}", + value = tag.value + } + ]) } restore_metadata_overrides = local.aurora_overrides } diff --git a/modules/aws-backup-source/variables.tf b/modules/aws-backup-source/variables.tf index 1f8efa6..c34c0bd 100644 --- a/modules/aws-backup-source/variables.tf +++ b/modules/aws-backup-source/variables.tf @@ -265,6 +265,7 @@ variable "backup_plan_config_ebsvol" { default = { enable = true selection_tag = "BackupEBSVol" + selection_tag_value = "True" compliance_resource_types = ["EBS"] rules = [ { @@ -306,7 +307,12 @@ variable "backup_plan_config_aurora" { description = "Configuration for backup plans with aurora" 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) restore_testing_overrides = optional(string) rules = optional(list(object({ @@ -325,6 +331,8 @@ variable "backup_plan_config_aurora" { default = { enable = true selection_tag = "BackupAurora" + selection_tag_value = "True" + selection_tags = [] compliance_resource_types = ["Aurora"] rules = [ { From c1626bd68e35e043affe48036ae7ca41e40e1a79 Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Fri, 24 Apr 2026 11:53:22 +0100 Subject: [PATCH 04/10] Allow to include environment name in resource names. --- modules/aws-backup-destination/backup.tf | 13 +++++++-- .../backup_vault_lock.tf | 5 ++-- .../backup_vault_policy.tf | 19 ++++++++++-- modules/aws-backup-destination/iam.tf | 4 +-- .../parameter_store_kms.tf | 29 +++++++++++++++++-- modules/aws-backup-destination/variables.tf | 9 ++++++ 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/modules/aws-backup-destination/backup.tf b/modules/aws-backup-destination/backup.tf index 2cdad37..e33ae48 100644 --- a/modules/aws-backup-destination/backup.tf +++ b/modules/aws-backup-destination/backup.tf @@ -1,13 +1,22 @@ resource "aws_backup_vault" "vault" { + count = var.resources_in_same_account ? 1 : 0 + name = var.name_prefix != null ? "${var.name_prefix}-backup-vault" : "${var.source_account_name}-backup-vault" kms_key_arn = var.kms_key } output "vault_arn" { - value = aws_backup_vault.vault.arn + value = var.resources_in_same_account ? aws_backup_vault.vault[0].arn : null } output "vault_name" { description = "The name of the backup vault." - value = aws_backup_vault.vault.name + value = var.resources_in_same_account ? aws_backup_vault.vault[0].name : null +} + +# ----- + +moved { + from = aws_backup_vault.vault + to = aws_backup_vault.vault[0] } diff --git a/modules/aws-backup-destination/backup_vault_lock.tf b/modules/aws-backup-destination/backup_vault_lock.tf index e1a3178..ce3e75d 100644 --- a/modules/aws-backup-destination/backup_vault_lock.tf +++ b/modules/aws-backup-destination/backup_vault_lock.tf @@ -1,6 +1,7 @@ resource "aws_backup_vault_lock_configuration" "vault_lock" { - count = var.enable_vault_protection ? 1 : 0 - backup_vault_name = aws_backup_vault.vault.name + count = var.enable_vault_protection && var.resources_in_same_account ? 1 : 0 + + backup_vault_name = aws_backup_vault.vault[0].name changeable_for_days = var.vault_lock_type == "compliance" ? var.changeable_for_days : null max_retention_days = var.vault_lock_max_retention_days min_retention_days = var.vault_lock_min_retention_days diff --git a/modules/aws-backup-destination/backup_vault_policy.tf b/modules/aws-backup-destination/backup_vault_policy.tf index 06e3468..9e94230 100644 --- a/modules/aws-backup-destination/backup_vault_policy.tf +++ b/modules/aws-backup-destination/backup_vault_policy.tf @@ -1,9 +1,12 @@ resource "aws_backup_vault_policy" "vault_policy" { - backup_vault_name = aws_backup_vault.vault.name - policy = data.aws_iam_policy_document.vault_policy.json + count = var.resources_in_same_account ? 1 : 0 + + backup_vault_name = aws_backup_vault.vault[0].name + policy = data.aws_iam_policy_document.vault_policy[0].json } data "aws_iam_policy_document" "vault_policy" { + count = var.resources_in_same_account ? 1 : 0 statement { sid = "AllowCopyToVault" @@ -66,3 +69,15 @@ data "aws_iam_policy_document" "vault_policy" { } } } + +# ----- + +moved { + from = aws_backup_vault_policy.vault_policy + to = aws_backup_vault_policy.vault_policy[0] +} + +moved { + from = data.aws_iam_policy_document.vault_policy + to = data.aws_iam_policy_document.vault_policy[0] +} diff --git a/modules/aws-backup-destination/iam.tf b/modules/aws-backup-destination/iam.tf index c700e86..bcd7641 100644 --- a/modules/aws-backup-destination/iam.tf +++ b/modules/aws-backup-destination/iam.tf @@ -42,7 +42,7 @@ resource "aws_iam_role" "copy_recovery_point" { } data "aws_iam_policy_document" "copy_recovery_point_permissions" { - count = var.enable_cross_account_vault_access ? 1 : 0 + count = var.enable_cross_account_vault_access && var.resources_in_same_account ? 1 : 0 # Start copy job (resource-level supports recoveryPoint*) statement { @@ -71,7 +71,7 @@ data "aws_iam_policy_document" "copy_recovery_point_permissions" { ] resources = [ "arn:aws:backup:${var.region}:${var.account_id}:recovery-point:*", - "arn:aws:backup:${var.region}:${var.account_id}:backup-vault:${aws_backup_vault.vault.name}", + "arn:aws:backup:${var.region}:${var.account_id}:backup-vault:${aws_backup_vault.vault[0].name}", "arn:aws:backup:${var.region}:${var.source_account_id}:backup-vault:*" ] } diff --git a/modules/aws-backup-destination/parameter_store_kms.tf b/modules/aws-backup-destination/parameter_store_kms.tf index 374fda7..409a57f 100644 --- a/modules/aws-backup-destination/parameter_store_kms.tf +++ b/modules/aws-backup-destination/parameter_store_kms.tf @@ -1,4 +1,6 @@ data "aws_iam_policy_document" "kms_key_policy" { + count = var.resources_in_same_account ? 1 : 0 + statement { sid = "Enable IAM User Permissions" effect = "Allow" @@ -33,17 +35,38 @@ data "aws_iam_policy_document" "kms_key_policy" { } resource "aws_kms_key" "parameter_store_key" { + count = var.resources_in_same_account ? 1 : 0 + description = "KMS key for cross-account encryption of Parameter Store backups." deletion_window_in_days = 7 - policy = data.aws_iam_policy_document.kms_key_policy.json + policy = data.aws_iam_policy_document.kms_key_policy[0].json } resource "aws_kms_alias" "parameter_store_alias" { + count = var.resources_in_same_account ? 1 : 0 + name = "alias/parameter-store-backup-key" - target_key_id = aws_kms_key.parameter_store_key.key_id + target_key_id = aws_kms_key.parameter_store_key[0].key_id } output "parameter_store_kms_key_arn" { description = "The ARN of the KMS key created in the backup account." - value = aws_kms_key.parameter_store_key.arn + value = var.resources_in_same_account ? aws_kms_key.parameter_store_key[0].arn : null +} + +# ----- + +moved { + from = data.aws_iam_policy_document.kms_key_policy + to = data.aws_iam_policy_document.kms_key_policy[0] +} + +moved { + from = aws_kms_key.parameter_store_key + to = aws_kms_key.parameter_store_key[0] +} + +moved { + from = aws_kms_alias.parameter_store_alias + to = aws_kms_alias.parameter_store_alias[0] } diff --git a/modules/aws-backup-destination/variables.tf b/modules/aws-backup-destination/variables.tf index bbe68da..bdc6b8e 100644 --- a/modules/aws-backup-destination/variables.tf +++ b/modules/aws-backup-destination/variables.tf @@ -100,3 +100,12 @@ variable "enable_cross_account_vault_access" { type = bool default = false } + +# If we're building this for multiple environments in the same account, some things +# should not be created. Such as the vault! There can be only one - the environment +# vaults should all copy to this, main/backup/immutable vault. +variable "resources_in_same_account" { + description = "Should all resources be created in the same account. Set to 'true' if base resources already exists in the account, and they should be reused." + type = bool + default = false +} From 655393bacddf5225fa38199a184622dae9a7e2b3 Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Mon, 27 Apr 2026 11:18:47 +0100 Subject: [PATCH 05/10] Run code through `terraform fmt`. --- modules/aws-backup-source/backup_framework.tf | 10 ++--- modules/aws-backup-source/backup_plan.tf | 40 +++++++++---------- modules/aws-backup-source/locals.tf | 14 +++---- modules/aws-backup-source/variables.tf | 6 +-- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/modules/aws-backup-source/backup_framework.tf b/modules/aws-backup-source/backup_framework.tf index 7435777..52a6ff0 100644 --- a/modules/aws-backup-source/backup_framework.tf +++ b/modules/aws-backup-source/backup_framework.tf @@ -6,7 +6,7 @@ data "aws_backup_framework" "main" { count = var.backup_plan_config.enable && var.resources_in_same_account != "" ? 1 : 0 - name = replace("${var.name_prefix}-${var.resources_in_same_account}-framework", "-", "_") + name = replace("${var.name_prefix}-${var.resources_in_same_account}-framework", "-", "_") } resource "aws_backup_framework" "main" { count = var.backup_plan_config.enable && var.resources_in_same_account == "" ? 1 : 0 @@ -145,7 +145,7 @@ resource "aws_backup_framework" "main" { data "aws_backup_framework" "dynamodb" { count = var.backup_plan_config_dynamodb.enable && var.resources_in_same_account != "" ? 1 : 0 - name = replace("${var.name_prefix}-${var.resources_in_same_account}-dynamodb-framework", "-", "_") + name = replace("${var.name_prefix}-${var.resources_in_same_account}-dynamodb-framework", "-", "_") } resource "aws_backup_framework" "dynamodb" { count = var.backup_plan_config_dynamodb.enable && var.resources_in_same_account == "" ? 1 : 0 @@ -190,7 +190,7 @@ resource "aws_backup_framework" "dynamodb" { data "aws_backup_framework" "ebsvol" { count = var.backup_plan_config_ebsvol.enable && var.resources_in_same_account != "" ? 1 : 0 - name = replace("${var.name_prefix}-${var.resources_in_same_account}-ebsvol-framework", "-", "_") + name = replace("${var.name_prefix}-${var.resources_in_same_account}-ebsvol-framework", "-", "_") } resource "aws_backup_framework" "ebsvol" { count = var.backup_plan_config_ebsvol.enable && var.resources_in_same_account == "" ? 1 : 0 @@ -235,7 +235,7 @@ resource "aws_backup_framework" "ebsvol" { data "aws_backup_framework" "aurora" { count = var.backup_plan_config_aurora.enable && var.resources_in_same_account != "" ? 1 : 0 - name = replace("${var.name_prefix}-${var.resources_in_same_account}-aurora-framework", "-", "_") + name = replace("${var.name_prefix}-${var.resources_in_same_account}-aurora-framework", "-", "_") } resource "aws_backup_framework" "aurora" { count = var.backup_plan_config_aurora.enable && var.resources_in_same_account == "" ? 1 : 0 @@ -279,7 +279,7 @@ resource "aws_backup_framework" "aurora" { data "aws_backup_framework" "parameter_store" { count = var.backup_plan_config_parameter_store.enable && var.resources_in_same_account != "" ? 1 : 0 - name = replace("${var.name_prefix}-${var.resources_in_same_account}-parameter-store-framework", "-", "_") + name = replace("${var.name_prefix}-${var.resources_in_same_account}-parameter-store-framework", "-", "_") } resource "aws_backup_framework" "parameter_store" { count = var.backup_plan_config_parameter_store.enable && var.resources_in_same_account == "" ? 1 : 0 diff --git a/modules/aws-backup-source/backup_plan.tf b/modules/aws-backup-source/backup_plan.tf index 3a7755e..e235608 100644 --- a/modules/aws-backup-source/backup_plan.tf +++ b/modules/aws-backup-source/backup_plan.tf @@ -169,10 +169,10 @@ resource "aws_backup_selection" "default" { condition { dynamic "string_equals" { for_each = concat(local.selection_tags_null_checked, [ - { - "key": var.backup_plan_config.selection_tag, - "value": var.backup_plan_config.selection_tag_value != null ? var.backup_plan_config.selection_tag_value : "True" - } + { + "key" : var.backup_plan_config.selection_tag, + "value" : var.backup_plan_config.selection_tag_value != null ? var.backup_plan_config.selection_tag_value : "True" + } ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" @@ -196,10 +196,10 @@ resource "aws_backup_selection" "dynamodb" { condition { dynamic "string_equals" { for_each = concat(local.selection_tags_dynamodb_null_checked, [ - { - "key": var.backup_plan_config_dynamodb.selection_tag, - "value": var.backup_plan_config_dynamodb.selection_tag_value != null ? var.backup_plan_config_dynamodb.selection_tag_value : "True" - } + { + "key" : var.backup_plan_config_dynamodb.selection_tag, + "value" : var.backup_plan_config_dynamodb.selection_tag_value != null ? var.backup_plan_config_dynamodb.selection_tag_value : "True" + } ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" @@ -223,10 +223,10 @@ resource "aws_backup_selection" "ebsvol" { condition { dynamic "string_equals" { for_each = concat(local.selection_tags_ebsvol_null_checked, [ - { - "key": var.backup_plan_config_ebsvol.selection_tag, - "value": var.backup_plan_config_ebsvol.selection_tag_value != null ? var.backup_plan_config_ebsvol.selection_tag_value : "True" - } + { + "key" : var.backup_plan_config_ebsvol.selection_tag, + "value" : var.backup_plan_config_ebsvol.selection_tag_value != null ? var.backup_plan_config_ebsvol.selection_tag_value : "True" + } ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" @@ -250,10 +250,10 @@ resource "aws_backup_selection" "aurora" { condition { dynamic "string_equals" { for_each = concat(local.selection_tags_aurora_null_checked, [ - { - "key": var.backup_plan_config_aurora.selection_tag, - "value": var.backup_plan_config_aurora.selection_tag_value != null ? var.backup_plan_config_aurora.selection_tag_value : "True" - } + { + "key" : var.backup_plan_config_aurora.selection_tag, + "value" : var.backup_plan_config_aurora.selection_tag_value != null ? var.backup_plan_config_aurora.selection_tag_value : "True" + } ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" @@ -277,10 +277,10 @@ resource "aws_backup_selection" "parameter_store" { condition { dynamic "string_equals" { for_each = concat(local.selection_tags_parameter_store_null_checked, [ - { - "key": var.backup_plan_config_parameter_store.selection_tag, - "value": var.backup_plan_config_parameter_store.selection_tag_value != null ? var.backup_plan_config_parameter_store.selection_tag_value : "True" - } + { + "key" : var.backup_plan_config_parameter_store.selection_tag, + "value" : var.backup_plan_config_parameter_store.selection_tag_value != null ? var.backup_plan_config_parameter_store.selection_tag_value : "True" + } ]) content { key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}" diff --git a/modules/aws-backup-source/locals.tf b/modules/aws-backup-source/locals.tf index 750d779..48530fd 100644 --- a/modules/aws-backup-source/locals.tf +++ b/modules/aws-backup-source/locals.tf @@ -1,5 +1,5 @@ locals { - resource_name_prefix = var.name_prefix != null ? (var.include_environment_in_resource_names ? "${var.name_prefix}-${var.environment_name}" : var.name_prefix) : (var.include_environment_in_resource_names ? "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-${var.environment_name}-backup" : "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-backup") + resource_name_prefix = var.name_prefix != null ? (var.include_environment_in_resource_names ? "${var.name_prefix}-${var.environment_name}" : var.name_prefix) : (var.include_environment_in_resource_names ? "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-${var.environment_name}-backup" : "${data.aws_region.current.id}-${data.aws_caller_identity.current.account_id}-backup") selection_tag_value_null_checked = (var.backup_plan_config.selection_tag_value == null) ? "True" : var.backup_plan_config.selection_tag_value selection_tag_value_aurora_null_checked = (var.backup_plan_config_aurora.selection_tag_value == null) ? "True" : var.backup_plan_config_aurora.selection_tag_value @@ -7,11 +7,11 @@ locals { selection_tag_value_ebsvol_null_checked = (var.backup_plan_config_ebsvol.selection_tag_value == null) ? "True" : var.backup_plan_config_ebsvol.selection_tag_value 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_null_checked = (var.backup_plan_config.selection_tags == null) ? [{ "key" : var.backup_plan_config.selection_tag, "value" : local.selection_tag_value_null_checked }] : var.backup_plan_config.selection_tags - selection_tags_aurora_null_checked = (var.backup_plan_config_aurora.selection_tags == null) ? [{ "key" : var.backup_plan_config_aurora.selection_tag, "value" : local.selection_tag_value_aurora_null_checked }] : var.backup_plan_config_aurora.selection_tags - selection_tags_dynamodb_null_checked = (var.backup_plan_config_dynamodb.selection_tags == null) ? [{ "key" : var.backup_plan_config_dynamodb.selection_tag, "value" : local.selection_tag_value_dynamodb_null_checked }] : var.backup_plan_config_dynamodb.selection_tags - selection_tags_ebsvol_null_checked = (var.backup_plan_config_ebsvol.selection_tags == null) ? [{ "key" : var.backup_plan_config_ebsvol.selection_tag, "value" : local.selection_tag_value_ebsvol_null_checked }] : var.backup_plan_config_ebsvol.selection_tags - 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 + selection_tags_null_checked = (var.backup_plan_config.selection_tags == null) ? [{ "key" : var.backup_plan_config.selection_tag, "value" : local.selection_tag_value_null_checked }] : var.backup_plan_config.selection_tags + selection_tags_aurora_null_checked = (var.backup_plan_config_aurora.selection_tags == null) ? [{ "key" : var.backup_plan_config_aurora.selection_tag, "value" : local.selection_tag_value_aurora_null_checked }] : var.backup_plan_config_aurora.selection_tags + selection_tags_dynamodb_null_checked = (var.backup_plan_config_dynamodb.selection_tags == null) ? [{ "key" : var.backup_plan_config_dynamodb.selection_tag, "value" : local.selection_tag_value_dynamodb_null_checked }] : var.backup_plan_config_dynamodb.selection_tags + selection_tags_ebsvol_null_checked = (var.backup_plan_config_ebsvol.selection_tags == null) ? [{ "key" : var.backup_plan_config_ebsvol.selection_tag, "value" : local.selection_tag_value_ebsvol_null_checked }] : var.backup_plan_config_ebsvol.selection_tags + 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( var.backup_plan_config.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.main[0].arn : aws_backup_framework.main[0].arn] : [], @@ -21,7 +21,7 @@ locals { var.backup_plan_config_parameter_store.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.parameter_store[0].arn : data.aws_backup_framework.parameter_store[0].arn] : [] )) - aurora_overrides = var.backup_plan_config_aurora.restore_testing_overrides == null ? null : jsondecode(var.backup_plan_config_aurora.restore_testing_overrides) + aurora_overrides = var.backup_plan_config_aurora.restore_testing_overrides == null ? null : jsondecode(var.backup_plan_config_aurora.restore_testing_overrides) terraform_role_arns = length(var.terraform_role_arns) > 0 ? var.terraform_role_arns : [var.terraform_role_arn] } diff --git a/modules/aws-backup-source/variables.tf b/modules/aws-backup-source/variables.tf index c34c0bd..0b88829 100644 --- a/modules/aws-backup-source/variables.tf +++ b/modules/aws-backup-source/variables.tf @@ -306,9 +306,9 @@ variable "backup_plan_config_ebsvol" { variable "backup_plan_config_aurora" { description = "Configuration for backup plans with aurora" type = object({ - enable = bool - selection_tag = optional(string) - selection_tag_value = optional(string) + enable = bool + selection_tag = optional(string) + selection_tag_value = optional(string) selection_tags = optional(list(object({ key = optional(string) value = optional(string) From b89d827ad30419153f9232abe436f3a071209810 Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Mon, 27 Apr 2026 11:19:43 +0100 Subject: [PATCH 06/10] Run code through `terraform fmt`. --- modules/aws-backup-destination/backup_vault_lock.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aws-backup-destination/backup_vault_lock.tf b/modules/aws-backup-destination/backup_vault_lock.tf index ce3e75d..0509490 100644 --- a/modules/aws-backup-destination/backup_vault_lock.tf +++ b/modules/aws-backup-destination/backup_vault_lock.tf @@ -1,5 +1,5 @@ resource "aws_backup_vault_lock_configuration" "vault_lock" { - count = var.enable_vault_protection && var.resources_in_same_account ? 1 : 0 + count = var.enable_vault_protection && var.resources_in_same_account ? 1 : 0 backup_vault_name = aws_backup_vault.vault[0].name changeable_for_days = var.vault_lock_type == "compliance" ? var.changeable_for_days : null From 87eff4aa0b81df228fc61c19253fc1c8a48250e7 Mon Sep 17 00:00:00 2001 From: Nick Miles Date: Fri, 17 Jul 2026 10:30:45 +0100 Subject: [PATCH 07/10] ENG-1290 Pinned action --- .github/workflows/cicd-1-pull-request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd-1-pull-request.yaml b/.github/workflows/cicd-1-pull-request.yaml index 90d1ede..df2e2d4 100644 --- a/.github/workflows/cicd-1-pull-request.yaml +++ b/.github/workflows/cicd-1-pull-request.yaml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout code" - uses: actions/checkout@v3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 From b3c6cda88e5be679ffa8c6260c9dc68654493a98 Mon Sep 17 00:00:00 2001 From: Nick Miles Date: Fri, 17 Jul 2026 10:38:02 +0100 Subject: [PATCH 08/10] ENG-1290 Run version check on all branches and bump to v1.5.0 --- .github/workflows/cicd-1-pull-request.yaml | 2 -- modules/aws-backup-source/version | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/cicd-1-pull-request.yaml b/.github/workflows/cicd-1-pull-request.yaml index df2e2d4..6cebd0b 100644 --- a/.github/workflows/cicd-1-pull-request.yaml +++ b/.github/workflows/cicd-1-pull-request.yaml @@ -9,8 +9,6 @@ on: jobs: check-version: - # Only enforce version bump on main branch pushes or version tag pushes - if: startsWith(github.ref, 'refs/heads/main') || startsWith(github.ref, 'refs/tags/v') name: "Check version" runs-on: ubuntu-latest steps: diff --git a/modules/aws-backup-source/version b/modules/aws-backup-source/version index c432e90..2e7bd91 100644 --- a/modules/aws-backup-source/version +++ b/modules/aws-backup-source/version @@ -1 +1 @@ -v1.4.2 +v1.5.0 From 233310113697460d59129c7c107d11be3f898383 Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Thu, 16 Jul 2026 13:34:45 +0100 Subject: [PATCH 09/10] Unify remote access variable. There where two variables for the same thing: * `enable_cross_account_vault_access`. * `enable_cross_account_role_permissions`. Use the latter.. + The IAM role and policy should be created IF we want resources in the same account OR (not AND!) we want cross-account permissions. --- modules/aws-backup-destination/iam.tf | 10 +++++----- modules/aws-backup-destination/variables.tf | 6 ------ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/modules/aws-backup-destination/iam.tf b/modules/aws-backup-destination/iam.tf index bcd7641..98514c0 100644 --- a/modules/aws-backup-destination/iam.tf +++ b/modules/aws-backup-destination/iam.tf @@ -1,6 +1,6 @@ ############################################# # Cross-account role for copy-recovery-point -# Created only when enable_cross_account_vault_access = true +# Created only when enable_cross_account_role_permissions = true ############################################# locals { @@ -8,7 +8,7 @@ locals { } data "aws_iam_policy_document" "copy_recovery_point_assume" { - count = var.enable_cross_account_vault_access ? 1 : 0 + count = var.enable_cross_account_role_permissions || var.resources_in_same_account ? 1 : 0 statement { effect = "Allow" @@ -31,7 +31,7 @@ data "aws_iam_policy_document" "copy_recovery_point_assume" { } resource "aws_iam_role" "copy_recovery_point" { - count = var.enable_cross_account_vault_access ? 1 : 0 + count = var.enable_cross_account_role_permissions || var.resources_in_same_account ? 1 : 0 name = local.copy_recovery_role_name assume_role_policy = data.aws_iam_policy_document.copy_recovery_point_assume[0].json description = "Role assumed by source account lambda to start and describe AWS Backup copy jobs, also passed to AWS Backup service for execution" @@ -42,7 +42,7 @@ resource "aws_iam_role" "copy_recovery_point" { } data "aws_iam_policy_document" "copy_recovery_point_permissions" { - count = var.enable_cross_account_vault_access && var.resources_in_same_account ? 1 : 0 + count = var.enable_cross_account_role_permissions || var.resources_in_same_account ? 1 : 0 # Start copy job (resource-level supports recoveryPoint*) statement { @@ -90,7 +90,7 @@ data "aws_iam_policy_document" "copy_recovery_point_permissions" { } resource "aws_iam_role_policy" "copy_recovery_point_policy" { - count = var.enable_cross_account_vault_access ? 1 : 0 + count = var.enable_cross_account_role_permissions ? 1 : 0 name = "${local.copy_recovery_role_name}-policy" role = aws_iam_role.copy_recovery_point[0].id policy = data.aws_iam_policy_document.copy_recovery_point_permissions[0].json diff --git a/modules/aws-backup-destination/variables.tf b/modules/aws-backup-destination/variables.tf index bdc6b8e..dc43f44 100644 --- a/modules/aws-backup-destination/variables.tf +++ b/modules/aws-backup-destination/variables.tf @@ -95,12 +95,6 @@ variable "enable_cross_account_role_permissions" { default = false } -variable "enable_cross_account_vault_access" { - description = "Flag to enable cross account vault access for AWS Backup" - type = bool - default = false -} - # If we're building this for multiple environments in the same account, some things # should not be created. Such as the vault! There can be only one - the environment # vaults should all copy to this, main/backup/immutable vault. From 2910ac77e3d76d2745d3f56dcbf43d8b8099326d Mon Sep 17 00:00:00 2001 From: TurboNHS Date: Mon, 20 Jul 2026 09:14:58 +0100 Subject: [PATCH 10/10] Fix unnecessary duplication. --- modules/aws-backup-source/locals.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/aws-backup-source/locals.tf b/modules/aws-backup-source/locals.tf index 48530fd..4810fc3 100644 --- a/modules/aws-backup-source/locals.tf +++ b/modules/aws-backup-source/locals.tf @@ -14,11 +14,11 @@ locals { 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( - var.backup_plan_config.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.main[0].arn : aws_backup_framework.main[0].arn] : [], - var.backup_plan_config_ebsvol.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.ebsvol[0].arn : data.aws_backup_framework.ebsvol[0].arn] : [], - var.backup_plan_config_dynamodb.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.dynamodb[0].arn : data.aws_backup_framework.dynamodb[0].arn] : [], - var.backup_plan_config_aurora.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.aurora[0].arn : data.aws_backup_framework.aurora[0].arn] : [], - var.backup_plan_config_parameter_store.enable ? [var.resources_in_same_account == "" ? aws_backup_framework.parameter_store[0].arn : data.aws_backup_framework.parameter_store[0].arn] : [] + var.backup_plan_config.enable ? aws_backup_framework.main[0].arn : [], + var.backup_plan_config_ebsvol.enable ? data.aws_backup_framework.ebsvol[0].arn : [], + var.backup_plan_config_dynamodb.enable ? data.aws_backup_framework.dynamodb[0].arn : [], + var.backup_plan_config_aurora.enable ? data.aws_backup_framework.aurora[0].arn : [], + var.backup_plan_config_parameter_store.enable ? data.aws_backup_framework.parameter_store[0].arn : [] )) aurora_overrides = var.backup_plan_config_aurora.restore_testing_overrides == null ? null : jsondecode(var.backup_plan_config_aurora.restore_testing_overrides)