Skip to content

Terraform module to create AWS Backup plans. AWS Backup is a fully managed backup service that makes it easy to centralize and automate the back up of data across AWS services (EBS volumes, RDS databases, DynamoDB tables, EFS file systems, and Storage Gateway volumes).

License

Notifications You must be signed in to change notification settings

lgallard/terraform-aws-backup

Repository files navigation

Terraform

terraform-aws-backup

Terraform module to create AWS Backup plans. AWS Backup is a fully managed backup service that makes it easy to centralize and automate the back up of data across AWS services (EBS volumes, RDS databases, DynamoDB tables, EFS file systems, and Storage Gateway volumes).

Features

  • Flexible backup plan customization
  • Comprehensive backup management:
    • Rules and selections
    • Copy actions and lifecycle policies
    • Retention periods and windows
    • Resource tagging
  • Advanced capabilities:
    • IAM role management
    • Multi-region support
    • Vault management
    • Framework integration
    • Organization policies
  • Enterprise features:
    • Notifications system
    • Audit Manager integration
    • Cross-account backups
    • Compliance controls

Usage

You can use this module to create a simple plan using the module's rule_* variables. You can also use the rules and selections list of maps variables to build a more complete plan by defining several rules and selections at once.

Check the examples folder where you can see how to configure backup plans with different selection criteria.

Simple plan

# AWS SNS Topic
resource "aws_sns_topic" "backup_vault_notifications" {
  name = "backup-vault-events"
}

# AWS Backup
module "aws_backup_example" {
  source = "../.."

  # Vault
  vault_name = "vault-3"

  # Vault lock configuration
  min_retention_days = 7  # Minimum retention of 7 days
  max_retention_days = 90 # Maximum retention of 90 days

  # Plan
  plan_name = "simple-plan"

  # Multiple rules using a list of maps
  rules = [
    {
      name              = "rule-1"
      schedule          = "cron(0 12 * * ? *)"
      start_window      = 120
      completion_window = 360
      lifecycle = {
        cold_storage_after = 0
        delete_after       = 90
      }
      copy_actions = []
      recovery_point_tags = {
        Environment = "prod"
      }
    },
    {
      name              = "rule-2"
      target_vault_name = "Default"
      schedule          = "cron(0 7 * * ? *)"
      start_window      = 120
      completion_window = 360
      lifecycle = {
        cold_storage_after = 0
        delete_after       = 90
      }
      copy_actions = []
      recovery_point_tags = {
        Environment = "prod"
      }
    }
  ]

  # Multiple selections
  selections = [
    {
      name = "selection-1"
      resources = [
        "arn:aws:dynamodb:us-east-1:123456789101:table/mydynamodb-table1",
        "arn:aws:dynamodb:us-east-1:123456789101:table/mydynamodb-table2"
      ]
      selection_tags = [
        {
          type  = "STRINGEQUALS"
          key   = "Environment"
          value = "prod"
        }
      ]
    }
  ]

  tags = {
    Owner       = "backup team"
    Environment = "prod"
    Terraform   = true
  }
}

Simple plan using variables

# AWS SNS Topic
resource "aws_sns_topic" "backup_vault_notifications" {
  name = "backup-vault-events"
}

# AWS Backup
module "aws_backup_example" {
  source = "../.."

  # Vault
  vault_name = "vault-1"

  # Vault lock configuration
  min_retention_days = 7
  max_retention_days = 120

  # Plan
  plan_name = "simple-plan"

  # Rule
  rule_name                         = "rule-1"
  rule_schedule                     = "cron(0 12 * * ? *)"
  rule_start_window                 = 120
  rule_completion_window            = 360
  rule_lifecycle_cold_storage_after = 30
  rule_lifecycle_delete_after       = 120
  rule_recovery_point_tags = {
    Environment = "prod"
  }

  # Selection
  selection_name = "selection-1"
  selection_resources = [
    "arn:aws:dynamodb:us-east-1:123456789101:table/mydynamodb-table1",
    "arn:aws:dynamodb:us-east-1:123456789101:table/mydynamodb-table2"
  ]
  selection_tags = [
    {
      type  = "STRINGEQUALS"
      key   = "Environment"
      value = "prod"
    }
  ]

  # Tags
  tags = {
    Owner       = "backup team"
    Environment = "prod"
    Terraform   = true
  }
}

Complete plan

# AWS SNS Topic
resource "aws_sns_topic" "backup_vault_notifications" {
  name = "backup-vault-events"
}

# AWS Backup
module "aws_backup_example" {
  source = "../.."

  # Vault configuration
  vault_name          = "complete_vault"
  vault_kms_key_arn   = "arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"
  vault_force_destroy = true
  min_retention_days  = 7
  max_retention_days  = 360
  locked              = true
  changeable_for_days = 3

  # Backup plan configuration
  plan_name = "complete_backup_plan"

  # Backup rules configuration
  rules = [
    {
      name                     = "rule_1"
      schedule                 = "cron(0 5 ? * * *)"
      start_window             = 480
      completion_window        = 561
      enable_continuous_backup = false
      lifecycle = {
        cold_storage_after = 30
        delete_after       = 180
      }
      recovery_point_tags = {
        Environment = "prod"
      }
      copy_actions = [
        {
          destination_vault_arn = "arn:aws:backup:us-east-1:123456789012:backup-vault:secondary_vault"
          lifecycle = {
            cold_storage_after = 30
            delete_after       = 180
          }
        }
      ]
    },
    {
      name                     = "rule_2"
      schedule                 = "cron(0 5 ? * * *)"
      start_window             = 480
      completion_window        = 561
      enable_continuous_backup = false
      lifecycle = {
        cold_storage_after = 30
        delete_after       = 360
      }
      recovery_point_tags = {
        Environment = "prod"
      }
      copy_actions = [
        {
          destination_vault_arn = "arn:aws:backup:us-east-1:123456789012:backup-vault:secondary_vault"
          lifecycle = {
            cold_storage_after = 30
            delete_after       = 360
          }
        }
      ]
    }
  ]

  # Backup selection configuration
  selections = [
    {
      name = "complete_selection"
      selection_tag = {
        type  = "STRINGEQUALS"
        key   = "Environment"
        value = "prod"
      }
      resources = [
        "arn:aws:dynamodb:us-west-2:123456789012:table/my-table",
        "arn:aws:ec2:us-west-2:123456789012:volume/vol-12345678"
      ]
    }
  ]

  tags = {
    Environment = "prod"
    Project     = "complete_backup"
  }
}

Simple plan using AWS Organizations backup policies

module "aws_backup_example" {
  source = "../.."

  # Backup Plan configuration
  plan_name = "organization_backup_plan"

  # Vault configuration
  vault_name         = "organization_backup_vault"
  min_retention_days = 7
  max_retention_days = 365

  rules = [
    {
      name                     = "critical_systems"
      target_vault_name        = "critical_systems_vault"
      schedule                 = "cron(0 5 ? * * *)"
      start_window             = 480
      completion_window        = 561
      enable_continuous_backup = false
      lifecycle = {
        cold_storage_after = 30
        delete_after       = 365
      }
      recovery_point_tags = {
        Environment = "prod"
        Criticality = "high"
      }
      copy_actions = [
        {
          destination_vault_arn = "arn:aws:backup:us-east-1:123456789012:backup-vault:secondary_vault"
          lifecycle = {
            cold_storage_after = 30
            delete_after       = 365
          }
        }
      ]
    },
    {
      name                     = "standard_systems"
      target_vault_name        = "standard_systems_vault"
      schedule                 = "cron(0 5 ? * * *)"
      start_window             = 480
      completion_window        = 561
      enable_continuous_backup = false
      lifecycle = {
        cold_storage_after = 0
        delete_after       = 90
      }
      recovery_point_tags = {
        Environment = "prod"
        Criticality = "standard"
      }
      copy_actions = [
        {
          destination_vault_arn = "arn:aws:backup:us-east-1:123456789012:backup-vault:secondary_vault"
          lifecycle = {
            cold_storage_after = 0
            delete_after       = 90
          }
        }
      ]
    }
  ]

  # Selection configuration
  selections = [
    {
      name = "critical_systems"
      selection_tag = {
        type  = "STRINGEQUALS"
        key   = "Criticality"
        value = "high"
      }
    },
    {
      name = "standard_systems"
      selection_tag = {
        type  = "STRINGEQUALS"
        key   = "Criticality"
        value = "standard"
      }
    }
  ]

  tags = {
    Environment = "prod"
    Project     = "organization_backup"
  }
}

AWS Backup Audit Manager Framework

# AWS Backup
module "aws_backup_example" {
  source = "../.."

  # Audit Framework
  audit_framework = {
    create      = true
    name        = "exampleFramework"
    description = "this is an example framework"

    controls = [
      # Vault lock check - ensures resources are protected by vault lock
      {
        name            = "BACKUP_RESOURCES_PROTECTED_BY_BACKUP_VAULT_LOCK"
        parameter_name  = "maxRetentionDays"
        parameter_value = "100" # Maximum retention period allowed by vault lock
      },
    ]
  }

  # Tags are now specified separately
  tags = {
    Name = "Example Framework"
  }
}

Requirements

Name Version
terraform >= 1.0.0
aws >= 4.0.0

Providers

Name Version
aws 5.89.0

Modules

No modules.

Resources

Name Type
aws_backup_framework.ab_framework resource
aws_backup_plan.ab_plan resource
aws_backup_report_plan.ab_report resource
aws_backup_selection.ab_selection resource
aws_backup_selection.ab_selections resource
aws_backup_vault.ab_vault resource
aws_backup_vault_lock_configuration.ab_vault_lock_configuration resource
aws_backup_vault_notifications.backup_events resource
aws_iam_policy.ab_tag_policy resource
aws_iam_role.ab_role resource
aws_iam_role_policy_attachment.ab_backup_s3_policy_attach resource
aws_iam_role_policy_attachment.ab_policy_attach resource
aws_iam_role_policy_attachment.ab_restores_policy_attach resource
aws_iam_role_policy_attachment.ab_restores_s3_policy_attach resource
aws_iam_role_policy_attachment.ab_tag_policy_attach resource
aws_organizations_policy.backup_policy resource
aws_organizations_policy_attachment.backup_policy resource
aws_sns_topic_policy.backup_events resource
aws_iam_policy_document.ab_role_assume_role_policy data source
aws_iam_policy_document.ab_tag_policy_document data source
aws_iam_policy_document.backup_events data source
aws_partition.current data source

Inputs

Name Description Type Default Required
advanced_backup_settings Advanced backup settings by resource type map(map(string)) {} no
audit_framework Configuration for AWS Backup Audit Manager framework
object({
create = bool
name = string
description = optional(string)
controls = list(object({
name = string
parameter_name = optional(string)
parameter_value = optional(string)
}))
})
{
"controls": [],
"create": false,
"description": null,
"name": null
}
no
backup_policies Map of backup policies to create
map(object({
target_vault_name = string
schedule = string
start_window = number
completion_window = number
lifecycle = object({
delete_after = number
cold_storage_after = optional(number)
})
recovery_point_tags = optional(map(string))
copy_actions = optional(list(map(string)))
enable_continuous_backup = optional(bool)
}))
{} no
backup_regions List of regions where backups should be created list(string) [] no
backup_selections Map of backup selections
map(object({
resources = optional(list(string))
not_resources = optional(list(string))
conditions = optional(map(any))
tags = optional(map(string))
}))
{} no
changeable_for_days The number of days before the lock date. If omitted creates a vault lock in governance mode, otherwise it will create a vault lock in compliance mode number null no
enable_org_policy Enable AWS Organizations backup policy bool false no
enabled Change to false to avoid deploying any AWS Backup resources bool true no
iam_role_arn If configured, the module will attach this role to selections, instead of creating IAM resources by itself string null no
iam_role_name Allow to set IAM role name, otherwise use predefined default string "" no
locked Change to true to add a lock configuration for the backup vault bool false no
max_retention_days The maximum retention period that the vault retains its recovery points number null no
min_retention_days The minimum retention period that the vault retains its recovery points number null no
notifications Notification block which defines backup vault events and the SNS Topic ARN to send AWS Backup notifications to. Leave it empty to disable notifications any {} no
notifications_disable_sns_policy Disable the creation of the SNS policy. Enable if you need to manage the policy elsewhere. bool false no
org_policy_description Description of the AWS Organizations backup policy string "AWS Organizations backup policy" no
org_policy_name Name of the AWS Organizations backup policy string "backup-policy" no
org_policy_target_id Target ID (Root/OU/Account) for the backup policy string null no
plan_name The display name of a backup plan string null no
reports The default cache behavior for this distribution.
list(object({
name = string
description = optional(string, null)
formats = optional(list(string), null)
s3_bucket_name = string
s3_key_prefix = optional(string, null)
report_template = string
accounts = optional(list(string), null)
organization_units = optional(list(string), null)
regions = optional(list(string), null)
framework_arns = optional(list(string), [])
}))
[] no
rule_completion_window The amount of time AWS Backup attempts a backup before canceling the job and returning an error number null no
rule_enable_continuous_backup Enable continuous backups for supported resources. bool false no
rule_lifecycle_cold_storage_after Specifies the number of days after creation that a recovery point is moved to cold storage number null no
rule_lifecycle_delete_after Specifies the number of days after creation that a recovery point is deleted. Must be 90 days greater than cold_storage_after number null no
rule_name An display name for a backup rule string null no
rule_recovery_point_tags Metadata that you can assign to help organize the resources that you create map(string) {} no
rule_schedule A CRON expression specifying when AWS Backup initiates a backup job string null no
rule_start_window The amount of time in minutes before beginning a backup number null no
rules A list of rule maps
list(object({
name = string
target_vault_name = optional(string)
schedule = optional(string)
start_window = optional(number)
completion_window = optional(number)
enable_continuous_backup = optional(bool)
lifecycle = optional(object({
cold_storage_after = optional(number)
delete_after = number
}))
recovery_point_tags = optional(map(string))
copy_actions = optional(list(object({
destination_vault_arn = string
lifecycle = optional(object({
cold_storage_after = optional(number)
delete_after = number
}))
})))
}))
[] no
selection_conditions A map of conditions that you define to assign resources to your backup plans using tags. map(any) {} no
selection_name The display name of a resource selection document string null no
selection_not_resources An array of strings that either contain Amazon Resource Names (ARNs) or match patterns of resources to exclude from a backup plan. list(any) [] no
selection_resources An array of strings that either contain Amazon Resource Names (ARNs) or match patterns of resources to assign to a backup plan list(any) [] no
selection_tags List of tags for selection_name var, when using variable definition. list(any) [] no
selections A list or map of backup selections. If passing a list, each selection must have a name attribute. any [] no
tags A mapping of tags to assign to the resource map(string) {} no
vault_force_destroy A boolean that indicates that 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 The server-side encryption key that is used to protect your backups string null no
vault_name Name of the backup vault to create. If not given, AWS use default string null no
windows_vss_backup Enable Windows VSS backup option and create a VSS Windows backup bool false no

Outputs

Name Description
framework_arn The ARN of the backup framework
framework_creation_time The date and time that the backup framework was created
framework_id The unique identifier of the backup framework
framework_status The deployment status of the backup framework
plan_arn The ARN of the backup plan
plan_id The id of the backup plan
plan_role The service role of the backup plan
plan_version Unique, randomly generated, Unicode, UTF-8 encoded string that serves as the version ID of the backup plan
vault_arn The ARN of the vault
vault_id The name of the vault

Known Issues

During the development of the module, the following issues were found:

Error creating Backup Selection

<!-- END_TF_DOCS -->

About

Terraform module to create AWS Backup plans. AWS Backup is a fully managed backup service that makes it easy to centralize and automate the back up of data across AWS services (EBS volumes, RDS databases, DynamoDB tables, EFS file systems, and Storage Gateway volumes).

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages