Snapshot Policies Example¶
This example demonstrates how to create and manage automated snapshot policies on Qumulo clusters using the qumulo_snapshot_policy resource. Snapshot policies automate point-in-time data protection.
Features¶
Five snapshot schedule types are demonstrated:
- Daily - Snapshots at a specific time each day
- Hourly - Snapshots within business hours windows
- Weekly - Snapshots on specific days of the week
- Monthly - Snapshots on a specific day of the month
- Multi-department - Using
for_eachfor bulk policy management
Architecture¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ SNAPSHOT POLICY OVERVIEW │
└─────────────────────────────────────────────────────────────────────────────┘
QUMULO CLUSTER
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ SNAPSHOT POLICIES (automated schedules) │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ daily-backup │ │ business-hours │ │ monthly-archive │ │
│ │ 2:00 AM daily │ │ Hourly 9-5 M-F │ │ 1st of month │ │
│ │ Retain: 7 days │ │ Retain: 24 hrs │ │ Retain: forever │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ FILESYSTEM │ │
│ │ │ │
│ │ /data ─────────────────► .snapshot/ │ │
│ │ ├── daily-backup_2024-01-15_02-00 │ │
│ │ ├── daily-backup_2024-01-16_02-00 │ │
│ │ ├── business-hours_2024-01-16_09-00 │ │
│ │ ├── business-hours_2024-01-16_10-00 │ │
│ │ └── monthly-archive_2024-01-01_00-00 │ │
│ │ │ │
│ │ /projects ─────────────► .snapshot/ (separate namespace) │ │
│ │ │ │
│ │ /compliance-data ──────► .snapshot/ (90-day retention) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
SNAPSHOT LIFECYCLE
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Create │───►│ Active │───►│ Expire │───►│ Delete │
│(schedule)│ │ (retain) │ │ (TTL) │ │(cleanup) │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
Prerequisites¶
- Qumulo cluster with REST API access (port 8000)
- Admin credentials for the cluster
- Existing filesystem paths for snapshot sources (or create them)
Usage¶
- Create a
terraform.tfvarsfile:
cluster_endpoint = "https://cluster.example.com:8000"
cluster_username = "admin"
cluster_password = "cluster-admin-password"
# Optional: Configure per-department policies
department_snapshot_config = {
engineering = {
path = "/departments/engineering"
hour = 3
retention = "14days"
}
marketing = {
path = "/departments/marketing"
hour = 4
retention = "7days"
}
research = {
path = "/departments/research"
hour = 5
retention = "30days"
}
}
- Initialize and apply:
Variables¶
| Name | Description | Type | Default |
|---|---|---|---|
cluster_endpoint |
Qumulo cluster REST API endpoint | string |
- |
cluster_username |
Qumulo cluster admin username | string |
"admin" |
cluster_password |
Qumulo cluster admin password | string |
- |
department_snapshot_config |
Map of department names to snapshot config | map(object) |
See example |
Department Config Object¶
{
path = string # Filesystem path to snapshot
hour = number # Hour of day (0-23) to take snapshot
retention = string # Retention period (e.g., "7days", "24hours")
}
Outputs¶
| Name | Description |
|---|---|
daily_backup_policy_id |
ID of the daily backup snapshot policy |
daily_backup_schedule_id |
Schedule ID of the daily backup policy |
daily_backup_source_file_id |
Resolved file ID for the daily backup source path |
business_hours_policy_id |
ID of the business hours snapshot policy |
monthly_archive_policy_id |
ID of the monthly archive snapshot policy |
department_policy_ids |
Map of department names to their policy IDs |
Schedule Types¶
Daily Snapshots¶
Take a snapshot every day at a specific time:
resource "qumulo_snapshot_policy" "daily" {
connection_profile = "cluster1"
policy_name = "daily-backup"
source_path = "/data"
schedule {
timezone = "America/Los_Angeles"
frequency = "SCHEDULE_DAILY_OR_WEEKLY"
hour = 2
minute = 0
on_days = ["EVERY_DAY"]
expiration_time_to_live = "7days"
}
}
Hourly Snapshots (Business Hours)¶
Take snapshots every hour during specific windows:
resource "qumulo_snapshot_policy" "hourly" {
connection_profile = "cluster1"
policy_name = "business-hours"
source_path = "/projects"
schedule {
timezone = "UTC"
frequency = "SCHEDULE_HOURLY_OR_LESS"
on_days = ["MON", "TUE", "WED", "THU", "FRI"]
window_start_hour = 9
window_start_minute = 0
window_end_hour = 17
window_end_minute = 0
fire_every_interval = "FIRE_IN_HOURS"
fire_every = 1
expiration_time_to_live = "24hours"
}
}
Weekly Snapshots¶
Take snapshots on specific days:
resource "qumulo_snapshot_policy" "weekly" {
connection_profile = "cluster1"
policy_name = "weekly-compliance"
source_path = "/compliance-data"
schedule {
timezone = "UTC"
frequency = "SCHEDULE_DAILY_OR_WEEKLY"
hour = 0
minute = 0
on_days = ["SUN"]
expiration_time_to_live = "90days"
}
}
Monthly Snapshots¶
Take snapshots on a specific day of the month:
resource "qumulo_snapshot_policy" "monthly" {
connection_profile = "cluster1"
policy_name = "monthly-archive"
source_file_id = "2" # Root directory
schedule {
timezone = "UTC"
frequency = "SCHEDULE_MONTHLY"
day_of_month = 1
hour = 0
minute = 0
expiration_time_to_live = "never"
}
}
Bulk Policies with for_each¶
Manage multiple policies with a single resource block:
variable "department_config" {
type = map(object({
path = string
hour = number
retention = string
}))
}
resource "qumulo_snapshot_policy" "departments" {
for_each = var.department_config
connection_profile = "cluster1"
policy_name = "${each.key}-daily-backup"
source_path = each.value.path
schedule {
timezone = "UTC"
frequency = "SCHEDULE_DAILY_OR_WEEKLY"
hour = each.value.hour
minute = 0
on_days = ["EVERY_DAY"]
expiration_time_to_live = each.value.retention
}
}
Schedule Reference¶
Frequency Options¶
| Frequency | Description |
|---|---|
SCHEDULE_HOURLY_OR_LESS |
Sub-daily intervals within a time window |
SCHEDULE_DAILY_OR_WEEKLY |
Daily or specific days of the week |
SCHEDULE_MONTHLY |
Specific day of the month |
Day Options¶
| Value | Description |
|---|---|
EVERY_DAY |
All days (for daily frequency) |
MON, TUE, WED, THU, FRI |
Weekdays |
SAT, SUN |
Weekend days |
Retention Formats¶
| Format | Example | Description |
|---|---|---|
| Hours | 24hours |
Retain for 24 hours |
| Days | 7days |
Retain for 7 days |
| Weeks | 4weeks |
Retain for 4 weeks |
| Never | never |
Never expire (permanent) |
Security Considerations¶
-
Retention Policies: Balance retention with storage costs. Longer retention requires more space.
-
Compliance: For regulatory compliance, use
"never"expiration and separate policies for compliance data. -
Access Control: Snapshots inherit permissions from the source directory. Users with read access can browse
.snapshotdirectories. -
Recovery Testing: Regularly test snapshot recovery to ensure data can be restored when needed.
-
Off-cluster Copies: Snapshots protect against user error but not hardware failure. Combine with replication for disaster recovery.
Full Configuration¶
# Example: Managing Snapshot Policies on a Qumulo Cluster
#
# This example demonstrates how to create and manage snapshot policies
# on an existing Qumulo cluster using the qumulo_snapshot_policy resource.
# Snapshot policies automate the creation of point-in-time snapshots on a schedule.
terraform {
required_providers {
qumulo = {
source = "qumulo-terraform-registry.s3.us-east-1.amazonaws.com/qumulo/qumulo"
version = "~> 1.0"
}
}
}
variable "cluster_endpoint" {
description = "Qumulo cluster REST API endpoint (e.g., https://cluster:8000)"
type = string
}
variable "cluster_username" {
description = "Qumulo cluster admin username"
type = string
default = "admin"
}
variable "cluster_password" {
description = "Qumulo cluster admin password"
type = string
sensitive = true
}
# Define connection profile for the cluster
provider "qumulo" {
connection_profiles = [
{
name = "cluster1"
endpoint = var.cluster_endpoint
username = var.cluster_username
password = var.cluster_password
insecure_skip_verify = true # Required for clusters with self-signed certificates
}
]
}
# -----------------------------------------------------------------------------
# Daily Backup Policy (using source_path)
# Takes a snapshot every day at 2 AM, keeps snapshots for 7 days
# -----------------------------------------------------------------------------
resource "qumulo_snapshot_policy" "daily_backup" {
connection_profile = "cluster1"
policy_name = "daily-backup"
source_path = "/data" # Automatically resolved to file ID
schedule {
timezone = "America/Los_Angeles"
frequency = "SCHEDULE_DAILY_OR_WEEKLY"
hour = 2
minute = 0
on_days = ["EVERY_DAY"]
expiration_time_to_live = "7days"
}
}
# -----------------------------------------------------------------------------
# Business Hours Policy (hourly snapshots)
# Takes a snapshot every hour during business hours on weekdays
# -----------------------------------------------------------------------------
resource "qumulo_snapshot_policy" "business_hours" {
connection_profile = "cluster1"
policy_name = "business-hours"
source_path = "/projects"
schedule {
timezone = "UTC"
frequency = "SCHEDULE_HOURLY_OR_LESS"
on_days = ["MON", "TUE", "WED", "THU", "FRI"]
window_start_hour = 9
window_start_minute = 0
window_end_hour = 17
window_end_minute = 0
fire_every_interval = "FIRE_IN_HOURS"
fire_every = 1
expiration_time_to_live = "24hours"
}
}
# -----------------------------------------------------------------------------
# Monthly Archive Policy (using source_file_id)
# Takes a snapshot on the 1st of each month, never expires
# -----------------------------------------------------------------------------
resource "qumulo_snapshot_policy" "monthly_archive" {
connection_profile = "cluster1"
policy_name = "monthly-archive"
source_file_id = "2" # Root directory, use source_path for most cases
schedule {
timezone = "UTC"
frequency = "SCHEDULE_MONTHLY"
day_of_month = 1
hour = 0
minute = 0
expiration_time_to_live = "never"
}
}
# -----------------------------------------------------------------------------
# Weekly Compliance Policy
# Takes a snapshot every Sunday at midnight for compliance retention
# -----------------------------------------------------------------------------
resource "qumulo_snapshot_policy" "weekly_compliance" {
connection_profile = "cluster1"
policy_name = "weekly-compliance"
source_path = "/compliance-data"
schedule {
timezone = "UTC"
frequency = "SCHEDULE_DAILY_OR_WEEKLY"
hour = 0
minute = 0
on_days = ["SUN"]
expiration_time_to_live = "90days"
}
}
# -----------------------------------------------------------------------------
# Department Snapshot Policies using for_each
# Demonstrates managing multiple policies with a single resource block
# -----------------------------------------------------------------------------
variable "department_snapshot_config" {
description = "Map of department names to their snapshot configuration"
type = map(object({
path = string
hour = number
retention = string
}))
default = {
engineering = {
path = "/departments/engineering"
hour = 3
retention = "14days"
}
marketing = {
path = "/departments/marketing"
hour = 4
retention = "7days"
}
research = {
path = "/departments/research"
hour = 5
retention = "30days"
}
}
}
resource "qumulo_snapshot_policy" "departments" {
for_each = var.department_snapshot_config
connection_profile = "cluster1"
policy_name = "${each.key}-daily-backup"
source_path = each.value.path
schedule {
timezone = "UTC"
frequency = "SCHEDULE_DAILY_OR_WEEKLY"
hour = each.value.hour
minute = 0
on_days = ["EVERY_DAY"]
expiration_time_to_live = each.value.retention
}
}
# -----------------------------------------------------------------------------
# Multi-Cluster Example
# Demonstrates managing snapshot policies across multiple clusters
# -----------------------------------------------------------------------------
variable "clusters" {
description = "Map of cluster names to their connection configuration"
type = map(object({
endpoint = string
username = string
password = string
}))
default = {}
}
# Note: To use multi-cluster, configure connection_profiles dynamically:
# provider "qumulo" {
# connection_profiles = [
# for name, config in var.clusters : {
# name = name
# endpoint = config.endpoint
# username = config.username
# password = config.password
# }
# ]
# }
#
# resource "qumulo_snapshot_policy" "multi_cluster_backup" {
# for_each = var.clusters
#
# connection_profile = each.key
#
# policy_name = "standard-backup"
# source_path = "/data"
#
# schedule {
# timezone = "UTC"
# frequency = "SCHEDULE_DAILY_OR_WEEKLY"
# hour = 3
# minute = 0
# on_days = ["EVERY_DAY"]
# expiration_time_to_live = "14days"
# }
# }
# -----------------------------------------------------------------------------
# Outputs
# -----------------------------------------------------------------------------
output "daily_backup_policy_id" {
description = "ID of the daily backup snapshot policy"
value = qumulo_snapshot_policy.daily_backup.id
}
output "daily_backup_schedule_id" {
description = "Schedule ID of the daily backup policy"
value = qumulo_snapshot_policy.daily_backup.schedule_id
}
output "daily_backup_source_file_id" {
description = "Resolved file ID for the daily backup source path"
value = qumulo_snapshot_policy.daily_backup.source_file_id
}
output "business_hours_policy_id" {
description = "ID of the business hours snapshot policy"
value = qumulo_snapshot_policy.business_hours.id
}
output "monthly_archive_policy_id" {
description = "ID of the monthly archive snapshot policy"
value = qumulo_snapshot_policy.monthly_archive.id
}
output "department_policy_ids" {
description = "Map of department names to their snapshot policy IDs"
value = { for k, v in qumulo_snapshot_policy.departments : k => v.id }
}