diff --git a/modules/aws-backup-destination/parameter_store_kms.tf b/modules/aws-backup-destination/parameter_store_kms.tf index 374fda7..95a9a0e 100644 --- a/modules/aws-backup-destination/parameter_store_kms.tf +++ b/modules/aws-backup-destination/parameter_store_kms.tf @@ -39,7 +39,7 @@ resource "aws_kms_key" "parameter_store_key" { } resource "aws_kms_alias" "parameter_store_alias" { - name = "alias/parameter-store-backup-key" + name = var.name_prefix != null ? "alias/${var.name_prefix}-parameter-store-backup-key" : "alias/${var.source_account_name}-parameter-store-backup-key" target_key_id = aws_kms_key.parameter_store_key.key_id } diff --git a/modules/aws-backup-source/README.md b/modules/aws-backup-source/README.md index 2a1c461..655cac5 100644 --- a/modules/aws-backup-source/README.md +++ b/modules/aws-backup-source/README.md @@ -60,6 +60,7 @@ No modules. | [aws_kms_key.aws_backup_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | | [aws_sns_topic.backup](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | | [aws_sns_topic_subscription.aws_backup_notifications_email_target](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource | +| [aws_sns_topic_subscription.aws_backup_notifications](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource | | [awscc_backup_restore_testing_plan.backup_restore_testing_plan](https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/backup_restore_testing_plan) | resource | | [awscc_backup_restore_testing_selection.backup_restore_testing_selection_dynamodb](https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/backup_restore_testing_selection) | resource | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | @@ -84,6 +85,7 @@ No modules. | [environment\_name](#input\_environment\_name) | The name of the environment where AWS Backup is configured. | `string` | n/a | yes | | [name\_prefix](#input\_name\_prefix) | Optional name prefix for vault resources | `string` | `null` | no | | [notifications\_target\_email\_address](#input\_notifications\_target\_email\_address) | The email address to which backup notifications will be sent via SNS. | `string` | `""` | no | +| [notifications\_target](#input\_notifications\_target) | Additional endpoints to send backup notifications via SNS | `string` | `""` | no | | [project\_name](#input\_project\_name) | The name of the project this relates to. | `string` | n/a | yes | | [reports\_bucket](#input\_reports\_bucket) | Bucket to drop backup reports into | `string` | n/a | yes | | [restore\_testing\_plan\_algorithm](#input\_restore\_testing\_plan\_algorithm) | Algorithm of the Recovery Selection Point | `string` | `"LATEST_WITHIN_WINDOW"` | no | @@ -95,6 +97,11 @@ No modules. ## Outputs -No outputs. +| Name | Description | +|---------------------------------| -------------------------| +| backup_role_arn | ARN of the of the backup role | +| backup_vault_arn | ARN of the of the Backup Vault | +| backup_vault_name | Name of the of the Backup Vault | +| backup_sns_topic_arn | ARN of SNS topic to which the Backup events are being send to | diff --git a/modules/aws-backup-source/backup_notification.tf b/modules/aws-backup-source/backup_notification.tf index cb71232..f6f2350 100644 --- a/modules/aws-backup-source/backup_notification.tf +++ b/modules/aws-backup-source/backup_notification.tf @@ -1,5 +1,5 @@ resource "aws_backup_vault_notifications" "backup_notification" { - count = var.notifications_target_email_address != "" ? 1 : 0 + count = local.enable_sns_notifications ? 1 : 0 backup_vault_name = aws_backup_vault.main.name sns_topic_arn = aws_sns_topic.backup[0].arn backup_vault_events = [ diff --git a/modules/aws-backup-source/backup_plan.tf b/modules/aws-backup-source/backup_plan.tf index 4e7a671..ea0bff5 100644 --- a/modules/aws-backup-source/backup_plan.tf +++ b/modules/aws-backup-source/backup_plan.tf @@ -27,6 +27,10 @@ resource "aws_backup_plan" "default" { } } } + + tags = { + "environment_name" = var.environment_name + } } # this backup plan shouldn't include a continous backup rule as it isn't supported for DynamoDB @@ -59,6 +63,10 @@ resource "aws_backup_plan" "dynamodb" { } } } + + tags = { + "environment_name" = var.environment_name + } } resource "aws_backup_plan" "ebsvol" { @@ -89,9 +97,13 @@ resource "aws_backup_plan" "ebsvol" { } } } + + tags = { + "environment_name" = var.environment_name + } } -# this backup plan shouldn't include a continous backup rule as it isn't supported for Aurora +# this backup plan shouldn't include a continuous backup rule as it isn't supported for Aurora resource "aws_backup_plan" "aurora" { count = var.backup_plan_config_aurora.enable ? 1 : 0 name = "${local.resource_name_prefix}-aurora-plan" @@ -120,6 +132,10 @@ resource "aws_backup_plan" "aurora" { } } } + + tags = { + "environment_name" = var.environment_name + } } @@ -153,6 +169,10 @@ resource "aws_backup_plan" "parameter_store" { } } } + + tags = { + "environment_name" = var.environment_name + } } @@ -230,7 +250,7 @@ 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 } } diff --git a/modules/aws-backup-source/backup_restore_testing.tf b/modules/aws-backup-source/backup_restore_testing.tf index b6389fc..2e94756 100644 --- a/modules/aws-backup-source/backup_restore_testing.tf +++ b/modules/aws-backup-source/backup_restore_testing.tf @@ -20,7 +20,7 @@ resource "awscc_backup_restore_testing_selection" "backup_restore_testing_select protected_resource_conditions = { string_equals = [{ key = "aws:ResourceTag/${var.backup_plan_config_dynamodb.selection_tag}" - value = "True" + value = (var.backup_plan_config_dynamodb.selection_tag_value == null) ? "True" : var.backup_plan_config_dynamodb.selection_tag_value }] } } @@ -36,7 +36,7 @@ resource "awscc_backup_restore_testing_selection" "backup_restore_testing_select protected_resource_conditions = { string_equals = [{ key = "aws:ResourceTag/${var.backup_plan_config_ebsvol.selection_tag}" - value = "True" + value = (var.backup_plan_config_ebsvol.selection_tag_value == null) ? "True" : var.backup_plan_config_ebsvol.selection_tag_value }] } } @@ -51,7 +51,7 @@ resource "awscc_backup_restore_testing_selection" "backup_restore_testing_select protected_resource_conditions = { string_equals = [{ key = "aws:ResourceTag/${var.backup_plan_config_aurora.selection_tag}" - value = "True" + value = (var.backup_plan_config_aurora.selection_tag_value == null) ? "True" : var.backup_plan_config_aurora.selection_tag_value }] } restore_metadata_overrides = local.aurora_overrides diff --git a/modules/aws-backup-source/locals.tf b/modules/aws-backup-source/locals.tf index 39d37d0..cb8fdc2 100644 --- a/modules/aws-backup-source/locals.tf +++ b/modules/aws-backup-source/locals.tf @@ -16,6 +16,7 @@ locals { var.backup_plan_config_parameter_store.enable ? [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] + 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] + enable_sns_notifications = var.notifications_target_email_address != "" || var.notifications_targets != {} } diff --git a/modules/aws-backup-source/outputs.tf b/modules/aws-backup-source/outputs.tf index 96ab936..d998360 100644 --- a/modules/aws-backup-source/outputs.tf +++ b/modules/aws-backup-source/outputs.tf @@ -5,10 +5,16 @@ output "backup_role_arn" { output "backup_vault_arn" { value = aws_backup_vault.main.arn - description = "ARN of the of the vault" + description = "ARN of the of the Backup Vault" } output "backup_vault_name" { value = aws_backup_vault.main.name - description = "Name of the of the vault" + description = "Name of the of the Backup Vault" } + +output "backup_sns_topic_arn" { + value = local.enable_sns_notifications ? aws_sns_topic.backup[0].arn : null + description = "ARN of SNS topic to which the Backup events are being send to" +} + diff --git a/modules/aws-backup-source/sns.tf b/modules/aws-backup-source/sns.tf index cdfec7f..307c617 100644 --- a/modules/aws-backup-source/sns.tf +++ b/modules/aws-backup-source/sns.tf @@ -1,5 +1,5 @@ resource "aws_sns_topic" "backup" { - count = var.notifications_target_email_address != "" ? 1 : 0 + count = local.enable_sns_notifications ? 1 : 0 name = "${local.resource_name_prefix}-notifications" kms_master_key_id = var.bootstrap_kms_key_arn policy = data.aws_iam_policy_document.allow_backup_to_sns.json @@ -33,3 +33,11 @@ resource "aws_sns_topic_subscription" "aws_backup_notifications_email_target" { endpoint = var.notifications_target_email_address filter_policy = jsonencode({ "State" : [{ "anything-but" : "COMPLETED" }] }) } + +resource "aws_sns_topic_subscription" "aws_backup_notifications_targets" { + for_each = var.notifications_targets + topic_arn = aws_sns_topic.backup[0].arn + protocol = each.value.protocol + endpoint = each.value.endpoint + filter_policy = jsonencode({ "State" : [{ "anything-but" : "COMPLETED" }] }) +} diff --git a/modules/aws-backup-source/variables.tf b/modules/aws-backup-source/variables.tf index d99aa10..6cae8d9 100644 --- a/modules/aws-backup-source/variables.tf +++ b/modules/aws-backup-source/variables.tf @@ -9,11 +9,21 @@ variable "environment_name" { } variable "notifications_target_email_address" { - description = "The email address to which backup notifications will be sent via SNS." + description = "The email address to which backup notifications will be sent via SNS" type = string default = "" } + +variable "notifications_targets" { + description = "Additional endpoints to send backup notifications via SNS" + type = map(object({ + protocol = string + endpoint = string + })) + default = {} +} + variable "bootstrap_kms_key_arn" { description = "The ARN of the bootstrap KMS key used for encryption at rest of the SNS topic." type = string @@ -307,6 +317,7 @@ variable "backup_plan_config_aurora" { type = object({ enable = bool selection_tag = string + selection_tag_value = optional(string) compliance_resource_types = list(string) restore_testing_overrides = optional(string) rules = optional(list(object({