Remove Unattached Block Volumes

To remove all unattached block volumes from a tenancy in OCI use the following pseudo code- make sure to updated it as needed.

All that is needed is the admin access to OCI via oci cli and the tenancy ID.

The script combs through each compartment and child compartment and finds and prints the command(s) to delete them via the oci cli.

import subprocess
import json
from tqdm import tqdm

TENANCY_OCID = "YOUR_TENANCY_OCID_HERE"

def run_command(command):
    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    output, error = process.communicate()
    if process.returncode != 0:
        print(f"Error executing command: {command}. Error: {error.decode('utf-8')}")
        return None
    return output.decode('utf-8')

def list_compartments():
    command = f'oci iam compartment list --all --compartment-id {TENANCY_OCID} --query "data[*].id"'
    output = run_command(command)
    compartments = json.loads(output)
    compartments.append(TENANCY_OCID)  # Include the root compartment
    return compartments

def list_all_volumes(compartment_id):
    command = f'oci bv volume list --compartment-id {compartment_id} --query "data[*].id"'
    output = run_command(command)
    return json.loads(output)

def list_attached_volumes(compartment_id):
    command = f'oci compute volume-attachment list --compartment-id {compartment_id} --query "data[*].volume-id"'
    output = run_command(command)
    return json.loads(output)

def main():
    compartments = list_compartments()
    all_volumes = []
    attached_volumes = []

    print("Fetching volume details...")
    for compartment in tqdm(compartments):
        all_volumes.extend(list_all_volumes(compartment))
        attached_volumes.extend(list_attached_volumes(compartment))

    unattached_volumes = set(all_volumes) - set(attached_volumes)

    print("\nUnattached Volumes:")
    for volume in unattached_volumes:
        print(volume)
        print(f"Command to delete: oci bv volume delete --volume-id {volume} --force")

if __name__ == "__main__":
    main()