Terraform module which creates AWS Backup resources on AWS: vault, vault lock, vault policy, notifications, logically air-gapped vault, IAM role, backup plans and resource selections. Report plans, restore testing plans and Audit Manager frameworks are provided as standalone submodules.
module "backup" {
source = "bgauduch/backup/aws"
name = "application"
vault_kms_key_arn = "arn:aws:kms:eu-west-1:123456789012:key/12345678-1234-1234-1234-123456789012"
vault_lock_enabled = true
vault_lock_min_retention_days = 7
vault_lock_max_retention_days = 365
plans = {
daily = {
rules = [{
name = "daily"
schedule = "cron(0 5 * * ? *)"
start_window = 60
completion_window = 180
lifecycle = {
delete_after = 35
}
}]
selections = {
tagged = {
resources = ["*"]
selection_tags = [{ type = "STRINGEQUALS", key = "backup", value = "daily" }]
}
}
}
}
tags = {
Terraform = "true"
Environment = "dev"
}
}- Backup vault encrypted with the AWS managed key or a customer managed KMS key, with vault lock in governance or compliance mode, vault policy for cross-account copies and SNS notifications
- Logically air-gapped vault
- IAM role assumed by AWS Backup with the AWS managed backup and restore policies, extensible with managed or inline policies, or an existing role
- Backup plans with multiple rules, lifecycle with cold storage and archive tiers, copy actions across regions and accounts, Windows VSS
- Resource selections by ARN, by tag and by condition
- Submodules for standalone plans, report plans, restore testing plans and Audit Manager frameworks
- Native
terraform testsuite with mocked providers and an end-to-end backup and restore test with Terratest
The module supports conditional resource creation:
module "backup" {
source = "bgauduch/backup/aws"
create = false
}The vault is encrypted with the AWS managed key aws/backup unless vault_kms_key_arn is set. The module never creates a KMS key: the key policy of a customer managed key must allow the IAM role assumed by AWS Backup to use the key and to create grants for AWS resources. See the complete example for a working key policy.
vault_copy_source_account_ids adds a statement allowing each account to copy recovery points into the vault. attach_vault_policy and vault_policy attach a full policy document, merged with the generated statements.
module "backup" {
source = "bgauduch/backup/aws"
name = "central"
vault_copy_source_account_ids = ["111111111111", "222222222222"]
}vault_lock_enabled creates a vault lock in governance mode: retention bounds are enforced, and the lock can be removed by a principal holding backup:DeleteBackupVaultLockConfiguration. Setting vault_lock_changeable_for_days switches the lock to compliance mode: once the lock date is reached, neither the lock nor the vault can be deleted, by anyone. See the AWS Backup Vault Lock documentation.
Any lock, governance mode included, rejects manual deletion of recovery points and on-demand backup jobs whose lifecycle falls outside the retention bounds. vault_force_destroy cannot empty a locked vault: remove the lock configuration first.
vault_notifications_enabled and vault_notifications_sns_topic_arn subscribe an SNS topic to the vault events listed in vault_notifications_events. The topic policy must allow backup.amazonaws.com to publish; the module does not manage the topic.
The module creates an IAM role assumed by backup.amazonaws.com with the AWS managed backup and restore policies, including the S3 ones unless iam_role_attach_s3_policies is false. Extra managed policies go in iam_role_additional_policy_arns and an inline policy in iam_role_additional_policy_json with create_iam_role_additional_policy, for KMS permissions on the keys of the protected resources for example. Set create_iam_role = false and iam_role_arn to use an existing role; a plan can also override the role through plans.<key>.iam_role_arn.
plans is a map of backup plans. Each plan holds a list of rules, with a schedule, windows, lifecycle and copy actions, and a map of selections assigning resources by ARN, by tag or by condition. Plans and selections are created through the plan sub-module, which can be used on its own against an existing vault.
Set create_vault = false and existing_vault_name to target a vault managed elsewhere. Plans and notifications then use that vault; the lock configuration and the vault policy are not managed.
- plan - Manages one backup plan with its rules and resource selections against an existing vault
- report - Manages report plans delivered to an existing S3 bucket
- restore-testing - Manages a restore testing plan and its selections
- framework - Manages an AWS Backup Audit Manager framework and its controls
- Simple - Vault, IAM role and a daily plan selecting resources by tag
- Complete - Customer managed KMS key, governance vault lock, cross-account copy policy, SNS notifications, air-gapped vault, multi-rule plan
- Cross-region copy - Secondary vault in another region fed by a copy action
- Plan - Plan submodule against an existing vault and role
- Report - Job report plans delivered to an S3 bucket
- Restore testing - Weekly restore tests of the protected DynamoDB tables
- Framework - AWS Backup Audit Manager controls
For managing multiple similar resources, see wrappers.
Unit tests run against mocked providers and need no AWS credentials:
terraform init -backend=false
terraform test -filter=tests/unit_root.tftest.hclIntegration tests (tests/integration_*.tftest.hcl) and the Terratest suite in tests/e2e deploy the examples in a real account, run an on-demand backup and restore of a DynamoDB table, and destroy everything, recovery points included:
terraform test -filter=tests/integration_root.tftest.hcl
cd tests/e2e && go test -v -timeout 120m ./...| Name | Version |
|---|---|
| terraform | >= 1.9 |
| aws | >= 6.24 |
| Name | Version |
|---|---|
| aws | >= 6.24 |
| Name | Source | Version |
|---|---|---|
| plan | ./modules/plan | n/a |
| Name | Type |
|---|---|
| aws_backup_logically_air_gapped_vault.this | resource |
| aws_backup_vault.this | resource |
| aws_backup_vault_lock_configuration.this | resource |
| aws_backup_vault_notifications.this | resource |
| aws_backup_vault_policy.this | resource |
| aws_iam_role.this | resource |
| aws_iam_role_policy.additional | resource |
| aws_iam_role_policy_attachment.this | resource |
| aws_iam_policy_document.assume_role | data source |
| aws_iam_policy_document.vault | data source |
| aws_partition.current | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| name | Name used as the default for the vault, the IAM role and the air-gapped vault | string |
n/a | yes |
| air_gapped_vault_kms_key_arn | ARN of the KMS key used to encrypt the logically air-gapped vault. Defaults to the AWS managed key | string |
null |
no |
| air_gapped_vault_max_retention_days | The maximum retention period, in days, that the logically air-gapped vault retains its recovery points | number |
35 |
no |
| air_gapped_vault_min_retention_days | The minimum retention period, in days, that the logically air-gapped vault retains its recovery points | number |
7 |
no |
| air_gapped_vault_name | Name of the logically air-gapped vault. Defaults to <name>-air-gapped |
string |
null |
no |
| attach_vault_policy | Determines whether vault_policy is attached to the backup vault. The statements generated from vault_copy_source_account_ids are attached regardless |
bool |
false |
no |
| create | Determines whether resources will be created (affects all resources) | bool |
true |
no |
| create_air_gapped_vault | Determines whether a logically air-gapped vault is created | bool |
false |
no |
| create_iam_role | Determines whether the IAM role assumed by AWS Backup is created. Set to false to use iam_role_arn |
bool |
true |
no |
| create_iam_role_additional_policy | Determines whether iam_role_additional_policy_json is attached inline to the IAM role |
bool |
false |
no |
| create_vault | Determines whether a backup vault is created. Set to false to target an existing vault through existing_vault_name |
bool |
true |
no |
| existing_vault_name | Name of an existing backup vault targeted by the plans and notifications when create_vault is false |
string |
null |
no |
| iam_role_additional_policy_arns | List of additional IAM policy ARNs attached to the IAM role, for example AWSBackupServiceRolePolicyForItemRestores |
list(string) |
[] |
no |
| iam_role_additional_policy_json | IAM policy document (JSON) attached inline to the IAM role when create_iam_role_additional_policy is true, for example KMS permissions on the keys of the protected resources |
string |
null |
no |
| iam_role_arn | ARN of an existing IAM role assumed by AWS Backup for the selections when create_iam_role is false. Can be overridden per plan |
string |
null |
no |
| iam_role_attach_s3_policies | Determines whether the AWS managed policies for S3 backup and restore are attached to the IAM role | bool |
true |
no |
| iam_role_name | Name of the IAM role. Defaults to <name>-backup |
string |
null |
no |
| iam_role_path | Path of the IAM role | string |
null |
no |
| iam_role_permissions_boundary | ARN of the policy used as the permissions boundary of the IAM role | string |
null |
no |
| plans | Map of backup plans to create, keyed by plan name. Each plan has one or more rules and zero or more selections:- name: plan name, defaults to the map key- windows_vss_enabled: enable Windows VSS backup for EC2 instances- iam_role_arn: IAM role assumed by AWS Backup for the selections of this plan, defaults to the module role- rules[]: name, schedule (cron), schedule_expression_timezone, start_window, completion_window, enable_continuous_backup, recovery_point_tags, target_logically_air_gapped_backup_vault_arn, lifecycle (cold_storage_after, delete_after, opt_in_to_archive_for_supported_resources), copy_actions[] (destination_vault_arn, lifecycle)- selections{}: keyed by selection name: name, resources, not_resources, selection_tags[] (type, key, value), conditions (string_equals[], string_like[], string_not_equals[], string_not_like[] of key/value) |
map(object({ |
{} |
no |
| region | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | string |
null |
no |
| tags | A map of tags to add to all resources | map(string) |
{} |
no |
| vault_copy_source_account_ids | List of AWS account IDs allowed to copy recovery points into the backup vault (cross-account backup) | list(string) |
[] |
no |
| vault_force_destroy | Determines whether all recovery points stored in the vault are deleted so that the vault can be destroyed without error | bool |
false |
no |
| vault_kms_key_arn | ARN of the KMS key used to encrypt the backup vault. Defaults to the AWS managed key aws/backup. The key policy must allow AWS Backup to use the key |
string |
null |
no |
| vault_lock_changeable_for_days | The number of days before the lock date. When set, the vault lock is created in compliance mode and cannot be removed once the lock date is reached. Leave null for governance mode |
number |
null |
no |
| vault_lock_enabled | Determines whether a vault lock configuration is created on the backup vault | bool |
false |
no |
| vault_lock_max_retention_days | The maximum retention period, in days, that the vault retains its recovery points | number |
null |
no |
| vault_lock_min_retention_days | The minimum retention period, in days, that the vault retains its recovery points | number |
null |
no |
| vault_name | Name of the backup vault. Defaults to name |
string |
null |
no |
| vault_notifications_enabled | Determines whether the backup vault events are sent to vault_notifications_sns_topic_arn |
bool |
false |
no |
| vault_notifications_events | List of backup vault events sent to the SNS topic | list(string) |
[ |
no |
| vault_notifications_sns_topic_arn | ARN of the SNS topic that receives the backup vault events when vault_notifications_enabled is true. The topic policy must allow backup.amazonaws.com to publish |
string |
null |
no |
| vault_policy | IAM policy document (JSON) applied to the backup vault when attach_vault_policy is true. Merged with the statements generated from vault_copy_source_account_ids |
string |
null |
no |
| Name | Description |
|---|---|
| air_gapped_vault_arn | The ARN of the logically air-gapped vault |
| air_gapped_vault_id | The name of the logically air-gapped vault |
| iam_role_arn | The ARN of the IAM role used by backup selections, created or provided |
| iam_role_name | The name of the IAM role created by the module |
| plans | Map of backup plans created, keyed by plan key, with id, arn and version |
| selections | Map of backup selection IDs, keyed by <plan key>/<selection key> |
| vault_arn | The ARN of the backup vault |
| vault_id | The name of the backup vault |
| vault_lock_configuration_id | The name of the vault the lock configuration applies to |
| vault_name | The name of the vault targeted by the backup plans, created or provided |
| vault_recovery_points | The number of recovery points stored in the backup vault |
Module is maintained by Baptiste Gauduchon.
Apache 2 Licensed. See LICENSE for full details.