Block storage volumes are attached to instances
OpenStack block storage volumes are evaluated to verify they are attached to at least one instance. Unattached volumes may indicate orphaned resources that are no longer in use but continue to incur storage costs and may contain sensitive data without active monitoring or access controls.
Risk
Unattached volumes may contain sensitive data that is no longer actively managed or monitored. Orphaned volumes increase storage costs and can be overlooked during security audits. If unattached volumes contain credentials or sensitive data, they may be accessed by unauthorized users who gain project access.
Run this check with Prowler
Run in Prowler Cloudprowler openstack --checks blockstorage_volume_not_unattachedRecommendation
Review unattached volumes regularly and delete those no longer needed. Back up important data before deletion. Implement volume lifecycle policies and automated cleanup for orphaned resources. Tag volumes with ownership and purpose metadata for easier management.
Remediation
CLI
openstack volume list --status available
openstack volume delete <volume_id>Other
Check Code
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_not_unattached(Check):
"""Ensure block storage volumes are attached to at least one instance."""
def execute(self) -> List[CheckReportOpenStack]:
findings: List[CheckReportOpenStack] = []
for volume in blockstorage_client.volumes:
report = CheckReportOpenStack(metadata=self.metadata(), resource=volume)
attachment_count = len(volume.attachments)
if attachment_count > 0:
report.status = "PASS"
report.status_extended = f"Volume {volume.name} ({volume.id}) is attached to {attachment_count} instance(s)."
elif volume.status != "available":
report.status = "PASS"
report.status_extended = (
f"Volume {volume.name} ({volume.id}) is not attached but is in "
f"'{volume.status}' state (not idle)."
)
else:
report.status = "FAIL"
report.status_extended = f"Volume {volume.name} ({volume.id}) is unattached and may be orphaned."
findings.append(report)
return findings