Getting Started With AWS Backup Plan

Gerald Bachlmayr
4 min readMay 23, 2022

AWS Backup

“Why don’t we have a working backup?” is unfortunately a question I hear too many times. Data is a critical asset for any organisation and needs to be treated accordingly. AWS Backup is a fully managed service and provides an easy way to manage backups. It supports many AWS resources, including EC2, S3, RDS, DynamoDB and others.

In this blog post we are using HCL (HashiCorp Configuration Language) to demonstrate the implementation of a Backup Plan. The Backup Plan itself will need a Backup Vault where the data can be stored. Backup Vaults can be hosted in any region and for cross-region backups we can use a vault in a different region. The following code creates a Backup Vault in our default region:

resource "aws_backup_vault" "vault" {
name = "vault"

The Backup Vault also requires an IAM policy.

      "Effect": "Allow",
"Principal": {
"AWS": "${aws_iam_role.role_backup.arn}"
"Action": [
"Resource": "${aws_backup_vault.vault.arn}"

The entire code including an example is available on GitHub (see below).

AWS Backup Plan

AWS Backup Plan is a powerful feature within the AWS Backup service. It gives us the flexibility to implement different backup frequencies and data life-cycles for AWS resources. Depending on the business criticality and regulatory requirements we can define our Recovery Point Objectives (RPO) and data life-cycle.

The RPO describes the maximum amount of data measured by time that can be lost as result of an outage. If our business is willing to lose newly created or modified data for a duration of 24 hours, then our backup frequency needs to reflect this as part of the AWS Backup Plan. If we have applications with different criticality levels, then we can define several Backup Plans reflecting those requirements. Each Backup Plan can include different backup frequencies and data life-cycles.

The backup frequency is defined by a Cron Expression. The six fields within our Cron Expression are in the same format as CloudWatch Events. The following example shows the cron job value for a backup that runs every hour at 30 minutes past the hour.

locals {
plan_schedule_default = "cron(30 0 * * ? *)"
cold_storage_after_default = 30
delete_after_default = 120
… …

The data life-cycle describes when the backup data can be moved to cold storage and/or can be deleted later on. In the example above we move the backup data to cold storage after 30 days and delete it after 120 days.

Now that we have our Backup Plan configuration items defined, we will have a look how to use them in our Terraform module:

resource "aws_backup_plan" "backup_plan_default" {
name = "backup_plan_default"
rule {
rule_name = "backup_rule_default"
target_vault_name =
schedule = local.plan_schedule_default
life-cycle {
cold_storage_after = local.cold_storage_after_default
delete_after = local.delete_after_default

In order to perform our backups we need permissions, which we define in an IAM role. The below example gives sufficient permissions to perform backups and restores for EC2:

resource "aws_iam_role" "role_backup" {
name = "aws-backup-service-role-${local.region}"
assume_role_policy = join("",
managed_policy_arns = [

AWS Backup Selection & Toggling Between Backup Plans

AWS Backup Selection is another feature within AWS Backup. It is an easy way to declare which AWS resources will be backed up by which Backup Plan.

In our example we are looking for resources that have a tag with the name backup_plan.

resource "aws_backup_selection" "selection_default" {
iam_role_arn = aws_iam_role.role_backup.arn
name = "backup_selection_default"
plan_id =
selection_tag {
key = "backup_plan"
value = "default"

By setting up different Backup Plans, we can standardise the backup offering for our entire organisation. Resources then only need to be tagged with the appropriate tag. This is really powerful and simple because application/system owners can now opt into a backup plan of their choice by just using one tag.

If backup requirements change, the resource can be easily moved to a different Backup Plan by updating the backup_plan tag. The following screenshot shows the backup_plan tag in the AWS console.

Selecting a Backup Plan by using a tag
Selecting a Backup Plan by using a tag

Key Takeaways and Other Considerations

AWS Backup is a fully managed service and AWS Backup Plan provides a lot of flexibility for a variety of data backup requirements. Here are a couple of other considerations to take on board:

  • Are the resources protected?
    Making sure that the resources are actually targeted by our AWS Backup Plan is crucial. We can see that easily in the AWS Backup Console under “Protected Resources”.
  • Can we recover from our backups?
    We need to validate that our backups provide data integrity, so that we can actually recover from the latest backup. This is really important and I have seen cases where customers were performing backups for 3 months but could not recover after an outage. How can we do this? I will leave this for an upcoming blog post.
  • Can I have more flexibility?
    In this write-up we looked into Selection Tags to define which AWS resources to select for a Backup Plan. Conditions are another way to control the selection process for AWS resources.

Source Code