195 lines
6.4 KiB
Bash
195 lines
6.4 KiB
Bash
|
|
#!/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 <file>] [--help]"
|
|||
|
|
SCRIPT_OPTIONS="--json <file> 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
|
|||
|
|
|