#!/usr/bin/env bash # Check Azure resource naming conventions # Identifies resources that don't follow the standard naming pattern # # REFACTORED - Uses common libraries set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/init.sh" SCRIPT_NAME="check-naming-conventions.sh" SCRIPT_DESC="Audit Azure resource naming conventions and categorize standard vs legacy vs non-standard" SCRIPT_USAGE="${SCRIPT_NAME} [--json ] [--help]" SCRIPT_OPTIONS="--json Write detailed JSON output to file\n--help Show help" SCRIPT_REQUIREMENTS="Azure CLI (ensure_azure_cli)" handle_help "${1:-}" # Initialize SUBSCRIPTION_ID="$(get_subscription_id)" ensure_azure_cli || exit 1 set_subscription "$SUBSCRIPTION_ID" || true log_section "CHECKING AZURE RESOURCE NAMING CONVENTIONS" # Standard naming pattern: {cloud}-{env}-{region}-{resource}-{purpose}-{instance} # Examples: # - Key Vault: az-p-{code}-kv-secrets-001 # - Resource Group: az-p-{code}-rg-sec-001 # - AKS: az-p-{code}-aks-main # Check function for standard pattern check_naming() { local name=$1 local resource_type=$2 local location=$3 # Standard pattern should start with az-p-, az-d-, or az-we- (dev environment) if [[ ! "$name" =~ ^az-[pdwe]- ]]; then return 1 fi # Should contain dashes (not legacy format without dashes) if [[ "$name" =~ ^az[pd][a-z]+ ]]; then return 1 fi # Should follow pattern: az-{env}-{code}-{type}-{purpose}-{instance} # Region code should be exactly 3 characters for standard format # Or: az-{env}-{type}-{purpose}-{instance} (for dev/main resources) # Or: az-{env}-{code}-aks-{purpose} (for dev AKS clusters) # Basic validation - check for 3-char region code pattern if [[ "$name" =~ ^az-[pdwe]-[a-z]{3}-[a-z]+- ]] || [[ "$name" =~ ^az-[we]-[a-z]+- ]] || [[ "$name" =~ ^az-[we]-[a-z]+-aks- ]]; then return 0 fi return 1 } echo "=" | awk '{printf "%-80s\n", ""}' echo "📊 KEY VAULTS" echo "=" | awk '{printf "%-80s\n", ""}' KEY_VAULTS=$(az keyvault list --query "[].{Name:name, RG:resourceGroup, Location:location}" -o tsv 2>/dev/null || true) STANDARD_COUNT=0 LEGACY_COUNT=0 OTHER_COUNT=0 if [ -n "$KEY_VAULTS" ]; then while IFS=$'\t' read -r name rg location; do if [ -z "$name" ]; then continue fi if check_naming "$name" "keyvault" "$location"; then log_success "✓ $name (RG: $rg)" STANDARD_COUNT=$((STANDARD_COUNT + 1)) elif [[ "$name" =~ ^azp[a-z]+kvsecrets001$ ]]; then log_warn "⚠ $name (RG: $rg) - Legacy format (no dashes)" LEGACY_COUNT=$((LEGACY_COUNT + 1)) else log_error "✗ $name (RG: $rg) - Non-standard format" OTHER_COUNT=$((OTHER_COUNT + 1)) fi done <<< "$KEY_VAULTS" else echo "No Key Vaults found" fi echo "=" | awk '{printf "%-80s\n", ""}' echo "📊 RESOURCE GROUPS" echo "=" | awk '{printf "%-80s\n", ""}' RESOURCE_GROUPS=$(az group list --query "[].{Name:name, Location:location}" -o tsv 2>/dev/null || true) RG_STANDARD=0 RG_LEGACY=0 RG_OTHER=0 if [ -n "$RESOURCE_GROUPS" ]; then while IFS=$'\t' read -r name location; do if [ -z "$name" ]; then continue fi # Skip MC_ resource groups (Azure-managed for AKS) if [[ "$name" =~ ^MC_ ]]; then continue fi if check_naming "$name" "resourcegroup" "$location"; then log_success "✓ $name" RG_STANDARD=$((RG_STANDARD + 1)) elif [[ "$name" =~ ^az[pd][a-z]+rg ]]; then log_warn "⚠ $name - Legacy format (no dashes)" RG_LEGACY=$((RG_LEGACY + 1)) else # Check if it's a project resource group or Azure-managed if [[ "$name" =~ defi-oracle|besu|chain138 ]]; then log_info "ℹ $name - Project-specific (acceptable)" elif [[ "$name" =~ ^NetworkWatcherRG$|^DefaultResourceGroup- ]]; then log_info "ℹ $name - Azure-managed (acceptable)" else log_error "✗ $name - Non-standard format" RG_OTHER=$((RG_OTHER + 1)) fi fi done <<< "$RESOURCE_GROUPS" else echo "No Resource Groups found" fi echo "=" | awk '{printf "%-80s\n", ""}' echo "📊 AKS CLUSTERS" echo "=" | awk '{printf "%-80s\n", ""}' AKS_CLUSTERS=$(az aks list --query "[].{Name:name, RG:resourceGroup, Location:location}" -o tsv 2>/dev/null || true) AKS_STANDARD=0 AKS_OTHER=0 if [ -n "$AKS_CLUSTERS" ]; then while IFS=$'\t' read -r name rg location; do if [ -z "$name" ]; then continue fi if check_naming "$name" "aks" "$location"; then log_success "✓ $name (RG: $rg)" AKS_STANDARD=$((AKS_STANDARD + 1)) elif [[ "$name" =~ ^az-(we|d)-.*-aks- ]] || [[ "$name" =~ ^az-we-aks- ]] || [[ "$name" =~ ^az-we-rg-dev- ]]; then log_info "ℹ $name (RG: $rg) - Dev environment (acceptable)" AKS_STANDARD=$((AKS_STANDARD + 1)) # Count as acceptable else log_error "✗ $name (RG: $rg) - Non-standard format" AKS_OTHER=$((AKS_OTHER + 1)) fi done <<< "$AKS_CLUSTERS" else echo "No AKS clusters found" fi echo "=" | awk '{printf "%-80s\n", ""}' echo "📊 SUMMARY" echo "=" | awk '{printf "%-80s\n", ""}' echo "Key Vaults:" echo " ✓ Standard format: $STANDARD_COUNT" echo " ⚠ Legacy format: $LEGACY_COUNT" echo " ✗ Non-standard: $OTHER_COUNT" echo "Resource Groups:" echo " ✓ Standard format: $RG_STANDARD" echo " ⚠ Legacy format: $RG_LEGACY" echo " ✗ Non-standard: $RG_OTHER" echo "AKS Clusters:" echo " ✓ Standard format: $AKS_STANDARD" echo " ✗ Non-standard: $AKS_OTHER" if [ "$LEGACY_COUNT" -gt 0 ] || [ "$RG_LEGACY" -gt 0 ] || [ "$OTHER_COUNT" -gt 0 ] || [ "$RG_OTHER" -gt 0 ] || [ "$AKS_OTHER" -gt 0 ]; then log_warn "⚠️ Some resources use non-standard naming conventions" echo "Recommendations:" echo " 1. Use standard format: az-p-{code}-{type}-{purpose}-{instance}" echo " 2. Legacy resources cannot be renamed (Azure limitation)" echo " 3. Create new resources with standard naming when possible" echo " 4. See docs/NAMING_CONVENTIONS.md for details" exit 1 else log_success "✅ All resources follow standard naming conventions" exit 0 fi