Resourcely Documentation
LoginSign Up
  • Get Started
    • 🎱What is Resourcely?
    • 👋Why Resourcely
    • 🏃Quickstart
      • Terraform policies integrated into CI
      • Remediate policy violations in existing infrastructure
      • Templates for generating Terraform
      • Glossary
  • Concepts
    • Foundry
      • Create Blueprints with Foundry
      • Creating Guardrails with Foundry
      • lmport Terraform Modules
    • Guardrails
      • Writing your own Guardrails
      • Editing Guardrails
      • Releasing Guardrails
      • Enabling Inactive Guardrails
      • Guardrails in Action
        • 🐱GitHub Actions
        • 🦊GitLab Pipelines
    • Campaigns
      • Get started with Campaigns
      • Creating Campaigns
      • Remediate Resources
      • Campaign Agent
        • State File Support
          • Amazon Simple Storage Service (S3)
          • Google Cloud Storage (GCS)
          • HCP Terraform
          • Spacelift
        • Running Campaigns with GitHub Actions and a Repo-Hosted State File
        • Running Campaigns Locally
    • Blueprints
      • Authoring Your Own Blueprints
      • Using Built-in Resourcely Blueprints
      • Configuring Global Contexts
      • Deep Linking
    • Resources
      • Provisioning Infrastructure
      • Editing Infrastructure
      • Shopping Cart
      • Config Roots and Environments
    • Other Features and Settings
      • Global Values
      • Global Context
      • Metrics
      • Resourcely-cli
      • Resourcely.yaml
      • VCS Proxy
      • Settings
        • User management
        • Company Information
        • Notification Settings
        • Change Management
          • 🐱Connect to GitHub
          • 🦊Connect to Gitlab
        • Generate API Token
    • ✨Production Setup
      • Single Sign-On (SSO)
        • Auth0
        • AWS Single Sign-On
        • Azure AD
        • Google Workspace
        • JumpCloud
        • Okta
        • Omnissa Workspace ONE (formerly VMware)
        • OneLogin
        • Ping Identity
        • Other SAML / OIDC Providers
      • Source Code Management
        • Page
        • 🐱GitHub
        • 🦊GitLab
        • Atlassian Bitbucket
        • Azure Repos
  • Tutorials and guides
    • Remediation Use Cases
      • Apply tags to resources for automating backups
      • Implement centralized logging
    • Blueprints Use Cases
      • Automate Data Pipeline Creation
      • Encryption for GCP
      • AWS Account Factory
      • Streamline and govern AI
      • IAM Factory
      • Cost optimization for FinOps
      • Guardrails for Terraform Modules
    • Using the Resourcely Terraform Provider
      • Setup Resourcely Provider
      • Blueprints
      • Guardrails
      • Global Context
  • Integrate
    • CI/CD & Terraform Runners
      • Atlantis
      • 🐟AWS CodeBuild
      • Azure Pipelines
      • Buildkite
      • CircleCI
      • CloudBees CI
      • Codefresh
      • Digger
      • Env0
      • 🎏GitHub Actions
        • 🐱Local Plan
          • 🐹AWS with OpenID Connect
        • 🐶Terraform Cloud Integration
      • 🦊GitLab Pipelines
      • Harness
      • 🗻HashiCorp Cloud Platform (formerly Terraform Cloud)
      • Jenkins
      • Octopus Deploy
      • Scalr
      • 🌌Spacelift
      • Terramate
      • 🌎Terrateam
    • Cloud Providers
      • 🌨️Amazon Web Services (AWS)
      • 🤓Google Cloud Platform (GCP)
        • Guardrail Gaunlet at Google Cloud Next 2025
      • 💾Microsoft Azure
      • Alibaba Cloud
      • Huawei Cloud
      • IBM Cloud
      • Oracle Cloud Infrastructure (OCI)
      • Tencent Cloud
      • VMware vSphere
    • Developer Portals
      • Atlassian Compass
      • Backstage
      • Cortex
      • Harness IDP
      • Home grown internal developer portals
      • OpsLevel
      • Port
      • Roadie
    • ITSM
      • Atlassian Jira
      • FreshWorks
      • ServiceNow ITSM
      • ZenDesk
    • CSPM
      • Wiz
    • More Terraform Provider Integrations
      • 🚂ConductorOne Provider
      • Databricks Provider
      • Kubernetes Provider
      • 🐕Datadog Provider
      • ❄️Snowflake Provider
Powered by GitBook
On this page
  • Define the assets you want recurring backups on
  • Make sure you have aws_backup_vault configured
  • Constructing relevant policy
  • Writing a Guardrail
  • Implement backup tags: Running a Campaign
  • Create Campaign
  • Remediate code
  • Managing exceptions
  • Submit PR
  • Summary
  1. Tutorials and guides
  2. Remediation Use Cases

Apply tags to resources for automating backups

Automate backups for your AWS resources by applying tags to resources at scale

PreviousRemediation Use CasesNextImplement centralized logging

Last updated 1 month ago

Your company's cloud environment is valuable: data, applications, logs, and the infrastructure behind them are all valuable. Ransomware attacks or accidental deletion can cost companies millions of dollars directly, while damaging brand reputations and customer relationships.

In this tutorial, we'll walk through how to set up backups for your existing AWS infrastructure at scale using Resourcely. We will automatically apply tags to relevant resources, and then use that to set up an aws_backup_vault.

Things you'll need to continue: 1. Resourcely account () 2. A Terraform pipeline running, and the Resourcely Campaign Agent for scanning your Terraform state (use our demo scaffolding repo )

Define the assets you want recurring backups on

Critical infrastructure is likely some of the following:

  • EC2 instances

  • EBS volumes

  • RDS instances

  • Aurora Clusters

  • DynamoDB tables

  • EFS file systems

For each of these resources, we'll add a backup tag that we can use with aws_backup_vault:

  tags = {
    backup = "true"
  }

Make sure you have aws_backup_vault configured

Setting up an aws_backup_vault like below, with a tag-based selection that looks for our backup tag, will allow us to automatically backup all of our relevant resources.

resource "aws_backup_vault" "main" {
  name = "primary-backup-vault"
}

resource "aws_backup_plan" "example" {
  name = "my-backup-plan"

  rule {
    rule_name         = "daily-backup"
    target_vault_name = aws_backup_vault.main.name
    schedule          = "cron(0 5 * * ? *)" # Daily at 5 AM UTC
    lifecycle {
      
    }
  }
}

resource "aws_backup_selection" "example" {
  name         = "tag-based-selection"
  plan_id      = aws_backup_plan.example.id
  resources    = []
   {
    type  = "STRINGEQUALS"
    key   = "backup"
    value = "true"
  }
}

Constructing relevant policy

Now, we'll move into Resourcely. If you haven't already, follow the Remediate policy violations in existing infrastructure quickstart to set up the Campaigns agent for scanning your existing infrastructure..

Writing a Guardrail

Resourcely Guardrails feature a flexible policy language. We can write a single policy that will allow us to find relevant resources without a backup tag and apply it.

// Guardrail for applying a backup tag to relevant resources

GUARDRAIL "Require backup tags on relevant AWS resources" 
  WHEN aws_db_instance OR aws_ebs_volume OR aws_rds_cluster OR aws_rds_cluster_instance OR aws_dynamodb_table OR aws_efs_file_system
    REQUIRE tags.backup = "true"

This policy will flag any resources that don't have the appropriate tag when we include it in a Campaign. You can choose this Guardrail from our pre-built policies in Resourcely, just search for "Require backup tags".

Implement backup tags: Running a Campaign

Campaigns lets companies orchestrate remediation across their existing resources. Here is the existing Terraform code that we have in our playground repo (feel free to use it for yourself for testing purposes).

main.tf
// 3 RDS resources: one with an incorrect tag, and two missing tags

resource "aws_db_instance" "example-rds_TJXZTFi3qSy724Fv" {
  identifier                   = "example-rds"
  engine                       = "postgres"
  engine_version               = "17.2"
  instance_class               = "db.t3.micro"
  allocated_storage            = 20
  max_allocated_storage        = 100
  db_name                      = "app_database"
  username                     = "db_user"
  password                     = "password"
  backup_retention_period      = 7
  storage_encrypted            = false
  multi_az                     = true
  deletion_protection          = true
  performance_insights_enabled = true
  skip_final_snapshot          = true
  tags = {
    backup = "false"
  }
}

resource "aws_db_instance" "key-application-dev" {
  identifier                   = "key-application-dev"
  engine                       = "postgres"
  engine_version               = "17.2"
  instance_class               = "db.t3.micro"
  allocated_storage            = 20
  max_allocated_storage        = 100
  db_name                      = "app_database"
  username                     = "db_user"
  password                     = "password"
  backup_retention_period      = 7
  storage_encrypted            = false
  multi_az                     = true
  deletion_protection          = true
  performance_insights_enabled = true
  skip_final_snapshot          = true
}

resource "aws_db_instance" "key-application-prod" {
  identifier                   = "key-application-prod"
  engine                       = "postgres"
  engine_version               = "17.2"
  instance_class               = "db.t3.micro"
  allocated_storage            = 20
  max_allocated_storage        = 100
  db_name                      = "app_database"
  username                     = "db_user"
  password                     = "password"
  backup_retention_period      = 7
  storage_encrypted            = false
  multi_az                     = true
  deletion_protection          = true
  performance_insights_enabled = true
  skip_final_snapshot          = true
}

Create Campaign

First, we'll create a Campaign. We'll choose relevant repositories and the policies that we want to scan for. I selected the Guardrail that we created above.

The Campaign has scanned our existing infrastructure for violations and identified those resources that fail.

Remediate code

Now that we know there are 3 resources missing the correct backup tag, let's remediate them! Navigating to the remediation screen shows us our violations against our Terraform code:

Let's look at each of our scenarios. The first is the example-rds instance, with an incorrect tag

example-rds
resource "aws_db_instance" "example-rds_TJXZTFi3qSy724Fv" {
  identifier                   = "example-rds"
  engine                       = "postgres"
  engine_version               = "17.2"
  instance_class               = "db.t3.micro"
  allocated_storage            = 20
  max_allocated_storage        = 100
  db_name                      = "app_database"
  username                     = "db_user"
  password                     = "password"
  backup_retention_period      = 7
  storage_encrypted            = false
  multi_az                     = true
  deletion_protection          = true
  performance_insights_enabled = true
  skip_final_snapshot          = true
  tags = {
    backup = "false"
  }
}

Given this resource has a tag keypair that matches our Guardrail, that specific parameter is highlighted when we click on our violation:

Changing the value to "true" gives us feedback that our change was accepted (with the green check).

Let's now consider our violation against key-application-prod. This resource is missing any tag parameters, so we highlight the overall resource. In this case, I must add a tag parameter.

We'll be releasing human-in-the-loop remediation support in the future: where the tag parameter will be automatically generated for a user to review.

When I add the tag parameter, Resourcely gives me feedback with a green check - to let me know that I've added the correct Terraform.

Managing exceptions

Let's consider our final violation. In this case, the RDS database is for development only. If your organization doesn't want to spend money backing up development databases, we may not want to add the tag. How can we satisfy the Guardrail without adding the tag?

The answer: exceptions. As a user I can request an exception by clicking on the Guardrail and "Manage Exception".

Submit PR

We have now satisfied our backup tag Guardrail. The next step is to submit these changes through our existing CI. This way we:

  • Preserve our existing approval workflows

  • Avoid Terraform drift as compared to automated remediation

By clicking Evaluate Changes --> Finalize, I can submit a change request through my version control tool of choice.

Here is the PR I made in GitHub via Resourcely remediation, that will add relevant backup tags.

The exception request for our dev database is included in the conversation, and a reviewer is automatically tagged to review the changes.

Summary

We've demonstrated two key use cases in one: adding backups to existing resources that are missing them at scale, and adding or changing tags to existing resources - again at scale.

Resourcely Campaigns are a flexible framework for changing Terraform configuration of existing resources. While a single person could manage the example we gave, it could easily scale to hundreds of different developers. Many Resourcely customers have security teams creating and managing Campaigns, while individual developers use the Remediation functionality for the resources they are responsible for.

You can also write it yourself in the .

Fixing misconfigurations can help you stay compliant, mitigate risk & liability, and reduce breaches or incidents. Get started yourself at today!

sign up free
here
Foundry
https://portal.resourcely.io
Creating a Campaign to apply tags
Campaign Summary
The specific resource addresses with violations
Remediation IDE with inline violations
Inline violation
Hovering gives us a suggested fix
Our violation highlights the overall resource when a parameter is missing
Added a backup parameter
Requesting an exception
We have green checks for our violations!
Submitting a PR
Files changed view
Exception request within PR