diff --git a/.gitignore b/.gitignore index d569eb4..8eca51b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ .DS_Store *__pycache__ .github/instructions/memory.instructions.md + +# Local temporary files +tmp/ +temp/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f6239b..3b145a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [v1.4.8] (2026-07-29) + +### 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.7] (2026-07-22) ### Improvements diff --git a/README.md b/README.md index a96b5a1..1e440fa 100644 --- a/README.md +++ b/README.md @@ -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) @@ -97,7 +101,16 @@ I will assume that your project uses the [repository template structure](https:/ Similarly I will assume that you have your backup destination account configuration at `infrastructure/environments/dev-backup`. We'll configure that first. -Copy the `modules/aws-backup-source` and `modules/aws-backup-destination` directories into your `infrastructure/modules` directory, giving you `infrastructure/modules/aws-backup-source` and `infrastructure/modules/aws-backup-destination`. +Reference the `aws-backup-source` and `aws-backup-destination` modules directly from this repository rather than copying them into your own. Using a versioned module source ensures you receive updates and security fixes automatically: + +```terraform +module "source" { + source = "git::https://github.com/NHSDigital/terraform-aws-backup.git//modules/aws-backup-source?ref=v1.4.8" + # ... +} +``` + +Pin the `ref` to a release tag so that upgrades are deliberate. ### IAM roles @@ -239,7 +252,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: @@ -270,6 +283,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 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. diff --git a/examples/source/aws-backups.tf b/examples/source/aws-backups.tf index 75a3a6e..3d65523 100644 --- a/examples/source/aws-backups.tf +++ b/examples/source/aws-backups.tf @@ -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" - # 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" diff --git a/modules/aws-backup-source/README.md b/modules/aws-backup-source/README.md index 13cc678..6129c28 100644 --- a/modules/aws-backup-source/README.md +++ b/modules/aws-backup-source/README.md @@ -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 diff --git a/modules/aws-backup-source/version b/modules/aws-backup-source/version index ff1560e..d6379b8 100644 --- a/modules/aws-backup-source/version +++ b/modules/aws-backup-source/version @@ -1 +1 @@ -v1.4.7 +v1.4.8