This module implements one or more AWS Backup vaults and backup plans. For each vault/plan pair, you pass:
-
A list of resource ARNs (or ARN patterns) to back up (e.g. all RDS clusters, all EFS file systems, etc.)
-
A set of tags to include or exclude (e.g. {Environment = "prod", Backup = "true"}).
This lets you create separate vaults/plans per service (RDS, EFS, S3, etc.) with custom schedules, cross-region targets, and IAM roles.
- Features
- Prerequisites
- Inputs
- Usage
- Vault Naming Convention
- Notes
- AWS Backup Managed Policies
- Best Practices
- IAM Permissions
- Troubleshooting
- Contributing
- Code of Conduct
- Security Policy
- Backup Plans - Configurable scheduling with cron expressions
- Cross-Region Backup - Optional backup replication to different AWS regions
- IAM Role Management - Automatic service role creation with default policy attachments
- SNS Notifications - Optional backup job status notifications
To use this module, ensure you have the following:
- Terraform: ~> 1.12
- AWS Provider: ~> 5.0
- AWS Account: Configured with appropriate permissions
Name | Description | Type | Default | Required |
---|---|---|---|---|
region |
The AWS region where resources will be created. | string |
"us-east-1" |
❌ No |
start_window_minutes |
Time window (minutes) before starting a backup job. | number |
60 |
❌ No |
completion_window_minutes |
Maximum time (minutes) a backup job can run before being canceled. | number |
180 |
❌ No |
cross_region_backup_enabled |
Enable/disable cross-region backup copies. | bool |
false |
❌ No |
cross_region_destination |
Destination region for cross-region backups. | string |
"us-west-2" |
❌ No |
vault_name |
Name of the backup vault. | string |
"DefaultBackupVault" |
❌ No |
backup_schedule |
Cron expression for backup schedule. | string |
"cron(0 5 * * ? *)" (5 AM UTC) |
❌ No |
backup_schedule_timzone |
Timezone for the backup_schedule. Default:' Etc/UTC'. | string |
Etc/UTC | ❌ No |
sns_topic_arn |
SNS topic ARN for backup vault notifications. | string |
"" |
❌ No |
backup_selection_resource_arns |
Required list of specific resource ARNs or ARN patterns to include in backup selection. Must provide at least one ARN or ARN pattern. | list(string) |
["*"] |
❌ No |
backup_selection_conditions |
Optional conditions that will be applied tot he ARNs or ARN patterns to further restrict the resrouces targted. | object({string_equals, string_like, string_not_equals, string_not_like}) |
{string_equals = {}, string_list = {}, string_not_equals = {}, string_not_like = {}} |
❌ No |
additional_managed_policies |
Additional IAM policy ARNs (max 16) to attach to the backup service role. Combined with required AWS Backup policies (max 20 total). | list(string) |
[] |
❌ No |
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "cross_region"
region = "us-west-2"
}
module "efs_backup" {
source = "USSBA/backup-plans/aws"
version = "~> 9.0"
vault_name = "prod-efs-backup-vault"
backup_schedule = "cron(0 3 * * ? *)"
backup_selection_resource_arns = [
"arn:aws:elasticfilesystem:${var.region}:${data.aws_caller_identity.current.account_id}:file-system/*",
]
backup_selection_conditions = {
string_equals = {
"aws:ResourceTag/Environment" = "prod"
"aws:ResourceTag/BackupType" = "efs"
"aws:ResourceTag/Backup" = "true"
}
}
providers = {
aws.cross_region = aws.cross_region
}
}
module "rds_backup" {
source = "USSBA/backup-plans/aws"
version = "~> 9.0"-backup-vault"
backup_schedule = "cron(0 4 * * ? *)"
backup_selection_resource_arns = [
"arn:aws:rds:${var.region}:${data.aws_caller_identity.current.account_id}:cluster:*",
]
backup_selection_conditions = {
string_equals = {
"aws:ResourceTag/Environment" = "prod"
"aws:ResourceTag/BackupType" = "rds"
"aws:ResourceTag/Backup" = "true"
}
}
cross_region_backup_enabled = true
cross_region_destination = "us-west-2"
providers = {
aws.cross_region = aws.cross_region
}
}
- Tag Requirements: Resources must be tagged with whatever keys/values you pass to
backup_selection_conditions
. - Provider Configuration: Cross-region provider is required even if cross-region backup is disabled
- Use hyphens (
-
) as word separators in vault names (e.g.,production-backup-vault
) - Avoid using underscores (
_
) as they are being deprecated in favor of hyphens - Vault names must be between 1 and 50 characters long
- Must be unique within an AWS Region for your AWS account
When renaming a vault from using underscores to hyphens, follow these steps to ensure a smooth transition without data loss:
-
Create the New Vault
- Update your Terraform configuration with the new vault name using hyphens
- Run
terraform plan
to verify the changes - Apply the changes with
terraform apply
to create the new vault
-
Copy Backups to the New Vault
Use the AWS CLI to copy recovery points from the old vault to the new one:
# List recovery points in the old vault OLD_VAULT="old_vault_name" NEW_VAULT="new-vault-name" # Get list of recovery points RECOVERY_POINTS=$(aws backup list-recovery-points-by-backup-vault \ --backup-vault-name $OLD_VAULT \ --query 'RecoveryPoints[].RecoveryPointArn' \ --output text) # Copy each recovery point to the new vault for RP_ARN in $RECOVERY_POINTS; do BACKUP_JOB_ID=$(aws backup start-copy-job \ --recovery-point-arn $RP_ARN \ --source-backup-vault-name $OLD_VAULT \ --destination-backup-vault-arn arn:aws:backup:REGION:ACCOUNT_ID:backup-vault:$NEW_VAULT \ --iam-role-arn arn:aws:iam::ACCOUNT_ID:role/service-role/AWSBackupDefaultServiceRole \ --query 'CopyJobId' \ --output text) echo "Started copy job $BACKUP_JOB_ID for $RP_ARN" done
-
Verify the Copy Operations
# Check status of copy jobs aws backup describe-copy-job --copy-job-id YOUR_COPY_JOB_ID # List recovery points in the new vault to verify aws backup list-recovery-points-by-backup-vault --backup-vault-name $NEW_VAULT
-
Update References
- Update any IAM policies, backup plans, or other resources that reference the old vault name
- Update any monitoring or alerting systems
-
Retire the Old Vault (Optional)
- After verifying all backups are successfully copied and accessible in the new vault
- Consider removing the old vault if it's no longer needed
- You may want to keep it for a transition period to ensure everything works as expected
- Cold storage is currently only supported for backups of Amazon EBS, Amazon EFS, Amazon DynamoDB, Amazon Timestream, SAP HANA on EC2, and VMware Backup.
- Cold storage backup for DynamoDB is only available when you opt in to advanced features for DynamoDB.
- Resources that do not support cold storage will only be retained for the 30 days in warm storage.
This module automatically attaches the following AWS managed policies to the backup service role:
arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup
- Required for backup operationsarn:aws:iam::aws:policy/AWSBackupServiceRolePolicyForS3Backup
- Required for S3 backup operationsarn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores
- Required for restore operationsarn:aws:iam::aws:policy/AWSBackupServiceRolePolicyForS3Restore
- Required for S3 restore operations
You can attach up to 16 additional managed policies using the additional_managed_policies
variable. Here are some commonly used AWS managed policies for backup operations:
arn:aws:iam::aws:policy/AWSBackupFullAccess
- Full access to AWS Backup featuresarn:aws:iam::aws:policy/AWSBackupOperatorAccess
- Permissions for backup operatorsarn:aws:iam::aws:policy/AWSBackupAuditAccess
- Read-only access to view backup configurationsarn:aws:iam::aws:policy/AWSBackupServiceRolePolicyForBackup
- Permissions for backup operationsarn:aws:iam::aws:policy/AWSBackupServiceRolePolicyForRestores
- Permissions for restore operations
arn:aws:iam::aws:policy/AWSBackupServiceRolePolicyForS3Backup
- For S3 backup operationsarn:aws:iam::aws:policy/AWSBackupServiceRolePolicyForS3Restore
- For S3 restore operationsarn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackupTest
- For backup testingarn:aws:iam::aws:policy/AWSBackupServiceRolePolicyForSAPHANA
- For SAP HANA database backups
- Backup Vaults: 100 per AWS account per region (soft limit, can be increased)
- Backup Plans: 100 per AWS account per region
- Recovery Points: 100,000 per backup vault
- Resource Selection: 500 resources per backup plan
- Managed Policies per Role: 20 total (default limit of 10, can be increased to 20)
- Role Name Length: 64 characters maximum
- Policy Size: 6,144 characters maximum for managed policies
- Policy Document Size: 10,240 characters maximum
- Copy Jobs: 10,000 per account per region
- Concurrent Copy Jobs: 1,000 per account per region
Note: The default limit for managed policies per role is 10 (5 AWS-managed + 5 customer-managed). You can request an increase to 20 (10 AWS-managed + 10 customer-managed) through the AWS Support Center.
- Use meaningful, descriptive names for
vault_name
to easily identify resources. - Follow a consistent naming convention across all backup resources (e.g.,
{env}-{app}-{purpose}
) - Use tags consistently to manage and organize backup resources
- When using
additional_managed_policies
, ensure they don't exceed the 20-policy limit per role - Prefer using AWS managed policies over custom policies when possible
- Regularly review and audit IAM policies for least privilege access
- Use tag-based resource selection (
= true
) for dynamic environments - For static environments, consider using explicit resource ARNs for better control
- Use the
exclude_conditions
variable to filter out resources that shouldn't be backed up - When backing up S3 buckets, ensure versioning is enabled for point-in-time recovery
- Set up CloudWatch Alarms for backup job failures
- Monitor backup storage usage and retention periods
- Regularly test restores to ensure your backup strategy meets your recovery objectives
- Review and update backup policies as your infrastructure evolves
- Enable encryption for all backup vaults (enabled by default)
- Use AWS KMS CMKs for encryption when additional control over encryption keys is required
- Implement backup vault access policies to restrict who can manage backups
- Enable MFA delete for critical backup vaults
The IAM role created by this module requires the following permissions:
backup:CreateBackupVault
backup:CreateBackupPlan
backup:CreateBackupSelection
backup:StartBackupJob
backup:StartCopyJob
(if cross-region backup is enabled)- Plus various read permissions for resource discovery and monitoring
You can attach up to 16 additional managed policies to the backup service role. Some useful policies include:
module "backup-with-custom-policies" {
source = "USSBA/backup-plans/aws"
version = "~> 9.0"
additional_managed_policies = [
"arn:aws:iam::aws:policy/AmazonRDSFullAccess",
"arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess",
"arn:aws:iam::aws:policy/AmazonEFSFullAccess"
]
}
- Verify the IAM role has the necessary permissions
- Check if the role's trust relationship allows the backup service to assume it
- Ensure any additional policies attached don't conflict with required permissions
- Verify the resource tags match your backup selection criteria
- Check if the resource type is supported by AWS Backup
- Ensure the IAM role has permissions to back up the specific resource type
- Verify the destination region is enabled in your AWS account
- Check if there are any VPC endpoint or network ACL restrictions
- Ensure the IAM role has permissions to create resources in the destination region
We welcome contributions. To contribute please read our CONTRIBUTING document.
All contributions are subject to the license and in no way imply compensation for contributions.
We strive for a welcoming and inclusive environment for all SBA projects.
Please follow this guidelines in all interactions:
- Be Respectful: use welcoming and inclusive language.
- Assume best intentions: seek to understand other's opinions.
Please do not submit an issue on GitHub for a security vulnerability. Instead, contact the development team through HQVulnerabilityManagement. Be sure to include all pertinent information.
The agency reserves the right to change this policy at any time.