Autonomous Database: Simple Tenancy Report via Python

When managing Oracle Cloud Infrastructure (OCI) environments, one common task for administrators is to inventory all Autonomous Databases across a tenancy. This can be particularly challenging if your tenancy spans multiple regions and compartments.

To solve this, we can leverage the OCI Python SDK to:
Scan all subscribed regions.
Iterate through all compartments (including subcompartments).
Retrieve Autonomous Database (ADB) details using the OCI Database APIs.
Export the results into a CSV file for easy reporting.

This blog post walks you through a Python script that does exactly that.

Prerequisites

1. Install the OCI Python SDK:

pip install oci

2. Configure your OCI credentials in ~/.oci/config.

Refer to the OCI SDK Configuration Documentation for details:
https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/pythonsdk.htm#config

Key OCI APIs Used

The script relies on several core APIs from the OCI Python SDK:

Identity Service:
– list_region_subscriptions: Get the list of all regions subscribed by the tenancy.
– list_compartments: Recursively retrieve all compartments in a tenancy.

Database Service:
– list_autonomous_databases: List all Autonomous Databases in a compartment.
– get_autonomous_database: Retrieve detailed information about a specific Autonomous Database.

The Script

Below is the Python script that ties everything together:

import oci
import csv

def main():
    config = oci.config.from_file("~/.oci/config", "DEFAULT")
    tenancy_id = config["tenancy"]
    identity_client = oci.identity.IdentityClient(config)
    regions = identity_client.list_region_subscriptions(tenancy_id).data
    output_file = "autonomous_databases.csv"

    headers = [
        "region", "display_name", "db_name", "lifecycle_state",
        "compute_count", "data_storage_size_in_tbs", "actual_used_data_storage_size_in_tbs",
        "db_version", "time_created", "license_model", "subnet_defined", "private_endpoint_defined",
        "whitelisted_ips", "maintenance_schedule_type", "backup_retention_period_in_days",
        "data_safe_status", "db_workload", "is_auto_scaling_enabled",
        "is_remote_data_guard_enabled", "is_local_data_guard_enabled",
        "local_disaster_recovery_type"
    ]

    with open(output_file, mode="w", newline="", encoding="utf-8") as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(headers)

        for region in regions:
            region_name = region.region_name
            print(f"Scanning region: {region_name}")
            config["region"] = region_name
            database_client = oci.database.DatabaseClient(config)

            compartments = oci.pagination.list_call_get_all_results(
                identity_client.list_compartments,
                tenancy_id,
                compartment_id_in_subtree=True
            ).data + [identity_client.get_compartment(tenancy_id).data]

            for compartment in compartments:
                try:
                    adb_list = oci.pagination.list_call_get_all_results(
                        database_client.list_autonomous_databases,
                        compartment.id
                    ).data

                    for adb in adb_list:
                        adb_details = database_client.get_autonomous_database(adb.id).data

                        row = [
                            region_name,
                            adb_details.display_name,
                            adb_details.db_name,
                            adb_details.lifecycle_state,
                            getattr(adb_details, "compute_count", None),
                            adb_details.data_storage_size_in_tbs,
                            getattr(adb_details, "actual_used_data_storage_size_in_tbs", None),
                            adb_details.db_version,
                            adb_details.time_created,
                            adb_details.license_model,
                            "Yes" if getattr(adb_details, "subnet_id", None) else "No",
                            "Yes" if getattr(adb_details, "private_endpoint", None) else "No",
                            ",".join(adb_details.whitelisted_ips) if adb_details.whitelisted_ips else None,
                            getattr(adb_details, "maintenance_schedule_type", None),
                            getattr(adb_details, "backup_retention_period_in_days", None),
                            getattr(adb_details, "data_safe_status", None),
                            getattr(adb_details, "db_workload", None),
                            getattr(adb_details, "is_auto_scaling_enabled", None),
                            getattr(adb_details, "is_remote_data_guard_enabled", None),
                            getattr(adb_details, "is_local_data_guard_enabled", None),
                            getattr(adb_details, "local_disaster_recovery_type", None),
                        ]
                        writer.writerow(row)

                except Exception as e:
                    print(f"Error scanning compartment {compartment.name} in {region_name}: {e}")

    print(f"All Autonomous Databases exported to {output_file}")

if __name__ == "__main__":
    main()

What the Script Collects

For each Autonomous Database, the script retrieves:
– Basic Information: Region, display name, DB name, lifecycle state, DB version.
– Compute & Storage: compute_count, allocated and actual used storage.
– Networking: Whether a subnet and private endpoint are configured.
– Maintenance & Backup: Schedule type, backup retention period.
– Security & Features: Data Safe status, workload type, auto-scaling, Data Guard settings, disaster recovery type.

Output Example

The output is a CSV file (autonomous_databases.csv) where each row represents one Autonomous Database.

Conclusion

With just a few lines of Python and the OCI SDK, you can automate the discovery of all Autonomous Databases across your tenancy — saving time and ensuring no database is overlooked.

For more details, check out the official documentation:
– OCI Python SDK Reference: https://docs.oracle.com/en-us/iaas/tools/python/latest/index.html
– Autonomous Database API Reference: https://docs.oracle.com/en-us/iaas/api/#/en/database/20160918/AutonomousDatabase/