Skip to content
Open
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@
.DS_Store
*__pycache__
.github/instructions/memory.instructions.md

# Local temporary files
tmp/
temp/
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [v1.4.7] (2026-07-23)

### Documentation

- Add Tagging Strategy section to README covering `selection_tag` configuration, multi-environment guidance, `selection_tags` AND-filter usage, and compliance framework limitations


## [v1.4.6] (2026-07-22)

### Features
Expand Down
91 changes: 90 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
- [IAM roles](#iam-roles)
- [Destination account configuration](#destination-account-configuration)
- [Source account configuration](#source-account-configuration)
- [Tagging Strategy](#tagging-strategy)
- [Choosing a selection tag](#choosing-a-selection-tag)
- [Multiple environments in the same account](#multiple-environments-in-the-same-account)
- [Additional tag filters (selection_tags)](#additional-tag-filters-selection_tags)
- [Next steps](#next-steps)
- [FAQs](#faqs)
- [Procedural notes](#procedural-notes)
Expand Down Expand Up @@ -239,7 +243,7 @@ The `name` is an arbitrary label. Change it to match the actual schedule. It wil

The `schedule` is a cron expression that determines when the backup will be taken. If you are unfamiliar with cron syntax, AWS document it [here](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html#eb-cron-expressions). In this example, the backup will be taken at midnight every day. If you are testing this configuration in a development environment, you may wish to change this to a more frequent schedule, or to a more convenient time of day.

The final detail to be aware of here is the `selection_tag`. This defines the tag that AWS Backup will use to determine which resources to back up, and which you will have seen above. Resources that you want to back up must have this tag. If you have followed the instructions above, you will have already tagged the resources you want to back up. The name of the tag has been chosen such that it is unlikely to conflict with any existing tags.
The final detail to be aware of here is the `selection_tag`. This defines the tag that AWS Backup will use to determine which resources to back up, and which you will have seen above. Resources that you want to back up must have this tag. If you have followed the instructions above, you will have already tagged the resources you want to back up. See the [Tagging Strategy](#tagging-strategy) section below for full guidance on choosing tag values.

The `aws-backup-source` module requires the ARN of the role in the destination account that terraform will assume to create the resources. This is passed in as the `destination_terraform_role_arn` variable. In my usage of the blueprint, this is passed in as an environment variable in the GitHub Actions pipeline. The terraform invocation looks like this:

Expand Down Expand Up @@ -270,6 +274,91 @@ The `aws-backup-source` module requires the ARN of the role in the destination a

When the earlier step wrote to the `$GITHUB_ENV` file, it wrote the `destination_vault_arn` output from the destination configuration. This is passed in as the `destination_vault_arn` variable to the source configuration, so we don't need to explicitly configure it here. Your CI/CD pipeline will need to ensure that the destination configuration is applied before the source configuration and that the `destination_vault_arn` output is passed along, and probably has a similar mechanism to the above.

## Tagging Strategy

The `selection_tag` variable controls which resources AWS Backup will protect. It is fully configurable — you can use any tag key and value that suits your project. The examples in this README use `NHSE-Enable-Backup` as the tag key with a value of `True`, but this is a recommendation, not a requirement.

### Choosing a selection tag

For **production** environments, we recommend using `NHSE-Enable-Backup` = `True` as the standard tag. This aligns with organisational reporting and makes it straightforward for centralised compliance dashboards to identify backed-up resources.

For **non-production** environments, you have flexibility:

- Use the same tag (`NHSE-Enable-Backup` = `True`) if you are going to create a single backup plan in the account.
- Use a different tag value (e.g. `NHSE-Enable-Backup` = `dev`) or a different tag key entirely (e.g. `BackupDev` = `True`) if you need to distinguish which resources belong to which environment's backup plan.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Use a different tag value (e.g. `NHSE-Enable-Backup` = `dev`) or a different tag key entirely (e.g. `BackupDev` = `True`) if you need to distinguish which resources belong to which environment's backup plan.
- Use a different tag values (e.g. `NHSE-Enable-Backup` = `dev`) or a different tag keys entirely (e.g. `BackupDev` = `True`) if you will have multiple backup plans in the account and need to distinguish which resources belong to which backup plan.


The tag value comparison is **case-sensitive**. `True`, `true`, and `TRUE` are all different values. The module defaults to `True`.

### Multiple environments in the same account

If you deploy multiple environments (e.g. dev, test, staging) into a single AWS account, each environment's backup module instance will create its own backup plan with a resource selection based on `selection_tag`. If all instances use the same tag, they will all select the same resources — which is usually not what you want.

The simplest approach is to **use a distinct `selection_tag` per environment**:

```terraform
# Dev environment
backup_plan_config = {
selection_tag = "BackupDev"
selection_tag_value = "True"
compliance_resource_types = ["S3"]
rules = [ ... ]
}

# Test environment
backup_plan_config = {
selection_tag = "BackupTest"
selection_tag_value = "True"
compliance_resource_types = ["S3"]
rules = [ ... ]
}
```

Alternatively, use the same tag key with different values:

```terraform
# Dev environment
backup_plan_config = {
selection_tag = "NHSE-Enable-Backup"
selection_tag_value = "dev"
compliance_resource_types = ["S3"]
rules = [ ... ]
}

# Test environment
backup_plan_config = {
selection_tag = "NHSE-Enable-Backup"
selection_tag_value = "test"
compliance_resource_types = ["S3"]
rules = [ ... ]
}
```

If all environments genuinely share the same retention requirements and schedules, consider deploying a **single module instance** with one shared tag. This avoids duplication and is the simplest configuration.

### Additional tag filters (selection_tags)

The `selection_tags` variable (plural) allows you to add extra tag conditions as a logical AND on top of the primary `selection_tag`. This is useful when you already have a broad backup tag on all resources but want to narrow the selection — for example, to only back up resources that are also tagged with a specific environment:

```terraform
backup_plan_config = {
selection_tag = "NHSE-Enable-Backup"
compliance_resource_types = ["S3"]
rules = [ ... ]
selection_tags = [
{
key = "Environment"
value = "production"
}
]
}
```

With this configuration, only resources tagged with BOTH `NHSE-Enable-Backup = True` AND `Environment = production` will be selected for backup.

**Known limitation:** The AWS Backup compliance framework evaluates resources based on the primary `selection_tag` only. It does not support filtering by multiple tags in its scope. This means that if you use `selection_tags` to narrow your backup selection, the framework may report false non-compliance for resources that have the primary tag but lack the additional tags. Those resources won't actually be backed up (because the plan requires all tags), but the framework will flag them as unprotected.

If you rely on framework compliance reports for operational dashboards, be aware of this gap. The recommended mitigation is to use distinct `selection_tag` values per environment (as described above) rather than relying on `selection_tags` for environment separation.

## Next steps

- If you haven't already, set up the appropriate steps in your CI/CD pipeline to deploy the destination and source configurations.
Expand Down
10 changes: 8 additions & 2 deletions examples/source/aws-backups.tf
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,15 @@ module "source" {
"schedule" : "cron(0 0 * * ? *)"
}
],
# selection_tag determines which resources this plan backs up.
# Use any tag key that suits your project. For production, we recommend "NHSE-Enable-Backup".
# For multi-environment accounts, use a distinct tag per environment to avoid plan collisions.
# See the Tagging Strategy section in the root README for full guidance.
"selection_tag" : "NHSE-Enable-Backup"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After speaking to Susana as well i think we should remove "selection_tags" section from the example to deter people from further using it. and potentially leave a comment saying further information and possible extensions of section_tags can be found in # See the Tagging Strategy section in the root README for full guidance.

# The selection_tags are optional and can be used to
# provide fine grained resource selection with existing tagging
# selection_tags (optional) adds extra tag conditions as a logical AND.
# Only resources matching ALL tags (selection_tag + selection_tags) will be backed up.
# Note: the compliance framework only evaluates the primary selection_tag, so using
# selection_tags for environment separation may cause false non-compliance reports.
"selection_tags" : [
{
"key" : "Environment"
Expand Down
2 changes: 2 additions & 0 deletions modules/aws-backup-source/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

The AWS Backup Module helps automates the setup of AWS Backup resources in a source account. It streamlines the process of creating, managing, and standardising backup configurations.

For guidance on choosing `selection_tag` values, multi-environment deployments, and the `selection_tags` additional filter feature, see the [Tagging Strategy](../../README.md#tagging-strategy) section in the root README.

## Example

```terraform
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.6
v1.4.7