Block storage volumes have at least one backup
OpenStack block storage volumes are evaluated to verify that at least one backup exists. Volume backups provide disaster recovery capability by storing volume data in a separate storage backend (e.g., Swift or Ceph). Without backups, data loss from volume corruption, accidental deletion, or infrastructure failure is irrecoverable.
Risk
Volumes without backups are vulnerable to permanent data loss from hardware failures, accidental deletion, software bugs, or ransomware attacks. Without backups, recovery from disasters requires rebuilding data from scratch, which may be impossible for stateful applications.
Run this check with Prowler
Run in Prowler Cloudprowler openstack --checks blockstorage_volume_backup_existsRecommendation
Create regular backups for all block storage volumes, especially those containing critical data. Implement automated backup schedules. Use incremental backups to reduce storage costs and backup time. Test backup restoration regularly to ensure recoverability.
Remediation
CLI
openstack volume backup create --name <backup_name> <volume_id>Other
Check Code
from collections import Counter
from typing import List
from prowler.lib.check.models import Check, CheckReportOpenStack
from prowler.providers.openstack.services.blockstorage.blockstorage_client import (
blockstorage_client,
)
class blockstorage_volume_backup_exists(Check):
"""Ensure block storage volumes have at least one backup."""
def execute(self) -> List[CheckReportOpenStack]:
findings: List[CheckReportOpenStack] = []
# Build volume_id -> backup count mapping
backup_counts = Counter(
backup.volume_id for backup in blockstorage_client.backups
)
for volume in blockstorage_client.volumes:
report = CheckReportOpenStack(metadata=self.metadata(), resource=volume)
count = backup_counts.get(volume.id, 0)
if count > 0:
report.status = "PASS"
report.status_extended = (
f"Volume {volume.name} ({volume.id}) has {count} backup(s)."
)
else:
report.status = "FAIL"
report.status_extended = (
f"Volume {volume.name} ({volume.id}) does not have any backups."
)
findings.append(report)
return findings