Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [v1.5.0] (2026-07-30)

### Features

- Add optional `create_framework` toggle (default `true`) to each backup plan config so backup frameworks can be managed independently from plan enablement

### Bug Fixes

- Guard framework ARN aggregation with `enable && create_framework` to avoid invalid index references when frameworks are disabled

### Improvements

- Align Aurora selection behavior with other resource types by supporting `selection_tag_value` and `selection_tags`
- Align restore testing selection tag filters (DynamoDB, EBS, Aurora) to derive from local null-checked tag lists instead of hardcoded `"True"`

## [v1.4.9] (2026-07-29)

### Documentation
Expand Down
10 changes: 5 additions & 5 deletions modules/aws-backup-source/backup_framework.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
resource "aws_backup_framework" "main" {
count = var.backup_plan_config.enable ? 1 : 0
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", "-", "_")
Expand Down Expand Up @@ -134,7 +134,7 @@ resource "aws_backup_framework" "main" {
}

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"
Expand Down Expand Up @@ -175,7 +175,7 @@ resource "aws_backup_framework" "dynamodb" {
}

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"
Expand Down Expand Up @@ -216,7 +216,7 @@ resource "aws_backup_framework" "ebsvol" {
}

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"
Expand Down Expand Up @@ -256,7 +256,7 @@ resource "aws_backup_framework" "aurora" {
}

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"
Expand Down
12 changes: 11 additions & 1 deletion modules/aws-backup-source/backup_plan.tf
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,17 @@ 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 = local.selection_tags_aurora_null_checked
content {
key = (try(string_equals.value.key, null) == null) ? null : "aws:ResourceTag/${string_equals.value.key}"
value = try(string_equals.value.value, null)
}
}
}
}

Expand Down
54 changes: 42 additions & 12 deletions modules/aws-backup-source/backup_restore_testing.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,20 @@ 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(
[
for tag in local.selection_tags_dynamodb_null_checked : {
key = "aws:ResourceTag/${tag.key}"
value = tag.value
}
],
[
{
key = "aws:ResourceTag/${var.backup_plan_config_dynamodb.selection_tag}"
value = local.selection_tag_value_dynamodb_null_checked
}
]
)
}
}

Expand All @@ -34,10 +44,20 @@ 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(
[
for tag in local.selection_tags_ebsvol_null_checked : {
key = "aws:ResourceTag/${tag.key}"
value = tag.value
}
],
[
{
key = "aws:ResourceTag/${var.backup_plan_config_ebsvol.selection_tag}"
value = local.selection_tag_value_ebsvol_null_checked
}
]
)
}
}

Expand All @@ -49,10 +69,20 @@ 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(
[
for tag in local.selection_tags_aurora_null_checked : {
key = "aws:ResourceTag/${tag.key}"
value = tag.value
}
],
[
{
key = "aws:ResourceTag/${var.backup_plan_config_aurora.selection_tag}"
value = local.selection_tag_value_aurora_null_checked
}
]
)
}
restore_metadata_overrides = local.aurora_overrides
}
27 changes: 15 additions & 12 deletions modules/aws-backup-source/locals.tf
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
locals {
resource_name_prefix = var.name_prefix != null ? var.name_prefix : "${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
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_tags_null_checked = (var.backup_plan_config.selection_tags == null) ? [] : var.backup_plan_config.selection_tags
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_dynamodb_null_checked = (var.backup_plan_config_dynamodb.selection_tags == null) ? [] : 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) ? [] : 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(
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] : [],
var.backup_plan_config_parameter_store.enable ? [aws_backup_framework.parameter_store[0].arn] : []
selection_tags_parameter_store_null_checked = (var.backup_plan_config_parameter_store.selection_tags == null) ? [] : var.backup_plan_config_parameter_store.selection_tags
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_tags_aurora_null_checked = (var.backup_plan_config_aurora.selection_tags == null) ? [] : var.backup_plan_config_aurora.selection_tags

framework_arn_list = flatten(concat(
Comment thread
hirra-farooq marked this conversation as resolved.
var.backup_plan_config.enable && var.backup_plan_config.create_framework ? [aws_backup_framework.main[0].arn] : [],
var.backup_plan_config_ebsvol.enable && var.backup_plan_config_ebsvol.create_framework ? [aws_backup_framework.ebsvol[0].arn] : [],
var.backup_plan_config_dynamodb.enable && var.backup_plan_config_dynamodb.create_framework ? [aws_backup_framework.dynamodb[0].arn] : [],
var.backup_plan_config_aurora.enable && var.backup_plan_config_aurora.create_framework ? [aws_backup_framework.aurora[0].arn] : [],
var.backup_plan_config_parameter_store.enable && var.backup_plan_config_parameter_store.create_framework ? [aws_backup_framework.parameter_store[0].arn] : [],
var.framework_arns
))
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]
Expand Down
16 changes: 16 additions & 0 deletions modules/aws-backup-source/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ variable "backup_plan_config" {
value = optional(string)
})))
compliance_resource_types = optional(list(string))
create_framework = optional(bool, true)
rules = optional(list(object({
name = string
schedule = string
Expand Down Expand Up @@ -174,6 +175,7 @@ variable "backup_plan_config_dynamodb" {
value = optional(string)
})))
compliance_resource_types = optional(list(string))
create_framework = optional(bool, true)
rules = optional(list(object({
name = string
schedule = string
Expand Down Expand Up @@ -251,6 +253,7 @@ variable "backup_plan_config_ebsvol" {
value = optional(string)
})))
compliance_resource_types = optional(list(string))
create_framework = optional(bool, true)
rules = optional(list(object({
name = string
schedule = string
Expand Down Expand Up @@ -309,6 +312,12 @@ variable "backup_plan_config_aurora" {
type = object({
enable = bool
selection_tag = optional(string)
selection_tag_value = optional(string)
selection_tags = optional(list(object({
key = optional(string)
value = optional(string)
})))
create_framework = optional(bool, true)
compliance_resource_types = optional(list(string))
restore_testing_overrides = optional(string)
rules = optional(list(object({
Expand Down Expand Up @@ -374,6 +383,7 @@ variable "backup_plan_config_parameter_store" {
key = optional(string)
value = optional(string)
})))
create_framework = optional(bool, true)
lambda_backup_cron = optional(string)
lambda_timeout_seconds = optional(number)
rules = optional(list(object({
Expand Down Expand Up @@ -445,6 +455,12 @@ variable "backup_plan_config_parameter_store" {
}
}

variable "framework_arns" {
description = "List of ARNs of backup frameworks to associate with the backup plan."
type = list(string)
default = []
}

variable "iam_role_permissions_boundary" {
description = "Optional permissions boundary ARN for backup role"
type = string
Expand Down
2 changes: 1 addition & 1 deletion modules/aws-backup-source/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.4.9
v1.5.0