TechnologyAug 27, 202610 min read

Stop Backing Up by Hand: A Day 0 to Day 2 Guide to Automating Cloud Protection


 

I gave a talk at Rubrik Forward this year called "The Automated Cloud" focused on a framework for automating cloud protection, plus code examples you can fork and implement within your organization immediately (see below).

 

 



 

But why do we even need automation in the cloud? If you've worked with cloud and data protection for any length of time, you've probably noticed the same pattern: infrastructure moves fast, and data protection doesn't move with it. The tooling most organizations leverage for this simply doesn’t keep pace.

Keeping up with a dynamic environment such as cloud using static, human-driven processes is nearly impossible: workloads spin up and down constantly, configs drift, accounts multiply. Point-in-time, person-to-person protection processes just aren't built for that.

Adding more processes simply adds more overhead. If protection is going to keep pace with the cloud, it needs to be built into the lifecycle of a workload from the moment it's created to the moment something threatens it. It needs to be provisioned as code, kept current automatically as things change, and be able to react on its own when a signal says something's wrong. 

So how do you automate cloud protection across the entire lifecycle, from Day 0 to Day 2?

 

 

 

 

 

Day 0, Day 1, Day 2

These terms get used differently everywhere, so let me define what they mean to me before moving forward:

 

  • Day 0 is foundational setup: provisioning Rubrik the same way you provision cloud, using Infrastructure as Code.

  • Day 1 is operational automation: the day-to-day mechanics of keeping new and changing workloads protected without a human clicking through a UI.

  • Day 2 is signal-driven intelligence: using a signal, either Rubrik detects something and triggers a process elsewhere, or something else (a security tool, SIEM, etc) detects something and triggers an action in Rubrik.

 

Most organizations I talk to excel at Day 1 as these tend to be some of the easiest, lowest-lift automations to build. Day 0 is a different story: unless you're a true cloud-first company, a lot of companies skip it entirely, with good intentions of implementing it later. You get a new tool, and you want to use it, not configure it through code first. 

 

Day 2 is where things get interesting, and a lot of organizations haven't really started here yet, unless they're already leaning on one of the pre-built integrations, like CrowdStrike, ServiceNow, or Palo Alto Networks Cortex XSOAR, which handle a lot of this out of the box.

 

So with that, let’s take a look at what’s possible by running through some automation examples for Day 0, Day 1 and Day 2

 

 


Automating Day 0: Infrastructure as Code

Rubrik's protection stack is fully expressible in Terraform through the Rubrik provider, which recently earned Terraform Premier Partner status.

If you're already a Terraform shop, or your process requires everything to go through a pipeline, or you're standing up a greenfield environment, it's best to configure Rubrik with Terraform right from the outset. Rubrik maintains a public repo with many examples covering everything from cloud account onboarding and SLA assignment to tag rules, custom roles, and Exocompute across AWS, Azure, and GCP.

We talk about that greenfield path a lot, but in practice, most of the customers I work with have already configured Rubrik by hand and are now trying to bring it into Terraform after the fact. So that's what we'll walk through today. 

Here's the scenario: you've already onboarded an AWS account to Rubrik Security Cloud, and you're already protecting workloads. Bringing an existing Rubrik environment into your Terraform state can be easily accomplished leveraging native import blocks.

Start by creating an imports.tf file in the root of your plan or module, and add an import block for your account:

 

 

import {
  to = polaris_aws_cnp_account.tme_rdp
  id = "<rsc-account-uuid>"
}

import {
  to = polaris_aws_exocompute.tme_rdp_us_east_1
  id = "<rsc-exocompute-uuid>"
}


Note: You'll need the account's UUID and the UUID of each Exocompute cluster you want to bring in. Both are visible in Rubrik Security Cloud within the URL: the account ID under Settings > Cloud Accounts, and each Exocompute cluster's ID on that account's Exocompute configuration page.

Next, run:

 terraform plan -generate-config-out=generated.tf  

Terraform will reach out, read the current state of that account and exocompute config, and write the resource HCL for you to the designated file. Review what it generates and copy it into your actual configuration files (often main.tf). Be sure to delete generated.tf so you don't end up with duplicate resource definitions.

Of course, a plan alone won't put anything into state though, that's what apply is for. Run terraform apply, and Terraform will bring the account and Exocompute config under management for real.

If the apply generates an error in regards to unrecognized features don’t worry, it just means that the provider is seeing a feature that it isn’t aware of yet. The fix: simply add a lifecycle block to the generated resource block to ignore the feature field as shown below. After running terraform apply again, everything should exit cleanly.
 

resource "polaris_aws_cnp_account" "tme_rdp" {
 # ... code

 lifecycle {
 ignore_changes = [feature]
 }
}


You might also have a number of SLA Domains that were created through the Rubrik UI that you'd like to bring under Terraform management. Just like accounts, SLAs can also be imported by referencing either by UUID or name:

 

import {
 to = polaris_sla_domain.gold
 id = "Gold"
}


Same process as before: run terraform plan -generate-config-out=generated.tf to generate the config, move it into your actual configuration files, delete generated.tf, then run terraform apply to bring those SLA Domains into your Terraform state.

A full working example, including the account resources, exocompute config, and the import file can be found in the Day0/tf-deploy repository.

 

 

Automating Day 1: Protection That Keeps Up

This is the stage where most teams are already well on their way and where the biggest practical wins live. Let’s explore a couple of examples here.

Tag-based SLA assignment: Remember the scenario from earlier where a workload spins up, and nobody's actually confirmed it's protected because the person who spun it up never talked to the backup team? Tag-based SLA assignment solves exactly that. Instead of manually applying an SLA to every new workload, you set up a tag rule in Rubrik: whenever Rubrik sees a workload carrying a specific key/value tag, it gets protected automatically. No more guessing.

Let's configure this from scratch in Terraform. First, we will create the SLA Domain itself using the following resource block:
 

resource "polaris_sla_domain" "aggressive" {
 name = "Aggressive"
 description = "Aggressive protection for critical EC2 workloads"
 object_types = ["AWS_EC2_EBS_OBJECT_TYPE"]

 hourly_schedule {
 frequency = 4
 retention = 24
 retention_unit = "HOURS"
 }
}


Here we’ve created an SLA named aggressive, that takes backups of EC2 every 4 hours and retains them for 1 day.

Next, a polaris_tag_rule resource that watches for a tag key/value pair (backup = aggressive) on your EC2 instances, and a polaris_sla_domain_assignment resource that binds that tag rule to our newly created SLA Domain:

 

resource "polaris_tag_rule" "aggressive_backup" {
 name = "aggressive-backup"
 object_type = "AWS_EC2_INSTANCE"

 tag {
 key = "backup"
 values = ["aggressive"]
 }
}

resource "polaris_sla_domain_assignment" "aggressive_backup" {
 sla_domain_id = polaris_sla_domain.aggressive.id

 object_ids = [
 polaris_tag_rule.aggressive_backup.id,
 ]
}


Run terraform plan and terraform apply, and we're good to go. From that point on, any tool that can set an AWS tag (Terraform, CloudFormation, awscli, etc) can trigger SLA assignment without anyone touching the Rubrik UI. Rubrik picks up the tagged instance on its next account refresh, typically within about 30 minutes, and assigns the SLA Domain automatically. No human in the mix, data protection is never an afterthought.

Monitoring The Pipeline - Snapshot Before Apply: Next, let’s take a look at bringing data protection into the deployment pipeline itself, triggering backups the moment before changes are made, rather than running on a separate schedule disconnected from our deployments. The process we will follow is as so:

Stop Backing Up by Hand: A Day 0 to Day 2 Guide to Automating Cloud Protection


To create this, let’s create a GitHub Actions workflow that, on every push to the main branch will parse the terraform plan results, find any EC2 instances or RDS databases that are about to be updated or destroyed, authenticate to Rubrik and trigger an on-demand snapshot of those resources before the apply is allowed to proceed

Take the following GitHub Action:

 

name: Terraform Safe Apply

on:
 push:
 branches: [main]

jobs:
 deploy:
 runs-on: ubuntu-latest

 steps:
 - name: Checkout
 uses: actions/checkout@v4

 - name: Configure AWS Credentials
 uses: aws-actions/configure-aws-credentials@v4
 with:
 aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
 aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
 aws-region: us-east-1

 - name: Setup Terraform
 uses: hashicorp/setup-terraform@v3
 with:
 terraform_wrapper: false

 - name: Terraform Init
 run: terraform init

 - name: Terraform Plan
 run: terraform plan -out=tfplan

 - name: Check for Modified Resources
 id: plan-check
 run: |
 terraform show -json tfplan | python3 -c "
 ..."

 - name: Start RSC Pre-Apply Jobs
 if: steps.plan-check.outputs.instance_id != '' || steps.plan-check.outputs.rds_id != ''
 id: rsc-jobs
 env:
 RSC_CLIENT_ID: ${{ secrets.RSC_CLIENT_ID }}
 RSC_CLIENT_SECRET: ${{ secrets.RSC_CLIENT_SECRET }}
 RSC_SLA_NAME: ${{ secrets.RSC_SLA_NAME }}
 AWS_INSTANCE_ID: ${{ steps.plan-check.outputs.instance_id }}
 AWS_RDS_ID: ${{ steps.plan-check.outputs.rds_id }}
 run: python3 .github/scripts/rsc_pre_apply.py

 - name: Terraform Apply
 run: terraform apply -auto-approve tfplan


We start by defining the schedule.  This action will trigger on any push to the main branch, direct, or through a pull request.  We can then see it runs a terraform init and terraform plan, parsing the data to determine if any resources are about to change. If so, those resources are passed to the pre-apply step which runs a python script (rsc_pre_apply.py). Finally, a terraform apply is initiated.

The rsc_pre_apply.py script authenticates to the RSC instance, looks up both the workloads and  the SLA Domain's internal IDs, kicks off an on-demand snapshot, and then polls the job status until it succeeds or fails:

 

def snapshot_ec2(token, rsc_id, sla_id, jobs):
    resp = gql(token, {
        "operationName": "TakeEC2InstanceSnapshotMutation",
        "variables": {"input": {"ec2InstanceIds": [rsc_id], "retentionSlaId": sla_id}},
        "query": "mutation TakeEC2InstanceSnapshotMutation(...) { startAwsNativeEc2InstanceSnapshotsJob(input: $input) { jobIds { jobId } errors { error } } }",
    })
    # ...record the job ID, then wait_for_jobs() polls until Success/Failure


If any of those snapshot jobs fail, the script exits non-zero and the apply never runs. This ensures we always have a clean snapshot before modifications are made. After all, we run nearly everything else within our pipelines, why treat data protection any differently?

You can find the full pipeline, including the workflow file and the pre-apply script in the tf-day1-pipeline repo.

And why not take it one step further: back up the actual repository code before it's merged and ensure we protect our terraform plans, code, and pipelines alongside the data! I wrote about this in more depth here: Backup as Code: Enforcing Rubrik Backups in GitHub Actions.



Automating Day 2: Orchestrating a Security Response

Day 2 is all about taking signals from one application or service, and using them to intelligently run automation against another application or service. The example below falls right in line: Defender for Cloud detecting ransomware events, and forensic snapshots happening within Rubrik.

Microsoft Defender for Cloud is already watching your Azure workloads for suspicious activity. When it fires an alert, its workflow automation can call out to a Logic App, which forwards to an Azure Function, which talks to Rubrik.

 

Stop Backing Up by Hand: A Day 0 to Day 2 Guide to Automating Cloud Protection

 

The Azure function itself is pretty similar to the automations we've already built for Day 1: parse the alert payload for the affected VM's resource ID, authenticate to Rubrik Security Cloud, look up the SLA Domain to attach, find the matching VM inside Rubrik, and trigger an on-demand snapshot for forensics.

 

@app.route(route="DefenderTrigger", auth_level=func.AuthLevel.FUNCTION)
def DefenderTrigger(req: func.HttpRequest) -> func.HttpResponse:
    alert = req.get_json()
    vm_resource_id = extract_vm_resource_id(alert)

    token = get_rsc_token()
    sla_id = lookup_sla(token, RSC_SLA_NAME)
    rsc_vm_id = find_azure_vm(token, vm_resource_id)

    job_id = trigger_vm_snapshot(token, rsc_vm_id, sla_id)
    return func.HttpResponse(json.dumps({"rsc_job_id": job_id}), status_code=200)


By the time a security analyst actually opens that Defender alert, the forensic snapshot already exists, captured automatically the moment the alert is fired. This workflow could easily be expanded to begin recovering the latest clean point-in-time backup to an isolated environment, or into a clean room. Furthermore, we can flip the table and use Rubrik intelligence for Day 2 workflows: Rubrik can fire a webhook on nearly any event (Anomaly Detected, Sensitive Data Found, Threats Discovered, etc) upon which you can automate a desired response. The possibilities and use-cases are endless.

Full function code can be found in the  Day2/AzureFunction/defender-rubrik-demo repository.

 

 

What We Covered, and Where to Start

To recap: Day 0 is infrastructure as code, and it's the one most orgs skip, even though a little upfront Terraform work tends to pay for itself many times over. 

Day 1 is where the highest-leverage automation lives for most teams, tag-based assignment and pipeline-integrated snapshots close real, common gaps. 

Day 2 is intelligence, using a signal from somewhere else in your stack to trigger protection automatically, at machine speed instead of human speed.

If you're looking to actually start on any of this, here's what I'd suggest, in order:

1. Audit your cloud accounts. Find every workload with no SLA assigned. You'll probably be surprised how many there are. 

2. Find your biggest gap. Is it Day 0 (no IaC at all), Day 1 (protection that isn't keeping pace with new workloads), or Day 2 (no automated response to signals from elsewhere)? Pick one. 

3. Fork a module and start small. Don't try to boil the ocean. Take a single Terraform resource, a single tag rule, or a single pipeline gate, and build that this week.

 

Both repos are public and meant to be forked:

 


If you want a deeper dive on the Terraform side, check out Rubrik and Terraform: A Cloud Architect's Guide. And if you want to go straight to the source on the API powering everything in this post, developer.rubrik.com is where to start.


Happy Building!

 

 

Related Articles

Blogs by This Author