From 7b64ca203c07086a65e9b6ac2c8cc5a64bf94e14 Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Wed, 22 Jan 2025 14:46:58 +0000 Subject: [PATCH 1/8] Add PowerShell and Bash scripts for Synapse Pause/Resume --- .../scripts/pause_resume_synapse.ps1 | 163 +++++++++++++++ .../scripts/pause_resume_synapse.sh | 188 ++++++++++++++++++ 2 files changed, 351 insertions(+) create mode 100755 e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 create mode 100755 e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh diff --git a/e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 b/e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 new file mode 100755 index 000000000..e9b443a19 --- /dev/null +++ b/e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 @@ -0,0 +1,163 @@ +# PowerShell script to Pause or Resume Azure Synapse SQL Pools and Azure SQL Data Warehouse (Dedicated SQL Pools). +# Requires Azure CLI installed and logged in. + +param( + [string]$SubscriptionId, + [string]$DeploymentIds, + [string]$Project, + [string]$Environments = "dev,stg,prod", + [string]$ResourceGroups, + [string]$Action = "Pause", + [switch]$DryRun +) + +# Function to display usage +function Show-Usage { + Write-Host "Usage: .\Script.ps1 -SubscriptionId [-DeploymentIds ] -Project -Environments `n[-ResourceGroups ] -Action [-DryRun]" -ForegroundColor Yellow + Write-Host " -SubscriptionId Azure Subscription ID (required)." + Write-Host " -DeploymentIds Deployment IDs (comma-separated, required if ResourceGroups is not specified)." + Write-Host " -Project Project name (required if ResourceGroups is not specified)." + Write-Host " -Environments Environments (default: dev,stg,prod)." + Write-Host " -ResourceGroups Resource groups override (comma-separated)." + Write-Host " -Action Action to perform: Pause or Resume (default: Pause)." + Write-Host " -DryRun Simulate actions without making any changes." + exit 1 +} + +# Validate required parameters +if (-not $SubscriptionId) { + Write-Host "ERROR: SubscriptionId is required." -ForegroundColor Red + Show-Usage +} + +if (-not $ResourceGroups -and (-not $DeploymentIds -or -not $Project)) { + Write-Host "ERROR: DeploymentIds and Project are required if ResourceGroups is not specified." -ForegroundColor Red + Show-Usage +} + +# Generate or override resource group names +$ResourceGroupsList = @() +if ($ResourceGroups) { + $ResourceGroupsList = $ResourceGroups -split ',' +} else { + foreach ($env in $Environments -split ',') { + foreach ($deploymentId in $DeploymentIds -split ',') { + $env = $env.Trim() # Ensure no extra spaces + $deploymentId = $deploymentId.Trim() # Ensure no extra spaces + $ResourceGroupsList += "${Project}-${deploymentId}-dbw-${env}-rg" + $ResourceGroupsList += "${Project}-${deploymentId}-${env}-rg" + } + } +} + +Write-Host "INFO: Using Resource Groups: $($ResourceGroupsList -join ', ')" -ForegroundColor Green + +# Set Azure subscription +az account set --subscription $SubscriptionId + +# Function to process Synapse SQL Pools +function Process-SynapseSqlPool { + param ( + [string]$ResourceGroup, + [string]$Action + ) + + $workspaces = az synapse workspace list --resource-group $ResourceGroup --query "[].name" -o tsv 2>$null + if (-not $workspaces) { + Write-Host "WARNING: No Synapse Workspaces found in Resource Group: $ResourceGroup" -ForegroundColor Yellow + return + } + + foreach ($workspace in $workspaces) { + Write-Host " INFO: Checking Workspace: $workspace" -ForegroundColor Green + + $sqlPools = az synapse sql pool list --workspace-name $workspace --resource-group $ResourceGroup --query "[].{name:name,status:status}" -o tsv + if (-not $sqlPools) { + Write-Host " WARNING: No SQL Pools found in Workspace: $workspace" -ForegroundColor Yellow + continue + } + + foreach ($sqlPool in $sqlPools) { + $poolName, $poolStatus = $sqlPool -split "\t" + Write-Host " INFO: SQL Pool: $poolName (Status: $poolStatus)" -ForegroundColor Green + + if (($Action -eq "Pause" -and $poolStatus -eq "Online") -or ($Action -eq "Resume" -and $poolStatus -eq "Paused")) { + Write-Host " $Action-ing Synapse SQL Pool: $poolName" -ForegroundColor Green + if (-not $DryRun) { + if ($Action -eq "Pause") { + az synapse sql pool pause --name $poolName --workspace-name $workspace --resource-group $ResourceGroup + } else { + az synapse sql pool resume --name $poolName --workspace-name $workspace --resource-group $ResourceGroup + } + Write-Host " Successfully $Action-ed Synapse SQL Pool: $poolName" -ForegroundColor Green + } else { + Write-Host " Dry Run: Would have $Action-ed Synapse SQL Pool: $poolName" -ForegroundColor Green + } + } else { + Write-Host " SQL Pool: $poolName is already in the desired state." -ForegroundColor Green + } + } + } +} + +# Function to process Azure SQL Data Warehouse (Dedicated SQL Pools) +function Process-SqlDatabase { + param ( + [string]$ResourceGroup, + [string]$Action + ) + + $sqlServers = az sql server list --resource-group $ResourceGroup --query "[].name" -o tsv 2>$null + if (-not $sqlServers) { + Write-Host "WARNING: No SQL Servers found in Resource Group: $ResourceGroup" -ForegroundColor Yellow + return + } + + foreach ($server in $sqlServers) { + Write-Host " INFO: Checking SQL Server: $server" -ForegroundColor Green + + $sqlDws = az sql dw list --server $server --resource-group $ResourceGroup --query "[].{name:name,status:status}" -o tsv + if (-not $sqlDws) { + Write-Host " WARNING: No Dedicated SQL Pools found on Server: $server" -ForegroundColor Yellow + continue + } + + foreach ($sqlDw in $sqlDws) { + $dwName, $dwStatus = $sqlDw -split "\t" + Write-Host " INFO: Dedicated SQL Pool: $dwName (Status: $dwStatus)" -ForegroundColor Green + + if (($Action -eq "Pause" -and $dwStatus -eq "Online") -or ($Action -eq "Resume" -and $dwStatus -eq "Paused")) { + Write-Host " $Action-ing Dedicated SQL Pool: $dwName" -ForegroundColor Green + if (-not $DryRun) { + if ($Action -eq "Pause") { + az sql dw pause --name $dwName --server $server --resource-group $ResourceGroup + } else { + az sql dw resume --name $dwName --server $server --resource-group $ResourceGroup + } + Write-Host " Successfully $Action-ed Dedicated SQL Pool: $dwName" -ForegroundColor Green + } else { + Write-Host " Dry Run: Would have $Action-ed Dedicated SQL Pool: $dwName" -ForegroundColor Green + } + } else { + Write-Host " Dedicated SQL Pool: $dwName is already in the desired state." -ForegroundColor Green + } + } + } +} + +# Process each resource group +foreach ($resourceGroup in $ResourceGroupsList) { + if (-not (az group show --name $resourceGroup 2>$null)) { + Write-Host "ERROR: Resource Group [$resourceGroup] does not exist. Skipping." -ForegroundColor Red + continue + } + + Write-Host "INFO: Processing Resource Group: $resourceGroup" -ForegroundColor Green + Write-Host "----------------------------------------" + + # Process Synapse SQL Pools + Process-SynapseSqlPool -ResourceGroup $resourceGroup -Action $Action + + # Process Azure SQL Data Warehouse (Dedicated SQL Pools) + Process-SqlDatabase -ResourceGroup $resourceGroup -Action $Action +} diff --git a/e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh b/e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh new file mode 100755 index 000000000..fa92a30b9 --- /dev/null +++ b/e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh @@ -0,0 +1,188 @@ +#!/bin/bash + +# Script to Pause or Resume Azure Synapse SQL Pools and Azure SQL Data Warehouse (Dedicated SQL Pools). +# Requires Azure CLI installed and logged in. + +set -e + +# Parameters +DEPLOYMENT_IDS=() +PROJECT="" +SUBSCRIPTION_ID="" +ENVIRONMENTS=("dev" "stg" "prod") +RESOURCE_GROUPS=() +ACTION="Pause" +DRY_RUN=false + +# Function to display usage +usage() { + echo "Usage: $0 -s SUBSCRIPTION_ID [-d DEPLOYMENT_IDS -p PROJECT -e ENVIRONMENTS] [-r RESOURCE_GROUPS] [-a ACTION] [--dry-run]" + echo " -s | --subscription-id Azure Subscription ID (required)." + echo " -d | --deployment-ids Deployment IDs (comma-separated, required if --resource-groups is not specified)." + echo " -p | --project Project name (required if --resource-groups is not specified)." + echo " -e | --environments Environments (comma-separated, default: dev,stg,prod)." + echo " -r | --resource-groups Resource groups (comma-separated)." + echo " -a | --action Action to perform: Pause or Resume (default: Pause)." + echo " --dry-run Perform a dry run without executing actions." + exit 1 +} + +# Log functions +log_info() { + echo -e "$(tput setaf 2)INFO:$(tput sgr0) $1" +} + +log_warning() { + echo -e "$(tput setaf 3)WARNING:$(tput sgr0) $1" +} + +log_error() { + echo -e "$(tput setaf 1)ERROR:$(tput sgr0) $1" +} + +# Parse arguments +while [[ "$#" -gt 0 ]]; do + case "$1" in + -s|--subscription-id) SUBSCRIPTION_ID="$2"; shift 2;; + -d|--deployment-ids) IFS="," read -r -a DEPLOYMENT_IDS <<< "$2"; shift 2;; + -p|--project) PROJECT="$2"; shift 2;; + -e|--environments) IFS="," read -r -a ENVIRONMENTS <<< "$2"; shift 2;; + -r|--resource-groups) IFS="," read -r -a RESOURCE_GROUPS <<< "$2"; shift 2;; + -a|--action) ACTION="$2"; shift 2;; + --dry-run) DRY_RUN=true; shift;; + *) usage;; + esac +done + +# Validate required parameters +if [[ -z "$SUBSCRIPTION_ID" ]]; then + log_error "SUBSCRIPTION_ID is required." + usage +fi + +if [[ ${#RESOURCE_GROUPS[@]} -eq 0 ]]; then + if [[ ${#DEPLOYMENT_IDS[@]} -eq 0 || -z "$PROJECT" ]]; then + log_error "DEPLOYMENT_IDS and PROJECT are required if --resource-groups is not specified." + usage + fi +fi + +# Generate or override resource group names +if [[ ${#RESOURCE_GROUPS[@]} -gt 0 ]]; then + RESOURCE_GROUPS=(${RESOURCE_GROUPS[@]}) +else + for env in "${ENVIRONMENTS[@]}"; do + for deployment_id in "${DEPLOYMENT_IDS[@]}"; do + RESOURCE_GROUPS+=("${PROJECT}-${deployment_id}-dbw-${env}-rg") + RESOURCE_GROUPS+=("${PROJECT}-${deployment_id}-${env}-rg") + done + done +fi + +log_info "Using Resource Groups: ${RESOURCE_GROUPS[*]}" + +# Set Azure subscription +az account set --subscription "$SUBSCRIPTION_ID" + +# Function to process Synapse SQL Pools +process_synapse_sql_pool() { + local resource_group="$1" + local action="$2" + + # Retrieve Synapse Workspaces + workspaces=$(az synapse workspace list --resource-group "$resource_group" --query "[].name" -o tsv 2>/dev/null) + if [[ -z "$workspaces" ]]; then + log_warning "No Synapse Workspaces found in Resource Group: $resource_group" + return + fi + + for workspace in $workspaces; do + log_info " Checking Workspace: $workspace" + + sql_pools=$(az synapse sql pool list --workspace-name "$workspace" --resource-group "$resource_group" --query "[].{name:name,status:status}" -o tsv) + if [[ -z "$sql_pools" ]]; then + log_warning " No SQL Pools found in Workspace: $workspace" + continue + fi + + while IFS=$'\t' read -r pool_name pool_status; do + log_info " SQL Pool: $pool_name (Status: $pool_status)" + + if [[ "$DRY_RUN" == true ]]; then + log_info " Dry Run: Would have ${action}d Synapse SQL Pool: $pool_name" + else + if [[ "$action" == "Pause" && "$pool_status" == "Online" ]]; then + log_info " Pausing Synapse SQL Pool: $pool_name" + az synapse sql pool pause --name "$pool_name" --workspace-name "$workspace" --resource-group "$resource_group" + log_info " Successfully paused Synapse SQL Pool: $pool_name" + elif [[ "$action" == "Resume" && "$pool_status" == "Paused" ]]; then + log_info " Resuming Synapse SQL Pool: $pool_name" + az synapse sql pool resume --name "$pool_name" --workspace-name "$workspace" --resource-group "$resource_group" + log_info " Successfully resumed Synapse SQL Pool: $pool_name" + else + log_info " Synapse SQL Pool: $pool_name is already in the desired state." + fi + fi + done <<< "$sql_pools" + done +} + +# Function to process Azure SQL Data Warehouse (Dedicated SQL Pools) +process_sql_database() { + local resource_group="$1" + local action="$2" + + # Retrieve SQL Servers + sql_servers=$(az sql server list --resource-group "$resource_group" --query "[].name" -o tsv 2>/dev/null) + if [[ -z "$sql_servers" ]]; then + log_warning "No SQL Servers found in Resource Group: $resource_group" + return + fi + + for server in $sql_servers; do + log_info " Checking SQL Server: $server" + + sql_dws=$(az sql dw list --server "$server" --resource-group "$resource_group" --query "[].{name:name,status:status}" -o tsv) + if [[ -z "$sql_dws" ]]; then + log_warning " No Dedicated SQL Pools found on Server: $server" + continue + fi + + while IFS=$'\t' read -r dw_name dw_status; do + log_info " Dedicated SQL Pool: $dw_name (Status: $dw_status)" + + if [[ "$DRY_RUN" == true ]]; then + log_info " Dry Run: Would have ${action}d Dedicated SQL Pool: $dw_name" + else + if [[ "$action" == "Pause" && "$dw_status" == "Online" ]]; then + log_info " Pausing Dedicated SQL Pool: $dw_name" + az sql dw pause --name "$dw_name" --server "$server" --resource-group "$resource_group" + log_info " Successfully paused Dedicated SQL Pool: $dw_name" + elif [[ "$action" == "Resume" && "$dw_status" == "Paused" ]]; then + log_info " Resuming Dedicated SQL Pool: $dw_name" + az sql dw resume --name "$dw_name" --server "$server" --resource-group "$resource_group" + log_info " Successfully resumed Dedicated SQL Pool: $dw_name" + else + log_info " Dedicated SQL Pool: $dw_name is already in the desired state." + fi + fi + done <<< "$sql_dws" + done +} + +# Process each resource group +for resource_group in "${RESOURCE_GROUPS[@]}"; do + if ! az group show --name "$resource_group" &>/dev/null; then + log_error "Resource Group [$resource_group] does not exist. Skipping." + continue + fi + + log_info "Processing Resource Group: $resource_group" + echo "----------------------------------------" + + # Process Synapse SQL Pools + process_synapse_sql_pool "$resource_group" "$ACTION" + + # Process Azure SQL Data Warehouse (Dedicated SQL Pools) + process_sql_database "$resource_group" "$ACTION" +done \ No newline at end of file From 77a15fb53a8a677a71dc72b3f7ccbee1382ac534 Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Fri, 24 Jan 2025 12:42:19 +0000 Subject: [PATCH 2/8] Support Manual and Automated Synapse Pause PowerShell Script with Additional features --- .../scripts/pause_resume_synapse.ps1 | 163 ---------- .../scripts/pause_resume_synapse.sh | 188 ------------ .../utilities/pause_resume_synapse.ps1 | 283 ++++++++++++++++++ 3 files changed, 283 insertions(+), 351 deletions(-) delete mode 100755 e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 delete mode 100755 e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh create mode 100755 e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 diff --git a/e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 b/e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 deleted file mode 100755 index e9b443a19..000000000 --- a/e2e_samples/parking_sensors/scripts/pause_resume_synapse.ps1 +++ /dev/null @@ -1,163 +0,0 @@ -# PowerShell script to Pause or Resume Azure Synapse SQL Pools and Azure SQL Data Warehouse (Dedicated SQL Pools). -# Requires Azure CLI installed and logged in. - -param( - [string]$SubscriptionId, - [string]$DeploymentIds, - [string]$Project, - [string]$Environments = "dev,stg,prod", - [string]$ResourceGroups, - [string]$Action = "Pause", - [switch]$DryRun -) - -# Function to display usage -function Show-Usage { - Write-Host "Usage: .\Script.ps1 -SubscriptionId [-DeploymentIds ] -Project -Environments `n[-ResourceGroups ] -Action [-DryRun]" -ForegroundColor Yellow - Write-Host " -SubscriptionId Azure Subscription ID (required)." - Write-Host " -DeploymentIds Deployment IDs (comma-separated, required if ResourceGroups is not specified)." - Write-Host " -Project Project name (required if ResourceGroups is not specified)." - Write-Host " -Environments Environments (default: dev,stg,prod)." - Write-Host " -ResourceGroups Resource groups override (comma-separated)." - Write-Host " -Action Action to perform: Pause or Resume (default: Pause)." - Write-Host " -DryRun Simulate actions without making any changes." - exit 1 -} - -# Validate required parameters -if (-not $SubscriptionId) { - Write-Host "ERROR: SubscriptionId is required." -ForegroundColor Red - Show-Usage -} - -if (-not $ResourceGroups -and (-not $DeploymentIds -or -not $Project)) { - Write-Host "ERROR: DeploymentIds and Project are required if ResourceGroups is not specified." -ForegroundColor Red - Show-Usage -} - -# Generate or override resource group names -$ResourceGroupsList = @() -if ($ResourceGroups) { - $ResourceGroupsList = $ResourceGroups -split ',' -} else { - foreach ($env in $Environments -split ',') { - foreach ($deploymentId in $DeploymentIds -split ',') { - $env = $env.Trim() # Ensure no extra spaces - $deploymentId = $deploymentId.Trim() # Ensure no extra spaces - $ResourceGroupsList += "${Project}-${deploymentId}-dbw-${env}-rg" - $ResourceGroupsList += "${Project}-${deploymentId}-${env}-rg" - } - } -} - -Write-Host "INFO: Using Resource Groups: $($ResourceGroupsList -join ', ')" -ForegroundColor Green - -# Set Azure subscription -az account set --subscription $SubscriptionId - -# Function to process Synapse SQL Pools -function Process-SynapseSqlPool { - param ( - [string]$ResourceGroup, - [string]$Action - ) - - $workspaces = az synapse workspace list --resource-group $ResourceGroup --query "[].name" -o tsv 2>$null - if (-not $workspaces) { - Write-Host "WARNING: No Synapse Workspaces found in Resource Group: $ResourceGroup" -ForegroundColor Yellow - return - } - - foreach ($workspace in $workspaces) { - Write-Host " INFO: Checking Workspace: $workspace" -ForegroundColor Green - - $sqlPools = az synapse sql pool list --workspace-name $workspace --resource-group $ResourceGroup --query "[].{name:name,status:status}" -o tsv - if (-not $sqlPools) { - Write-Host " WARNING: No SQL Pools found in Workspace: $workspace" -ForegroundColor Yellow - continue - } - - foreach ($sqlPool in $sqlPools) { - $poolName, $poolStatus = $sqlPool -split "\t" - Write-Host " INFO: SQL Pool: $poolName (Status: $poolStatus)" -ForegroundColor Green - - if (($Action -eq "Pause" -and $poolStatus -eq "Online") -or ($Action -eq "Resume" -and $poolStatus -eq "Paused")) { - Write-Host " $Action-ing Synapse SQL Pool: $poolName" -ForegroundColor Green - if (-not $DryRun) { - if ($Action -eq "Pause") { - az synapse sql pool pause --name $poolName --workspace-name $workspace --resource-group $ResourceGroup - } else { - az synapse sql pool resume --name $poolName --workspace-name $workspace --resource-group $ResourceGroup - } - Write-Host " Successfully $Action-ed Synapse SQL Pool: $poolName" -ForegroundColor Green - } else { - Write-Host " Dry Run: Would have $Action-ed Synapse SQL Pool: $poolName" -ForegroundColor Green - } - } else { - Write-Host " SQL Pool: $poolName is already in the desired state." -ForegroundColor Green - } - } - } -} - -# Function to process Azure SQL Data Warehouse (Dedicated SQL Pools) -function Process-SqlDatabase { - param ( - [string]$ResourceGroup, - [string]$Action - ) - - $sqlServers = az sql server list --resource-group $ResourceGroup --query "[].name" -o tsv 2>$null - if (-not $sqlServers) { - Write-Host "WARNING: No SQL Servers found in Resource Group: $ResourceGroup" -ForegroundColor Yellow - return - } - - foreach ($server in $sqlServers) { - Write-Host " INFO: Checking SQL Server: $server" -ForegroundColor Green - - $sqlDws = az sql dw list --server $server --resource-group $ResourceGroup --query "[].{name:name,status:status}" -o tsv - if (-not $sqlDws) { - Write-Host " WARNING: No Dedicated SQL Pools found on Server: $server" -ForegroundColor Yellow - continue - } - - foreach ($sqlDw in $sqlDws) { - $dwName, $dwStatus = $sqlDw -split "\t" - Write-Host " INFO: Dedicated SQL Pool: $dwName (Status: $dwStatus)" -ForegroundColor Green - - if (($Action -eq "Pause" -and $dwStatus -eq "Online") -or ($Action -eq "Resume" -and $dwStatus -eq "Paused")) { - Write-Host " $Action-ing Dedicated SQL Pool: $dwName" -ForegroundColor Green - if (-not $DryRun) { - if ($Action -eq "Pause") { - az sql dw pause --name $dwName --server $server --resource-group $ResourceGroup - } else { - az sql dw resume --name $dwName --server $server --resource-group $ResourceGroup - } - Write-Host " Successfully $Action-ed Dedicated SQL Pool: $dwName" -ForegroundColor Green - } else { - Write-Host " Dry Run: Would have $Action-ed Dedicated SQL Pool: $dwName" -ForegroundColor Green - } - } else { - Write-Host " Dedicated SQL Pool: $dwName is already in the desired state." -ForegroundColor Green - } - } - } -} - -# Process each resource group -foreach ($resourceGroup in $ResourceGroupsList) { - if (-not (az group show --name $resourceGroup 2>$null)) { - Write-Host "ERROR: Resource Group [$resourceGroup] does not exist. Skipping." -ForegroundColor Red - continue - } - - Write-Host "INFO: Processing Resource Group: $resourceGroup" -ForegroundColor Green - Write-Host "----------------------------------------" - - # Process Synapse SQL Pools - Process-SynapseSqlPool -ResourceGroup $resourceGroup -Action $Action - - # Process Azure SQL Data Warehouse (Dedicated SQL Pools) - Process-SqlDatabase -ResourceGroup $resourceGroup -Action $Action -} diff --git a/e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh b/e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh deleted file mode 100755 index fa92a30b9..000000000 --- a/e2e_samples/parking_sensors/scripts/pause_resume_synapse.sh +++ /dev/null @@ -1,188 +0,0 @@ -#!/bin/bash - -# Script to Pause or Resume Azure Synapse SQL Pools and Azure SQL Data Warehouse (Dedicated SQL Pools). -# Requires Azure CLI installed and logged in. - -set -e - -# Parameters -DEPLOYMENT_IDS=() -PROJECT="" -SUBSCRIPTION_ID="" -ENVIRONMENTS=("dev" "stg" "prod") -RESOURCE_GROUPS=() -ACTION="Pause" -DRY_RUN=false - -# Function to display usage -usage() { - echo "Usage: $0 -s SUBSCRIPTION_ID [-d DEPLOYMENT_IDS -p PROJECT -e ENVIRONMENTS] [-r RESOURCE_GROUPS] [-a ACTION] [--dry-run]" - echo " -s | --subscription-id Azure Subscription ID (required)." - echo " -d | --deployment-ids Deployment IDs (comma-separated, required if --resource-groups is not specified)." - echo " -p | --project Project name (required if --resource-groups is not specified)." - echo " -e | --environments Environments (comma-separated, default: dev,stg,prod)." - echo " -r | --resource-groups Resource groups (comma-separated)." - echo " -a | --action Action to perform: Pause or Resume (default: Pause)." - echo " --dry-run Perform a dry run without executing actions." - exit 1 -} - -# Log functions -log_info() { - echo -e "$(tput setaf 2)INFO:$(tput sgr0) $1" -} - -log_warning() { - echo -e "$(tput setaf 3)WARNING:$(tput sgr0) $1" -} - -log_error() { - echo -e "$(tput setaf 1)ERROR:$(tput sgr0) $1" -} - -# Parse arguments -while [[ "$#" -gt 0 ]]; do - case "$1" in - -s|--subscription-id) SUBSCRIPTION_ID="$2"; shift 2;; - -d|--deployment-ids) IFS="," read -r -a DEPLOYMENT_IDS <<< "$2"; shift 2;; - -p|--project) PROJECT="$2"; shift 2;; - -e|--environments) IFS="," read -r -a ENVIRONMENTS <<< "$2"; shift 2;; - -r|--resource-groups) IFS="," read -r -a RESOURCE_GROUPS <<< "$2"; shift 2;; - -a|--action) ACTION="$2"; shift 2;; - --dry-run) DRY_RUN=true; shift;; - *) usage;; - esac -done - -# Validate required parameters -if [[ -z "$SUBSCRIPTION_ID" ]]; then - log_error "SUBSCRIPTION_ID is required." - usage -fi - -if [[ ${#RESOURCE_GROUPS[@]} -eq 0 ]]; then - if [[ ${#DEPLOYMENT_IDS[@]} -eq 0 || -z "$PROJECT" ]]; then - log_error "DEPLOYMENT_IDS and PROJECT are required if --resource-groups is not specified." - usage - fi -fi - -# Generate or override resource group names -if [[ ${#RESOURCE_GROUPS[@]} -gt 0 ]]; then - RESOURCE_GROUPS=(${RESOURCE_GROUPS[@]}) -else - for env in "${ENVIRONMENTS[@]}"; do - for deployment_id in "${DEPLOYMENT_IDS[@]}"; do - RESOURCE_GROUPS+=("${PROJECT}-${deployment_id}-dbw-${env}-rg") - RESOURCE_GROUPS+=("${PROJECT}-${deployment_id}-${env}-rg") - done - done -fi - -log_info "Using Resource Groups: ${RESOURCE_GROUPS[*]}" - -# Set Azure subscription -az account set --subscription "$SUBSCRIPTION_ID" - -# Function to process Synapse SQL Pools -process_synapse_sql_pool() { - local resource_group="$1" - local action="$2" - - # Retrieve Synapse Workspaces - workspaces=$(az synapse workspace list --resource-group "$resource_group" --query "[].name" -o tsv 2>/dev/null) - if [[ -z "$workspaces" ]]; then - log_warning "No Synapse Workspaces found in Resource Group: $resource_group" - return - fi - - for workspace in $workspaces; do - log_info " Checking Workspace: $workspace" - - sql_pools=$(az synapse sql pool list --workspace-name "$workspace" --resource-group "$resource_group" --query "[].{name:name,status:status}" -o tsv) - if [[ -z "$sql_pools" ]]; then - log_warning " No SQL Pools found in Workspace: $workspace" - continue - fi - - while IFS=$'\t' read -r pool_name pool_status; do - log_info " SQL Pool: $pool_name (Status: $pool_status)" - - if [[ "$DRY_RUN" == true ]]; then - log_info " Dry Run: Would have ${action}d Synapse SQL Pool: $pool_name" - else - if [[ "$action" == "Pause" && "$pool_status" == "Online" ]]; then - log_info " Pausing Synapse SQL Pool: $pool_name" - az synapse sql pool pause --name "$pool_name" --workspace-name "$workspace" --resource-group "$resource_group" - log_info " Successfully paused Synapse SQL Pool: $pool_name" - elif [[ "$action" == "Resume" && "$pool_status" == "Paused" ]]; then - log_info " Resuming Synapse SQL Pool: $pool_name" - az synapse sql pool resume --name "$pool_name" --workspace-name "$workspace" --resource-group "$resource_group" - log_info " Successfully resumed Synapse SQL Pool: $pool_name" - else - log_info " Synapse SQL Pool: $pool_name is already in the desired state." - fi - fi - done <<< "$sql_pools" - done -} - -# Function to process Azure SQL Data Warehouse (Dedicated SQL Pools) -process_sql_database() { - local resource_group="$1" - local action="$2" - - # Retrieve SQL Servers - sql_servers=$(az sql server list --resource-group "$resource_group" --query "[].name" -o tsv 2>/dev/null) - if [[ -z "$sql_servers" ]]; then - log_warning "No SQL Servers found in Resource Group: $resource_group" - return - fi - - for server in $sql_servers; do - log_info " Checking SQL Server: $server" - - sql_dws=$(az sql dw list --server "$server" --resource-group "$resource_group" --query "[].{name:name,status:status}" -o tsv) - if [[ -z "$sql_dws" ]]; then - log_warning " No Dedicated SQL Pools found on Server: $server" - continue - fi - - while IFS=$'\t' read -r dw_name dw_status; do - log_info " Dedicated SQL Pool: $dw_name (Status: $dw_status)" - - if [[ "$DRY_RUN" == true ]]; then - log_info " Dry Run: Would have ${action}d Dedicated SQL Pool: $dw_name" - else - if [[ "$action" == "Pause" && "$dw_status" == "Online" ]]; then - log_info " Pausing Dedicated SQL Pool: $dw_name" - az sql dw pause --name "$dw_name" --server "$server" --resource-group "$resource_group" - log_info " Successfully paused Dedicated SQL Pool: $dw_name" - elif [[ "$action" == "Resume" && "$dw_status" == "Paused" ]]; then - log_info " Resuming Dedicated SQL Pool: $dw_name" - az sql dw resume --name "$dw_name" --server "$server" --resource-group "$resource_group" - log_info " Successfully resumed Dedicated SQL Pool: $dw_name" - else - log_info " Dedicated SQL Pool: $dw_name is already in the desired state." - fi - fi - done <<< "$sql_dws" - done -} - -# Process each resource group -for resource_group in "${RESOURCE_GROUPS[@]}"; do - if ! az group show --name "$resource_group" &>/dev/null; then - log_error "Resource Group [$resource_group] does not exist. Skipping." - continue - fi - - log_info "Processing Resource Group: $resource_group" - echo "----------------------------------------" - - # Process Synapse SQL Pools - process_synapse_sql_pool "$resource_group" "$ACTION" - - # Process Azure SQL Data Warehouse (Dedicated SQL Pools) - process_sql_database "$resource_group" "$ACTION" -done \ No newline at end of file diff --git a/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 b/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 new file mode 100755 index 000000000..b8faef573 --- /dev/null +++ b/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 @@ -0,0 +1,283 @@ +# PowerShell script to Pause or Resume Azure Synapse SQL Pools and Azure SQL Data Warehouse (Dedicated SQL Pools). +# Supports both Azure Automation (Managed Identity) and local manual execution. + +param( + [string]$SubscriptionId, + [string]$DeploymentIds, + [string]$Project, + [string]$Environments = "dev,stg", + [string]$ResourceGroups, + [ValidateSet("Pause", "Resume")] + [string]$Action = "Pause", + [switch]$DryRun +) + +# Initialize error and warning tracking +[int]$global:iWarningCount = 0 +[int]$global:iErrorCount = 0 +$ErrorActionPreference = "Continue" + +# Function to log messages and handle error/warning counters +function Log-Message { + param ( + [string]$Message, + [string]$Level = "INFO" + ) + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + switch ($Level) { + "ERROR" { + $global:iErrorCount++ + Write-Error "$timestamp [$Level] $Message" + } + "WARNING" { + $global:iWarningCount++ + Write-Warning "$timestamp [$Level] $Message" + } + default { + Write-Output "$timestamp [$Level] $Message" + } + } +} + + +# Function to display usage +function Show-Usage { + Write-Host "Usage: .\pause_resume_synapse.ps1 -SubscriptionId [-DeploymentIds ] -Project -Environments `n[-ResourceGroups ] -Action [-DryRun]" -ForegroundColor Yellow + Write-Host " -SubscriptionId Azure Subscription ID (required for manual run)." + Write-Host " -ResourceGroups Resource groups (comma-separated, use '*' to target all resource groups)." + Write-Host " -DeploymentIds Deployment IDs for resource group generation (comma-separated, required if ResourceGroups is not specified)." + Write-Host " -Project Project name for resource group generation (required if ResourceGroups is not specified)." + Write-Host " -Environments Environments for resource group generation (comma-separated, required if ResourceGroups is not specified) (default: dev,stg)" + Write-Host " -Action Action to perform: Pause or Resume (default: Pause)." + Write-Host " -DryRun Simulate actions without making any changes (default: false)." + exit 1 +} + +# Trim unnecessary spaces from parameters +$SubscriptionId = $SubscriptionId.Trim() +$DeploymentIds = $DeploymentIds.Trim() +$Project = $Project.Trim() +$Environments = $Environments.Trim() +$ResourceGroups = $ResourceGroups.Trim() +$Action = $Action.Trim() + +# Validate Action parameter +if ($Action -notin @("Pause", "Resume")) { + Log-Message "ERROR: Invalid action '$Action'. Valid actions are 'Pause' or 'Resume'." "ERROR" + Show-Usage +} + +# Ensure Az modules are installed and imported +$modules = @("Az.Accounts", "Az.Sql", "Az.Synapse", "Az.Resources") +foreach ($module in $modules) { + if (-not (Get-Module -ListAvailable -Name $module)) { + Log-Message "Installing module $module..." "INFO" + Install-Module -Name $module -Force -Scope CurrentUser -AllowClobber + } + Import-Module $module -ErrorAction Stop +} + +# Authenticate and set subscription context +try { + if ($env:MSI_SECRET) { + Log-Message "Running in Azure Automation. Authenticating with Managed Identity." "INFO" + Connect-AzAccount -Identity -ErrorAction Stop + } else { + Log-Message "Running locally. Using manual authentication." "INFO" + $Context = Get-AzContext + if (-not $Context) { + Log-Message "No existing context. Logging in..." "INFO" + Connect-AzAccount -ErrorAction Stop + } else { + Log-Message "Existing context detected. Account: $($Context.Account.Id)" "INFO" + } + } + + if (-not $SubscriptionId) { + $Subscriptions = Get-AzSubscription -ErrorAction Stop + if (-not $Subscriptions) { + Log-Message "No subscriptions are accessible." "ERROR" + Show-Usage + } + $SubscriptionId = $Subscriptions[0].Id + Log-Message "No subscription specified. Defaulting to: $SubscriptionId" "INFO" + } + + Set-AzContext -SubscriptionId $SubscriptionId -ErrorAction Stop + Log-Message "Subscription context set to: $SubscriptionId" "INFO" +} catch { + Log-Message "Authentication or subscription setup failed: $_" "ERROR" + Show-Usage +} + +# Determine resource groups +$ResourceGroupsList = @() + +if ($ResourceGroups -eq '*') { + try { + $ResourceGroupsList = Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName + Log-Message "Targeting all resource groups in the subscription." "INFO" + } catch { + Log-Message "Failed to retrieve resource groups: $_" "ERROR" + exit 1 + } +} elseif ($ResourceGroups -and $ResourceGroups -ne "") { + $ResourceGroupsList = $ResourceGroups -split ',' +} elseif ($Project -and $DeploymentIds) { + foreach ($env in $Environments -split ',') { + foreach ($deploymentId in $DeploymentIds -split ',') { + $ResourceGroupsList += "${Project}-${deploymentId}-dbw-${env}-rg" + $ResourceGroupsList += "${Project}-${deploymentId}-${env}-rg" + } + } +} else { + Log-Message "No resource groups provided or generated." "ERROR" + Show-Usage +} + +Log-Message "Resource Groups to process: $($ResourceGroupsList -join ', ')" "INFO" + +# Function to process Synapse SQL Pools +function Process-SynapseSqlPool { + param ( + [string]$ResourceGroup, + [string]$Action + ) + + try { + $workspaces = Get-AzSynapseWorkspace -ResourceGroupName $ResourceGroup | Select-Object -ExpandProperty Name + if (-not $workspaces) { + Log-Message "WARNING: No Synapse Workspaces found in Resource Group: $ResourceGroup" "WARNING" + return + } + } catch { + Log-Message "ERROR: Failed to retrieve Synapse Workspaces for Resource Group: $ResourceGroup. $_" "ERROR" + return + } + + foreach ($workspace in $workspaces) { + Log-Message "INFO: Checking Synapse Workspace: $workspace for SQL Pools" "INFO" + + try { + $sqlPools = Get-AzSynapseSqlPool -ResourceGroupName $ResourceGroup -WorkspaceName $workspace + if (-not $sqlPools) { + Log-Message "WARNING: No SQL Pools found in Workspace: $workspace" "WARNING" + continue + } + } catch { + Log-Message "ERROR: Failed to retrieve SQL Pools for Workspace: $workspace. $_" "ERROR" + continue + } + + foreach ($sqlPool in $sqlPools) { + $poolName = $sqlPool.Name + $poolStatus = $sqlPool.Status + + if ($poolStatus -eq "Paused") { + Log-Message "INFO: SQL Pool: $poolName is already paused. Skipping." "INFO" + } elseif ($poolStatus -eq "Online") { + Log-Message "INFO: SQL Pool: $poolName is online. Initiating $Action..." "INFO" + + try { + if (-not $DryRun) { + if ($Action -eq "Pause") { + Suspend-AzSynapseSqlPool -Name $poolName -WorkspaceName $workspace -ResourceGroupName $ResourceGroup + } elseif ($Action -eq "Resume") { + Resume-AzSynapseSqlPool -Name $poolName -WorkspaceName $workspace -ResourceGroupName $ResourceGroup + } + } + Log-Message "Successfully $Action-ed SQL Pool: $poolName." "INFO" + } catch { + Log-Message "ERROR: Failed to $Action SQL Pool: $poolName. $_" "ERROR" + } + } else { + Log-Message "WARNING: SQL Pool: $poolName is in an unsupported state: $poolStatus" "WARNING" + } + } + } +} + +# Function to process Azure SQL Data Warehouses +function Process-SqlDatabase { + param ( + [string]$ResourceGroup, + [string]$Action + ) + + try { + $sqlServers = Get-AzSqlServer -ResourceGroupName $ResourceGroup | Select-Object -ExpandProperty ServerName + if (-not $sqlServers) { + Log-Message "WARNING: No SQL Servers found in Resource Group: $ResourceGroup" "WARNING" + return + } + } catch { + Log-Message "ERROR: Failed to retrieve SQL Servers for Resource Group: $ResourceGroup. $_" "ERROR" + return + } + + foreach ($server in $sqlServers) { + Log-Message "INFO: Checking SQL Server: $server in Resource Group: $ResourceGroup" "INFO" + + try { + $sqlDws = Get-AzSqlDatabase -ResourceGroupName $ResourceGroup -ServerName $server | Where-Object { $_.Edition -eq "DataWarehouse" } + if (-not $sqlDws) { + Log-Message "WARNING: No Dedicated SQL Pools found on Server: $server" "WARNING" + continue + } + } catch { + Log-Message "ERROR: Failed to retrieve Dedicated SQL Pools for Server: $server. $_" "ERROR" + continue + } + + foreach ($sqlDw in $sqlDws) { + $dwName = $sqlDw.DatabaseName + $dwStatus = $sqlDw.Status + + if ($dwStatus -eq "Paused") { + Log-Message "INFO: Dedicated SQL Pool: $dwName is already paused." "INFO" + } elseif ($dwStatus -eq "Online") { + Log-Message "INFO: Dedicated SQL Pool: $dwName is online. Initiating $Action..." "INFO" + + try { + if (-not $DryRun) { + if ($Action -eq "Pause") { + Suspend-AzSqlDatabase -ResourceGroupName $ResourceGroup -ServerName $server -DatabaseName $dwName + } elseif ($Action -eq "Resume") { + Resume-AzSqlDatabase -ResourceGroupName $ResourceGroup -ServerName $server -DatabaseName $dwName + } + } + Log-Message "Successfully $Action-ed Dedicated SQL Pool: $dwName." "INFO" + } catch { + Log-Message "ERROR: Failed to $Action Dedicated SQL Pool: $dwName. $_" "ERROR" + } + } else { + Log-Message "WARNING: Dedicated SQL Pool: $dwName is in an unsupported state: $dwStatus" "WARNING" + } + } + } +} + +# Process each resource group +foreach ($resourceGroup in $ResourceGroupsList) { + try { + # Attempt to get the resource group with localized error handling + $rgExists = Get-AzResourceGroup -Name $resourceGroup -ErrorAction Stop + Log-Message "-----------------------------------------------" "INFO" + Log-Message "INFO: Processing Resource Group: $($rgExists.ResourceGroupName) in location: $($rgExists.Location)" "INFO" + Log-Message "-----------------------------------------------" "INFO" + + # Process Synapse SQL Pools + Process-SynapseSqlPool -ResourceGroup $resourceGroup -Action $Action + + # Process Azure SQL Data Warehouse + Process-SqlDatabase -ResourceGroup $resourceGroup -Action $Action + } catch { + # Log the error but don't exit the script + Log-Message "ERROR: Resource Group [$resourceGroup] does not exist or is inaccessible. $_" "ERROR" + continue + } +} + + +# Final error and warning summary +Log-Message "Script completed with $global:iErrorCount error(s) and $global:iWarningCount warning(s)." "INFO" \ No newline at end of file From f9c9a6bc36a167286832d25b95b993768c29190e Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Fri, 24 Jan 2025 12:43:09 +0000 Subject: [PATCH 3/8] Add README file for Synapse Pause script --- .../utilities/README_pause_resume_synapse.md | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md diff --git a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md new file mode 100644 index 000000000..a0cef3ce8 --- /dev/null +++ b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md @@ -0,0 +1,284 @@ +# Pause/Resume Azure Synapse SQL Pools and Azure SQL Data Warehouse Script + +## Overview + +This PowerShell script is designed to automate the pausing or resuming of Azure Synapse SQL Pools and Azure SQL Data Warehouse (Dedicated SQL Pools). This functionality helps organizations optimize costs by pausing unused resources and resuming them when needed. + +It supports both manual execution and deployment as an Azure Automation Runbook with a Managed Identity, making it ideal for scheduled automation tasks. + +--- + +## Features + +- **Automated Pause/Resume**: + - Dynamically pause or resume SQL Pools across specific or all resource groups. +- **Flexible Execution**: + - Run locally with PowerShell or automate through Azure Automation. +- **Custom Parameters**: + - Specify environments (e.g., dev, stg, prod) and projects for targeted execution. +- **Error and Warning Tracking**: + - Logs all errors and warnings, providing a detailed summary at the end. +- **Dry Run Mode**: + - Simulate actions without making changes to validate configurations. + +--- + +## Parameters + +| Parameter | Description | Default | +|------------------|---------------------------------------------------------------------------------------------------------|-----------| +| `SubscriptionId` | Azure Subscription ID. Required for local execution. | | +| `DeploymentIds` | Comma-separated deployment IDs. Required if `ResourceGroups` is not provided. | | +| `Project` | Project name. Required if `ResourceGroups` is not provided. | | +| `Environments` | Environments (e.g., dev, stg, prod). | `dev,stg` | +| `ResourceGroups` | Comma-separated list of resource groups. Use `*` to target all resource groups in the subscription. | | +| `Action` | Specify `Pause` or `Resume`. | `Pause` | +| `DryRun` | Simulate actions without making changes. | `false` | + +--- + +## Prerequisites + +1. **Azure Subscription**: Ensure you have access to an Azure subscription. +2. **Azure PowerShell Module**: Ensure `Az.Accounts`, `Az.Sql`, `Az.Synapse`, `Az.Automation`,and `Az.Resources` modules are installed. +3. **Azure Automation Account**: Create an Azure Automation Account with a system-assigned managed identity. (Steps are provided in this instructions). +4. **Required Azure Roles**: + - Assign the `Contributor` role to the Automation Account's managed identity for the scope `/subscriptions/`. + - Optionally, assign more restrictive permissions as needed (e.g., for specific Resource Groups). +5. **PowerShell Environment**: If running locally, ensure the account has appropriate permissions. + +--- + +## Local Execution + +To execute the script manually: + +1. Download the script (`pause_resume_synapse.ps1`) to your local machine. +2. Open PowerShell and navigate to the script's location. +3. Run the script with the desired parameters. Example: + + ```powershell + .\pause_resume_synapse.ps1 -SubscriptionId "" -ResourceGroups "" -Action "Pause" + ``` +4. Review the output for warnings, errors, or success messages. + +--- + +## Azure Automation Deployment +### 1. Create a Resource Group for Automation +To keep resources organized, create a dedicated Resource Group for the Automation Account: + +*Using Bash* +```bash +az group create --name "Automation-RG" --location "East US" +``` + +*Using PowerShell* +```powershell +New-AzResourceGroup -Name "Automation-RG" -Location "East US" +``` + +### 2. Create an Azure Automation Account + +*Using Bash* +```bash +az automation account create --resource-group "Automation-RG" --name "SynapseAutomation" --location "East US" +``` + +*Using PowerShell* +```powershell +New-AzAutomationAccount -ResourceGroupName "Automation-RG" -Name "SynapseAutomation" -Location "East US" +``` + +### 3. Enable System-Assigned Managed Identity + +*Using Bash* +```bash +az resource update --resource-group "Automation-RG" --name "SynapseAutomation" --resource-type "Microsoft.Automation/automationAccounts" --set identity.type=SystemAssigned +``` + +*Using PowerShell* +```powershell +Set-AzAutomationAccount -ResourceGroupName "Automation-RG" -Name "SynapseAutomation" -AssignSystemIdentity +``` + +### 4. Retrieve the Object ID of the Managed Identity + +*Using Bash* +```bash +az resource show --resource-group "Automation-RG" --name "SynapseAutomation" --resource-type "Microsoft.Automation/automationAccounts" --query "identity.principalId" --output tsv +``` + +*Using PowerShell* +```powershell +(Get-AzAutomationAccount -ResourceGroupName "Automation-RG" -Name "SynapseAutomation").Identity.PrincipalId +``` + +### 5. Assign Managed Identity Permissions +Grant the Managed Identity appropriate permissions: + +*Using Bash* +```bash +az role assignment create --assignee-object-id "" --role "Contributor" --scope "/subscriptions/" --assignee-principal-type "ServicePrincipal" +``` + +*Using PowerShell* +```powershell +New-AzRoleAssignment -ObjectId "" -RoleDefinitionName "Contributor" -Scope "/subscriptions/" +``` + +Replace "subscription-id" with your Azure subscription ID and "ManagedIdentityObjectId" with the output of the previous command. + +### 6. Import the Script into the Automation Account +This can be done directly in Azure Portal using the following steps: +1. In the Azure Portal, go to your Automation Account. +2. Navigate to Runbooks > Add a Runbook. +3. Upload the script and set its type to PowerShell. + +For a fully automated solution, follow these commands: + +1. Create the Runbook and Upload the script + + *Using Bash* + ```bash + az automation runbook create --resource-group "Automation-RG" --automation-account-name "SynapseAutomation" --name "PauseResumeSynapse" --type "PowerShell" + + az automation runbook replace-content --resource-group "Automation-RG" --automation-account-name "SynapseAutomation" --name "PauseResumeSynapse" --content @"./pause_resume_synapse.ps1" + ``` + + *Using PowerShell* + ```powershell + Import-AzAutomationRunbook -ResourceGroupName "Automation-RG" -AutomationAccountName "SynapseAutomation" -Name "PauseResumeSynapse" -Path "./pause_resume_synapse.ps1" -Type PowerShell + ``` + +2. Publish the Runbook + + *Using Bash* + ```bash + az automation runbook publish --resource-group "Automation-RG" --automation-account-name "SynapseAutomation" --name "PauseResumeSynapse" + ``` + + *Using PowerShell* + ```powershell + Publish-AzAutomationRunbook -ResourceGroupName "Automation-RG" -AutomationAccountName "SynapseAutomation" -Name "PauseResumeSynapse" + ``` + +### 7. Test the Runbook +1. Go to the Runbooks section of your Automation Account. +2. Select your uploaded Runbook. +3. Click Start and provide the necessary parameters. + +--- + +## Scheduling Automation + +To schedule the script in Azure Automation using Azure Portal: +1. Navigate to the Runbooks section of your Automation Account. +2. Select your Runbook. +3. Click Link to schedule. +4. Create a new schedule and configure it (e.g., daily at midnight). + +To schedule the Runbook using Commands: +1. Create a schedule in the Automation Account: + +*Using Bash* +```bash +# Calculate midnight for the next day in UTC -- or set manually to a specific time such as "2025-01-24T00:00:00Z" +$startTime = (Get-Date).AddDays(1).Date.ToUniversalTime() + +az automation schedule create --resource-group "Automation-RG" --automation-account-name "SynapseAutomation" --name "DailyPause" --start-time $startTime --time-zone UTC --frequency "Day" --interval 1 +``` + +*Using PowerShell* +```powershell +# Calculate midnight for the next day in UTC -- or set manually to a specific time such as "2025-01-24T00:00:00Z" +$startTime = (Get-Date).AddDays(1).Date.ToUniversalTime() + +New-AzAutomationSchedule ` + -ResourceGroupName "Automation-RG" ` + -AutomationAccountName "SynapseAutomation" ` + -Name "DailyPause" ` + -StartTime $startTime ` + -DayInterval 1 ` + -TimeZone "UTC" +``` + +2. Link the schedule to the Runbook: + After reviewing the [Azure CLI commands for Azure Automation](https://learn.microsoft.com/en-us/cli/azure/automation?view=azure-cli-latest), there is no direct Azure CLI command to link a schedule to a runbook. The ability to link a schedule to a runbook can only be done via the Azure Portal, PowerShell, or using the Azure REST API. + +*Using PowerShell* +```powershell +Register-AzAutomationScheduledRunbook ` + -AutomationAccountName "SynapseAutomation" ` + -ResourceGroupName "Automation-RG" ` + -RunbookName "PauseResumeSynapse" ` + -ScheduleName "DailyPause" ` + + # Add any relevant parameter based on your need + -Parameters @{ + #SubscriptionId = "SubscriptionId" + #DeploymentIds = "Deployment1,Deployment2" + #project = "ProjectName" + #Environments = "dev,stg,prod" + #ResourceGroups = "*" + #Action = "Pause" + } +``` + +--- + +## Logging and Monitoring + +1. **Error Logging**: + - Navigate to your Automation Account in the Azure Portal. + - Go to Jobs to view the status of Runbook executions. + - Check the logs for warnings, errors, or success messages. +2. **Error and Warning Counters**: + - The script tracks errors and warnings globally. + - The final log will show the total number of errors and warnings encountered. +3. **Dry Run**: + - Use the -DryRun flag to simulate actions without making any changes. + +--- + +## Example Scenarios + +### 1. Pause All SQL Pools in a Subscription +```powershell +.\pause_resume_synapse.ps1 -SubscriptionId "your-subscription-id" -ResourceGroups "*" -Action "Pause" +``` + +### 2. Resume SQL Pools for a Specific Project +```powershell +.\pause_resume_synapse.ps1 -SubscriptionId "your-subscription-id" -Project "YourProject" -DeploymentIds "Deployment1,Deployment2" -Action "Resume" +``` + +### 3. Test Without Making Changes +```powershell +.\pause_resume_synapse.ps1 -SubscriptionId "your-subscription-id" -ResourceGroups "*" -Action "Pause" -DryRun +``` + +--- + +## Troubleshooting + +- **Module Errors**: Ensure Azure modules are installed and updated: `Update-Module -Name Az -Force`. +- **Permission Issues**: Verify the Managed Identity has appropriate role assignments. Ensure local accounts have sufficient permissions. +- **Azure Automation Errors**: Review the Runbook job logs for detailed error messages. + +--- + +## Notes + +- **Dry Run Mode**: Use the `-DryRun` switch to verify actions before making changes. +- **Error and Warning Summary**: At the end of the script, a summary of errors and warnings is displayed. + +--- + +## License + +This script is provided "as-is" without warranty of any kind. Use at your own risk. + +--- + +This Readme file provides a complete overview of how to use the script, deploy it to Azure Automation, set up permissions, and troubleshoot common issues. \ No newline at end of file From bc21d6ae71122c27535ff27bb7e32522692c3736 Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Fri, 24 Jan 2025 13:13:50 +0000 Subject: [PATCH 4/8] Add References section to Synapse Pause README file --- .../utilities/README_pause_resume_synapse.md | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md index a0cef3ce8..ee42943dc 100644 --- a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md +++ b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md @@ -275,10 +275,30 @@ Register-AzAutomationScheduledRunbook ` --- +## References + +- [Pause and resume compute in dedicated SQL pool (formerly SQL DW) with Azure PowerShell](https://learn.microsoft.com/azure/synapse-analytics/sql-data-warehouse/pause-and-resume-compute-powershell) +- [Pause and Resume Compute in Synapse Workspace with PowerShell](https://learn.microsoft.com/azure/synapse-analytics/sql-data-warehouse/pause-and-resume-compute-workspace-powershell) +- [Azure Automation Overview](https://learn.microsoft.com/azure/automation/automation-intro) +- [Azure Automation Runbooks](https://learn.microsoft.com/azure/automation/automation-runbook-types) +- [Manage schedules in Azure Automation](https://learn.microsoft.com/azure/automation/shared-resources/schedules) +- [Using a system-assigned managed identity for an Azure Automation account](https://learn.microsoft.com/azure/automation/enable-managed-identity-for-automation) +- [Azure PowerShell Documentation](https://learn.microsoft.com/powershell/azure/new-azureps-module-az) +- [Azure CLI Documentation](https://learn.microsoft.com/cli/azure/) +- [Azure CLI Automation Commands](https://learn.microsoft.com/cli/azure/automation?view=azure-cli-latest) +- [Resume-AzSynapseSqlPool PowerShell Command](https://github.com/Azure/azure-powershell/blob/main/src/Synapse/Synapse/help/Resume-AzSynapseSqlPool.md) +- [Suspend-AzSynapseSqlPool PowerShell Command](https://github.com/Azure/azure-powershell/blob/main/src/Synapse/Synapse/help/Suspend-AzSynapseSqlPool.md) +- [Azure PowerShell GitHub Repository](https://github.com/Azure/azure-powershell/tree/main) +- [AZ.Automation PowerShell Commands](https://learn.microsoft.com/powershell/module/az.automation) +- [Azure Automation Pricing](https://azure.microsoft.com/pricing/details/automation/) + +--- + ## License This script is provided "as-is" without warranty of any kind. Use at your own risk. --- -This Readme file provides a complete overview of how to use the script, deploy it to Azure Automation, set up permissions, and troubleshoot common issues. \ No newline at end of file +This Readme file provides a complete overview of how to use the script, deploy it to Azure Automation, set up permissions, and troubleshoot common issues. + From 612b288c34ecb4dc3a0086b62e9a8decf0b1062a Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Tue, 28 Jan 2025 10:21:21 +0000 Subject: [PATCH 5/8] Add InstallModules parameter to pause_resume_synapse script for automatic module installation --- .../utilities/README_pause_resume_synapse.md | 3 ++- .../utilities/pause_resume_synapse.ps1 | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md index ee42943dc..3ffd517a6 100644 --- a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md +++ b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md @@ -34,13 +34,14 @@ It supports both manual execution and deployment as an Azure Automation Runbook | `ResourceGroups` | Comma-separated list of resource groups. Use `*` to target all resource groups in the subscription. | | | `Action` | Specify `Pause` or `Resume`. | `Pause` | | `DryRun` | Simulate actions without making changes. | `false` | +| `InstallModules` | Install missing modules if not present. | `false` | --- ## Prerequisites 1. **Azure Subscription**: Ensure you have access to an Azure subscription. -2. **Azure PowerShell Module**: Ensure `Az.Accounts`, `Az.Sql`, `Az.Synapse`, `Az.Automation`,and `Az.Resources` modules are installed. +2. **Azure PowerShell Module**: Ensure `Az.Accounts`, `Az.Sql`, `Az.Synapse`, `Az.Automation`, and `Az.Resources` modules are installed. Alternatively, use the `-InstallModules` parameter to install missing modules automatically. 3. **Azure Automation Account**: Create an Azure Automation Account with a system-assigned managed identity. (Steps are provided in this instructions). 4. **Required Azure Roles**: - Assign the `Contributor` role to the Automation Account's managed identity for the scope `/subscriptions/`. diff --git a/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 b/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 index b8faef573..68809db86 100755 --- a/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 +++ b/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 @@ -9,7 +9,8 @@ param( [string]$ResourceGroups, [ValidateSet("Pause", "Resume")] [string]$Action = "Pause", - [switch]$DryRun + [switch]$DryRun, + [switch]$InstallModules ) # Initialize error and warning tracking @@ -42,7 +43,7 @@ function Log-Message { # Function to display usage function Show-Usage { - Write-Host "Usage: .\pause_resume_synapse.ps1 -SubscriptionId [-DeploymentIds ] -Project -Environments `n[-ResourceGroups ] -Action [-DryRun]" -ForegroundColor Yellow + Write-Host "Usage: .\pause_resume_synapse.ps1 -SubscriptionId [-DeploymentIds ] -Project -Environments `n[-ResourceGroups ] -Action [-DryRun] [-InstallModules]" -ForegroundColor Yellow Write-Host " -SubscriptionId Azure Subscription ID (required for manual run)." Write-Host " -ResourceGroups Resource groups (comma-separated, use '*' to target all resource groups)." Write-Host " -DeploymentIds Deployment IDs for resource group generation (comma-separated, required if ResourceGroups is not specified)." @@ -50,6 +51,7 @@ function Show-Usage { Write-Host " -Environments Environments for resource group generation (comma-separated, required if ResourceGroups is not specified) (default: dev,stg)" Write-Host " -Action Action to perform: Pause or Resume (default: Pause)." Write-Host " -DryRun Simulate actions without making any changes (default: false)." + Write-Host " -InstallModules Install missing modules if not present (default: false)." exit 1 } @@ -71,8 +73,13 @@ if ($Action -notin @("Pause", "Resume")) { $modules = @("Az.Accounts", "Az.Sql", "Az.Synapse", "Az.Resources") foreach ($module in $modules) { if (-not (Get-Module -ListAvailable -Name $module)) { - Log-Message "Installing module $module..." "INFO" - Install-Module -Name $module -Force -Scope CurrentUser -AllowClobber + if ($InstallModules) { + Log-Message "Installing module $module..." "INFO" + Install-Module -Name $module -Force -Scope CurrentUser -AllowClobber + } else { + Log-Message "Module $module is missing. Use -InstallModules to install missing modules." "ERROR" + exit 1 + } } Import-Module $module -ErrorAction Stop } From 5e9fa6968a7c279204fe343d9e77ae71e5fc4cc5 Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Tue, 28 Jan 2025 16:30:33 +0000 Subject: [PATCH 6/8] Enhance README and script usage documentation for pause_resume_synapse and improved logging for state transitions --- .../utilities/README_pause_resume_synapse.md | 51 +++++++++---------- .../utilities/pause_resume_synapse.ps1 | 44 ++++++++++------ 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md index 3ffd517a6..80c2b3da4 100644 --- a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md +++ b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md @@ -28,8 +28,8 @@ It supports both manual execution and deployment as an Azure Automation Runbook | Parameter | Description | Default | |------------------|---------------------------------------------------------------------------------------------------------|-----------| | `SubscriptionId` | Azure Subscription ID. Required for local execution. | | -| `DeploymentIds` | Comma-separated deployment IDs. Required if `ResourceGroups` is not provided. | | -| `Project` | Project name. Required if `ResourceGroups` is not provided. | | +| `DeploymentIds` | Comma-separated deployment IDs. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | +| `Project` | Project name. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | | `Environments` | Environments (e.g., dev, stg, prod). | `dev,stg` | | `ResourceGroups` | Comma-separated list of resource groups. Use `*` to target all resource groups in the subscription. | | | `Action` | Specify `Pause` or `Resume`. | `Pause` | @@ -38,15 +38,33 @@ It supports both manual execution and deployment as an Azure Automation Runbook --- +## Example Scenarios + +### 1. Pause All SQL Pools in a Subscription +```powershell +.\pause_resume_synapse.ps1 -SubscriptionId "SubscriptionId" -ResourceGroups "*" -Action "Pause" +``` + +### 2. Resume SQL Pools for a Specific Project in Dev, Stg and Prod Environments +```powershell +.\pause_resume_synapse.ps1 -SubscriptionId "SubscriptionId" -Project "Project1" -DeploymentIds "Deployment1,Deployment2" -Environments "dev,stg,prod" -Action "Resume" +``` + +### 3. Test Without Making Changes +```powershell +.\pause_resume_synapse.ps1 -SubscriptionId "SubscriptionId" -ResourceGroups "*" -Action "Pause" -DryRun +``` + +--- + ## Prerequisites 1. **Azure Subscription**: Ensure you have access to an Azure subscription. 2. **Azure PowerShell Module**: Ensure `Az.Accounts`, `Az.Sql`, `Az.Synapse`, `Az.Automation`, and `Az.Resources` modules are installed. Alternatively, use the `-InstallModules` parameter to install missing modules automatically. -3. **Azure Automation Account**: Create an Azure Automation Account with a system-assigned managed identity. (Steps are provided in this instructions). -4. **Required Azure Roles**: - - Assign the `Contributor` role to the Automation Account's managed identity for the scope `/subscriptions/`. +3. **Required Azure Roles**: + - Assign the `Contributor` role to the Automation Account's managed identity for the scope `/subscriptions/`. - Optionally, assign more restrictive permissions as needed (e.g., for specific Resource Groups). -5. **PowerShell Environment**: If running locally, ensure the account has appropriate permissions. +4. **PowerShell Environment**: If running locally, ensure the account has appropriate permissions. --- @@ -59,7 +77,7 @@ To execute the script manually: 3. Run the script with the desired parameters. Example: ```powershell - .\pause_resume_synapse.ps1 -SubscriptionId "" -ResourceGroups "" -Action "Pause" + .\pause_resume_synapse.ps1 -SubscriptionId "" -ResourceGroups "" -Action "Pause" ``` 4. Review the output for warnings, errors, or success messages. @@ -242,25 +260,6 @@ Register-AzAutomationScheduledRunbook ` --- -## Example Scenarios - -### 1. Pause All SQL Pools in a Subscription -```powershell -.\pause_resume_synapse.ps1 -SubscriptionId "your-subscription-id" -ResourceGroups "*" -Action "Pause" -``` - -### 2. Resume SQL Pools for a Specific Project -```powershell -.\pause_resume_synapse.ps1 -SubscriptionId "your-subscription-id" -Project "YourProject" -DeploymentIds "Deployment1,Deployment2" -Action "Resume" -``` - -### 3. Test Without Making Changes -```powershell -.\pause_resume_synapse.ps1 -SubscriptionId "your-subscription-id" -ResourceGroups "*" -Action "Pause" -DryRun -``` - ---- - ## Troubleshooting - **Module Errors**: Ensure Azure modules are installed and updated: `Update-Module -Name Az -Force`. diff --git a/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 b/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 index 68809db86..7061537fa 100755 --- a/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 +++ b/e2e_samples/parking_sensors/utilities/pause_resume_synapse.ps1 @@ -46,8 +46,8 @@ function Show-Usage { Write-Host "Usage: .\pause_resume_synapse.ps1 -SubscriptionId [-DeploymentIds ] -Project -Environments `n[-ResourceGroups ] -Action [-DryRun] [-InstallModules]" -ForegroundColor Yellow Write-Host " -SubscriptionId Azure Subscription ID (required for manual run)." Write-Host " -ResourceGroups Resource groups (comma-separated, use '*' to target all resource groups)." - Write-Host " -DeploymentIds Deployment IDs for resource group generation (comma-separated, required if ResourceGroups is not specified)." - Write-Host " -Project Project name for resource group generation (required if ResourceGroups is not specified)." + Write-Host " -DeploymentIds Deployment IDs for resource group generation. Specific to Databricks E2E use case. (comma-separated, required if ResourceGroups is not specified)." + Write-Host " -Project Project name for resource group generation. Specific to Databricks E2E use case. (required if ResourceGroups is not specified)." Write-Host " -Environments Environments for resource group generation (comma-separated, required if ResourceGroups is not specified) (default: dev,stg)" Write-Host " -Action Action to perform: Pause or Resume (default: Pause)." Write-Host " -DryRun Simulate actions without making any changes (default: false)." @@ -180,10 +180,11 @@ function Process-SynapseSqlPool { $poolName = $sqlPool.Name $poolStatus = $sqlPool.Status - if ($poolStatus -eq "Paused") { - Log-Message "INFO: SQL Pool: $poolName is already paused. Skipping." "INFO" - } elseif ($poolStatus -eq "Online") { - Log-Message "INFO: SQL Pool: $poolName is online. Initiating $Action..." "INFO" + Log-Message "INFO: Current state of SQL Pool: $poolName is $poolStatus" "INFO" + if (($Action -eq "Pause" -and $poolStatus -eq "Paused") -or ($Action -eq "Resume" -and $poolStatus -eq "Online")) { + Log-Message "INFO: SQL Pool: $poolName is already in the desired state: $poolStatus. Skipping." "INFO" + } else { + Log-Message "INFO: SQL Pool: $poolName is in state: $poolStatus. Initiating $Action..." "INFO" try { if (-not $DryRun) { @@ -192,13 +193,18 @@ function Process-SynapseSqlPool { } elseif ($Action -eq "Resume") { Resume-AzSynapseSqlPool -Name $poolName -WorkspaceName $workspace -ResourceGroupName $ResourceGroup } + # Verify the new state + $newStatus = (Get-AzSynapseSqlPool -ResourceGroupName $ResourceGroup -WorkspaceName $workspace -Name $poolName).Status + Log-Message "INFO: New state of SQL Pool: $poolName is $newStatus" "INFO" + if (($Action -eq "Pause" -and $newStatus -eq "Paused") -or ($Action -eq "Resume" -and $newStatus -eq "Online")) { + Log-Message "Successfully $Action-ed SQL Pool: $poolName." "INFO" + } else { + Log-Message "ERROR: SQL Pool: $poolName did not transition to the expected state. Current state: $newStatus" "ERROR" + } } - Log-Message "Successfully $Action-ed SQL Pool: $poolName." "INFO" } catch { Log-Message "ERROR: Failed to $Action SQL Pool: $poolName. $_" "ERROR" } - } else { - Log-Message "WARNING: SQL Pool: $poolName is in an unsupported state: $poolStatus" "WARNING" } } } @@ -240,10 +246,11 @@ function Process-SqlDatabase { $dwName = $sqlDw.DatabaseName $dwStatus = $sqlDw.Status - if ($dwStatus -eq "Paused") { - Log-Message "INFO: Dedicated SQL Pool: $dwName is already paused." "INFO" - } elseif ($dwStatus -eq "Online") { - Log-Message "INFO: Dedicated SQL Pool: $dwName is online. Initiating $Action..." "INFO" + Log-Message "INFO: Current state of Dedicated SQL Pool: $dwName is $dwStatus" "INFO" + if (($Action -eq "Pause" -and $dwStatus -eq "Paused") -or ($Action -eq "Resume" -and $dwStatus -eq "Online")) { + Log-Message "INFO: Dedicated SQL Pool: $dwName is already in the desired state: $dwStatus. Skipping." "INFO" + } else { + Log-Message "INFO: Dedicated SQL Pool: $dwName is in state: $dwStatus. Initiating $Action..." "INFO" try { if (-not $DryRun) { @@ -252,13 +259,18 @@ function Process-SqlDatabase { } elseif ($Action -eq "Resume") { Resume-AzSqlDatabase -ResourceGroupName $ResourceGroup -ServerName $server -DatabaseName $dwName } + # Verify the new state + $newStatus = (Get-AzSqlDatabase -ResourceGroupName $ResourceGroup -ServerName $server -DatabaseName $dwName).Status + Log-Message "INFO: New state of Dedicated SQL Pool: $dwName is $newStatus" "INFO" + if (($Action -eq "Pause" -and $newStatus -eq "Paused") -or ($Action -eq "Resume" -and $newStatus -eq "Online")) { + Log-Message "Successfully $Action-ed Dedicated SQL Pool: $dwName." "INFO" + } else { + Log-Message "ERROR: Dedicated SQL Pool: $dwName did not transition to the expected state. Current state: $newStatus" "ERROR" + } } - Log-Message "Successfully $Action-ed Dedicated SQL Pool: $dwName." "INFO" } catch { Log-Message "ERROR: Failed to $Action Dedicated SQL Pool: $dwName. $_" "ERROR" } - } else { - Log-Message "WARNING: Dedicated SQL Pool: $dwName is in an unsupported state: $dwStatus" "WARNING" } } } From b8e763634ecf4eac4e404a75ea2db2779e1c7cef Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Thu, 30 Jan 2025 14:00:21 +0000 Subject: [PATCH 7/8] Update README_pause_resume_synapse to include example values for parameters --- .../utilities/README_pause_resume_synapse.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md index 80c2b3da4..2aa3773cd 100644 --- a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md +++ b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md @@ -25,16 +25,16 @@ It supports both manual execution and deployment as an Azure Automation Runbook ## Parameters -| Parameter | Description | Default | -|------------------|---------------------------------------------------------------------------------------------------------|-----------| -| `SubscriptionId` | Azure Subscription ID. Required for local execution. | | -| `DeploymentIds` | Comma-separated deployment IDs. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | -| `Project` | Project name. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | -| `Environments` | Environments (e.g., dev, stg, prod). | `dev,stg` | -| `ResourceGroups` | Comma-separated list of resource groups. Use `*` to target all resource groups in the subscription. | | -| `Action` | Specify `Pause` or `Resume`. | `Pause` | -| `DryRun` | Simulate actions without making changes. | `false` | -| `InstallModules` | Install missing modules if not present. | `false` | +| Parameter | Description | Default | Example | +|------------------|---------------------------------------------------------------------------------------------------------|-----------|----------------------------------------------| +| `SubscriptionId` | Azure Subscription ID. Required for local execution. | | `12345678-1234-1234-1234-123456789abc` | +| `DeploymentIds` | Comma-separated deployment IDs. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | `tst01, tst02` | +| `Project` | Project name. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | `mdwdops` | +| `Environments` | Environments (e.g., dev, stg, prod). | `dev,stg` | `dev,stg,prod` | +| `ResourceGroups` | Comma-separated list of resource groups. Use `*` to target all resource groups in the subscription. | | `RG1,RG2` | +| `Action` | Specify `Pause` or `Resume`. | `Pause` | `Pause` | +| `DryRun` | Simulate actions without making changes. | `false` | `false` | +| `InstallModules` | Install missing modules if not present. | `false` | `true` | --- From b5f101ef396f22b33ace09905c7edeff6f10d525 Mon Sep 17 00:00:00 2001 From: Raafat Zarka Date: Thu, 30 Jan 2025 14:06:40 +0000 Subject: [PATCH 8/8] Update README_pause_resume_synapse to provide specific examples for ResourceGroups parameter --- .../parking_sensors/utilities/README_pause_resume_synapse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md index 2aa3773cd..be46d36c8 100644 --- a/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md +++ b/e2e_samples/parking_sensors/utilities/README_pause_resume_synapse.md @@ -31,7 +31,7 @@ It supports both manual execution and deployment as an Azure Automation Runbook | `DeploymentIds` | Comma-separated deployment IDs. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | `tst01, tst02` | | `Project` | Project name. Required if `ResourceGroups` is not provided. Specific to Databricks E2E use case. | | `mdwdops` | | `Environments` | Environments (e.g., dev, stg, prod). | `dev,stg` | `dev,stg,prod` | -| `ResourceGroups` | Comma-separated list of resource groups. Use `*` to target all resource groups in the subscription. | | `RG1,RG2` | +| `ResourceGroups` | Comma-separated list of resource groups. Use `*` to target all resource groups in the subscription. | | `mdwdops-tst01-dev-rg,mdwdops-tst01-stg-rg` | | `Action` | Specify `Pause` or `Resume`. | `Pause` | `Pause` | | `DryRun` | Simulate actions without making changes. | `false` | `false` | | `InstallModules` | Install missing modules if not present. | `false` | `true` |