#!/usr/bin/env bash # List all Azure resources in the subscription using Azure CLI # REFACTORED - Uses common libraries # Organizes resources by type and resource group set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" load_env --file "$SCRIPT_DIR/../../.env" ${ENV_PROFILE:+--profile "$ENV_PROFILE"} SCRIPT_NAME="list-all-resources.sh" SCRIPT_DESC="List all Azure resources by type and resource group, with Key Vault & AKS detail" SCRIPT_USAGE="${SCRIPT_NAME} [--json ] [--help]" SCRIPT_OPTIONS="--json Also export full az resource list JSON to file\n--help Show help" SCRIPT_REQUIREMENTS="Azure CLI (ensure_azure_cli), subscription access" handle_help "${1:-}" # Initialize SUBSCRIPTION_ID="$(get_subscription_id)" ensure_azure_cli || exit 1 set_subscription "$SUBSCRIPTION_ID" || true CURRENT_SUB=$(az account show --query id -o tsv) CURRENT_SUB_NAME=$(az account show --query name -o tsv) log_section "LISTING ALL AZURE RESOURCES" log_info "Subscription: $CURRENT_SUB_NAME" log_info "Subscription ID: $CURRENT_SUB" echo "" # Get all resource groups log_info "Getting resource groups..." RESOURCE_GROUPS=$(az group list --query "[].name" -o tsv 2>/dev/null) if [ -z "$RESOURCE_GROUPS" ]; then log_warn "No resource groups found" exit 0 fi RG_COUNT=$(echo "$RESOURCE_GROUPS" | wc -l) log_success "Found $RG_COUNT resource groups" echo "" # Resource type groups declare -A RESOURCE_TYPES=( ["Key Vaults"]="Microsoft.KeyVault/vaults" ["Kubernetes Clusters"]="Microsoft.ContainerService/managedClusters" ["Virtual Networks"]="Microsoft.Network/virtualNetworks" ["Storage Accounts"]="Microsoft.Storage/storageAccounts" ["Application Gateways"]="Microsoft.Network/applicationGateways" ["Load Balancers"]="Microsoft.Network/loadBalancers" ["Public IPs"]="Microsoft.Network/publicIPAddresses" ["NICs"]="Microsoft.Network/networkInterfaces" ["Subnets"]="Microsoft.Network/virtualNetworks/subnets" ["Log Analytics Workspaces"]="Microsoft.OperationalInsights/workspaces" ["Virtual Machines"]="Microsoft.Compute/virtualMachines" ["Disks"]="Microsoft.Compute/disks" ["Network Security Groups"]="Microsoft.Network/networkSecurityGroups" ["Route Tables"]="Microsoft.Network/routeTables" ) # Summary statistics TOTAL_RESOURCES=0 declare -A TYPE_COUNTS echo "=" | awk '{printf "%-80s\n", ""}' echo "πŸ“Š RESOURCES BY TYPE" echo "=" | awk '{printf "%-80s\n", ""}' echo "" # List resources by type for TYPE_NAME in "${!RESOURCE_TYPES[@]}"; do TYPE_PROVIDER="${RESOURCE_TYPES[$TYPE_NAME]}" RESOURCES=$(az resource list --resource-type "$TYPE_PROVIDER" --query "[].{Name:name, RG:resourceGroup, Location:location}" -o tsv 2>/dev/null || true) if [ -n "$RESOURCES" ]; then COUNT=$(echo "$RESOURCES" | wc -l) TYPE_COUNTS["$TYPE_NAME"]=$COUNT TOTAL_RESOURCES=$((TOTAL_RESOURCES + COUNT)) log_info "$TYPE_NAME: $COUNT" echo "$RESOURCES" | while IFS=$'\t' read -r name rg location; do if [ -n "$name" ]; then printf " %-50s | %-30s | %s\n" "$name" "$rg" "$location" fi done echo "" fi done echo "=" | awk '{printf "%-80s\n", ""}' echo "πŸ“Š RESOURCES BY RESOURCE GROUP" echo "=" | awk '{printf "%-80s\n", ""}' echo "" # List all resources grouped by resource group TOTAL_BY_RG=0 for RG in $RESOURCE_GROUPS; do log_info "Resource Group: $RG" RG_RESOURCES=$(az resource list --resource-group "$RG" --query "[].{Name:name, Type:type, Location:location}" -o tsv 2>/dev/null || true) if [ -n "$RG_RESOURCES" ]; then RG_COUNT=$(echo "$RG_RESOURCES" | wc -l) TOTAL_BY_RG=$((TOTAL_BY_RG + RG_COUNT)) echo "$RG_RESOURCES" | while IFS=$'\t' read -r name type location; do if [ -n "$name" ]; then TYPE_SHORT=$(echo "$type" | cut -d'/' -f2- | sed 's|/|/|') printf " %-50s | %-40s | %s\n" "$name" "$TYPE_SHORT" "$location" fi done echo "" else log_warn " (empty)" echo "" fi done # Get all resources (catch-all for any types not in our list) echo "=" | awk '{printf "%-80s\n", ""}' echo "πŸ“Š ALL RESOURCES (SUMMARY)" echo "=" | awk '{printf "%-80s\n", ""}' echo "" ALL_RESOURCES=$(az resource list --query "[].{Name:name, Type:type, RG:resourceGroup, Location:location}" -o tsv 2>/dev/null || true) if [ -n "$ALL_RESOURCES" ]; then TOTAL_ALL=$(echo "$ALL_RESOURCES" | wc -l) echo "Total resources: $TOTAL_ALL" echo "" # Count by resource type log_info "Resources by type:" echo "$ALL_RESOURCES" | cut -f2 | sort | uniq -c | sort -rn | head -20 | while read count type; do TYPE_SHORT=$(echo "$type" | cut -d'/' -f2- | sed 's|/|/|') printf " %4s %s\n" "$count" "$TYPE_SHORT" done echo "" fi echo "=" | awk '{printf "%-80s\n", ""}' echo "πŸ“Š SUMMARY" echo "=" | awk '{printf "%-80s\n", ""}' echo "" echo "Subscription: $CURRENT_SUB_NAME" echo "Subscription ID: $CURRENT_SUB" echo "Resource Groups: $RG_COUNT" echo "Total Resources (by RG): $TOTAL_BY_RG" if [ -n "$ALL_RESOURCES" ]; then echo "Total Resources (all): $TOTAL_ALL" fi echo "" # List Key Vaults separately (most important for this project) echo "=" | awk '{printf "%-80s\n", ""}' echo "πŸ” KEY VAULTS DETAIL" echo "=" | awk '{printf "%-80s\n", ""}' echo "" KEY_VAULTS=$(az keyvault list --query "[].{Name:name, RG:resourceGroup, Location:location}" -o tsv 2>/dev/null || true) if [ -n "$KEY_VAULTS" ]; then KV_COUNT=$(echo "$KEY_VAULTS" | wc -l) echo "Key Vaults: $KV_COUNT" echo "" echo "$KEY_VAULTS" | while IFS=$'\t' read -r name rg location; do if [ -n "$name" ]; then echo " Key Vault: $name" echo " Resource Group: $rg" echo " Location: $location" # Get secrets count SECRETS_COUNT=$(az keyvault secret list --vault-name "$name" --query "length(@)" -o tsv 2>/dev/null || echo "0") echo " Secrets: $SECRETS_COUNT" # Get RBAC status IS_RBAC=$(az keyvault show --name "$name" --query "properties.enableRbacAuthorization" -o tsv 2>/dev/null || echo "false") echo " RBAC Enabled: $IS_RBAC" echo "" fi done else log_warn "No Key Vaults found" echo "" fi # List AKS clusters separately echo "=" | awk '{printf "%-80s\n", ""}' echo "☸️ KUBERNETES CLUSTERS DETAIL" echo "=" | awk '{printf "%-80s\n", ""}' echo "" AKS_CLUSTERS=$(az aks list --query "[].{Name:name, RG:resourceGroup, Location:location, Version:kubernetesVersion, Status:powerState.code}" -o tsv 2>/dev/null || true) if [ -n "$AKS_CLUSTERS" ]; then AKS_COUNT=$(echo "$AKS_CLUSTERS" | wc -l) echo "AKS Clusters: $AKS_COUNT" echo "" echo "$AKS_CLUSTERS" | while IFS=$'\t' read -r name rg location version status; do if [ -n "$name" ]; then echo " Cluster: $name" echo " Resource Group: $rg" echo " Location: $location" echo " Kubernetes Version: $version" echo " Status: $status" # Get node pools NODE_POOLS=$(az aks nodepool list --cluster-name "$name" --resource-group "$rg" --query "[].{Name:name, Count:count, VM:vmSize}" -o tsv 2>/dev/null || true) if [ -n "$NODE_POOLS" ]; then echo " Node Pools:" echo "$NODE_POOLS" | while IFS=$'\t' read -r np_name np_count np_vm; do if [ -n "$np_name" ]; then echo " - $np_name: $np_count nodes ($np_vm)" fi done fi echo "" fi done else log_warn "No AKS clusters found" echo "" fi # Export to JSON option if [ "$1" = "--json" ]; then OUTPUT_FILE="${2:-azure-resources-$(date +%Y%m%d-%H%M%S).json}" echo "Exporting to JSON: $OUTPUT_FILE" az resource list --output json > "$OUTPUT_FILE" log_success "Exported to $OUTPUT_FILE" echo "" fi log_success "Resource listing complete!" echo ""