diff --git a/modules/aws-backup-source/backup_framework.tf b/modules/aws-backup-source/backup_framework.tf index 19a2803..66bc13e 100644 --- a/modules/aws-backup-source/backup_framework.tf +++ b/modules/aws-backup-source/backup_framework.tf @@ -1,4 +1,12 @@ +# There can be only one [framework with x controls in one account]! + +data "aws_backup_framework" "main" { + count = var.backup_plan_config.enable && var.backup_plan_config.create_framework ? 1 : 0 + name = replace("${local.resource_name_prefix}-framework", "-", "_") +} resource "aws_backup_framework" "main" { + count = var.backup_plan_config.enable && var.backup_plan_config.create_framework ? 1 : 0 + # must be underscores instead of dashes name = replace("${local.resource_name_prefix}-framework", "-", "_") description = "${var.project_name} Backup Framework" @@ -131,8 +139,12 @@ resource "aws_backup_framework" "main" { } } +data "aws_backup_framework" "dynamodb" { + count = var.backup_plan_config_dynamodb.enable && var.backup_plan_config_dynamodb.create_framework ? 1 : 0 + name = replace("${local.resource_name_prefix}-dynamodb-framework", "-", "_") +} resource "aws_backup_framework" "dynamodb" { - count = var.backup_plan_config_dynamodb.enable ? 1 : 0 + count = var.backup_plan_config_dynamodb.enable && var.backup_plan_config_dynamodb.create_framework ? 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 +184,12 @@ resource "aws_backup_framework" "dynamodb" { } } +data "aws_backup_framework" "ebsvol" { + count = var.backup_plan_config_ebsvol.enable && var.backup_plan_config_ebsvol.create_framework ? 1 : 0 + name = replace("${local.resource_name_prefix}-ebsvol-framework", "-", "_") +} resource "aws_backup_framework" "ebsvol" { - count = var.backup_plan_config_ebsvol.enable ? 1 : 0 + count = var.backup_plan_config_ebsvol.enable && var.backup_plan_config_ebsvol.create_framework ? 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 +229,12 @@ resource "aws_backup_framework" "ebsvol" { } } +data "aws_backup_framework" "aurora" { + count = var.backup_plan_config_aurora.enable && var.backup_plan_config_aurora.create_framework ? 1 : 0 + name = replace("${local.resource_name_prefix}-aurora-framework", "-", "_") +} resource "aws_backup_framework" "aurora" { - count = var.backup_plan_config_aurora.enable ? 1 : 0 + count = var.backup_plan_config_aurora.enable && var.backup_plan_config_aurora.create_framework ? 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 +273,12 @@ resource "aws_backup_framework" "aurora" { } } +data "aws_backup_framework" "parameter_store" { + count = var.backup_plan_config_parameter_store.enable && var.backup_plan_config_parameter_store.create_framework ? 1 : 0 + name = replace("${local.resource_name_prefix}-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.backup_plan_config_parameter_store.create_framework ? 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 +316,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..c45429c 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_report_plan.tf b/modules/aws-backup-source/backup_report_plan.tf index 5a6e128..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 ? "${replace(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 ? "${replace(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 ? "${replace(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 ? "${replace(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..7ddba1c 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 = { @@ -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/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..4810fc3 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.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_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_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_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] : [] + 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 ? 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) + + 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 0cd2f94..f062ca4 100644 --- a/modules/aws-backup-source/variables.tf +++ b/modules/aws-backup-source/variables.tf @@ -95,6 +95,7 @@ variable "backup_plan_config" { value = optional(string) }))) compliance_resource_types = list(string) + create_framework = optional(bool, true) rules = list(object({ name = string schedule = string @@ -172,6 +173,7 @@ variable "backup_plan_config_dynamodb" { value = optional(string) }))) compliance_resource_types = list(string) + create_framework = optional(bool, true) rules = optional(list(object({ name = string schedule = string @@ -249,6 +251,7 @@ variable "backup_plan_config_ebsvol" { value = optional(string) }))) compliance_resource_types = list(string) + create_framework = optional(bool, true) rules = optional(list(object({ name = string schedule = string @@ -265,6 +268,7 @@ variable "backup_plan_config_ebsvol" { default = { enable = true selection_tag = "BackupEBSVol" + selection_tag_value = "True" compliance_resource_types = ["EBS"] rules = [ { @@ -305,10 +309,16 @@ variable "backup_plan_config_ebsvol" { variable "backup_plan_config_aurora" { description = "Configuration for backup plans with aurora" type = object({ - enable = bool - 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) restore_testing_overrides = optional(string) + create_framework = optional(bool, true) rules = optional(list(object({ name = string schedule = string @@ -325,6 +335,8 @@ variable "backup_plan_config_aurora" { default = { enable = true selection_tag = "BackupAurora" + selection_tag_value = "True" + selection_tags = [] compliance_resource_types = ["Aurora"] rules = [ { @@ -374,6 +386,7 @@ variable "backup_plan_config_parameter_store" { }))) lambda_backup_cron = optional(string) lambda_timeout_seconds = optional(number) + create_framework = optional(bool, true) rules = optional(list(object({ name = string schedule = string @@ -520,3 +533,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 +}