Views:

Can I use a local Mac terminal instead of Azure Cloud Shell for deployment?

Configure your Mac terminal as an alternative to Azure Cloud Shell when deploying to an Azure management group across multiple regions.

Problem

When deploying across multiple regions via Azure Cloud Shell, you may encounter errors caused by Cloud Shell limitations. Retrying can sometimes resolve the issue. A more reliable workaround is to deploy from your local Mac terminal.
Complete the following steps to configure your Mac terminal for deployment.

Solution

  1. Upgrade bash.
    macOS ships with an outdated version of bash. Install the latest version:
    brew install bash
    Add the new bash to the list of allowed shells (assuming Homebrew installed bash at /opt/homebrew/bin/bash):
    sudo bash -c 'echo /opt/homebrew/bin/bash >> /etc/shells'
  2. Set the new bash as your default shell:
    chsh -s /opt/homebrew/bin/bash
  3. Open a new terminal and verify the bash version:
    which bash
    bash --version
    The output should be similar to the following:
    /opt/homebrew/bin/bash
    
    GNU bash, version 5.2.37(1)-release (aarch64-apple-darwin24.0.0)
  4. Install the timeout command. The timeout command is not available on macOS by default.
    Install the coreutils package:
    brew install coreutils
    Validate that the gtimeout command is available:
    gtimeout --version
    Add an alias so that timeout maps to gtimeout. Open your ~/.zprofile (or ~/.bash_profile if using bash as the default shell) and add the following line:
    alias timeout=gtimeout
    Refresh your active terminal session:
    source ~/.zprofile
  5. Install Azure CLI and sign in:
    brew update && brew install azure-cli
    az login
Your Mac terminal is ready for deployment. Run terraform apply from your installation directory.

Can I use a local Linux terminal instead of Azure Cloud Shell for deployment?

Configure your Linux terminal as an alternative to Azure Cloud Shell when deploying to an Azure management group across multiple regions.

Problem

When deploying across multiple regions using Azure Cloud Shell, you may encounter errors caused by Cloud Shell limitations. A more reliable workaround is to deploy from your local Linux terminal (Ubuntu/Debian).
Complete the following steps to configure your Linux terminal for deployment.

Solution

  1. Install the Azure CLI:
    sudo apt update
    curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
  2. Install Terraform:
    sudo apt-get install -y gnupg software-properties-common
    wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
    echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    sudo apt-get update && sudo apt-get install -y terraform
  3. Install the required tools:
    sudo apt-get install -y unzip jq
  4. Authenticate to Azure:
    az login --use-device-code
    Follow the on-screen instructions to complete authentication using a browser. Select the target subscription when prompted.
Your Linux terminal is ready for deployment. Run terraform apply from your installation directory.

How do I manually sync function apps if the sync step fails during deployment?

Use the manual sync script to retry function app trigger synchronization for subscriptions that failed during Azure management group deployment.

Problem

When the Terraform deployment completes, the last step syncs function app triggers for each subscription in the management group. If this step fails, you may see output similar to the following:
module.sync-function-trigger[0].null_resource.sync_triggers (local-exec): Failed to call function app xxxx after 3 attempts

module.sync-function-trigger[0].null_resource.sync_triggers (local-exec): WARNING: Calling updater functions failed for one or more functions, but continuing due to management group deployment mode

module.sync-function-trigger[0].null_resource.sync_triggers (local-exec): Check failure log: terraform-sync-logs/xxxxxxxxxxxxxxxxx_sync_failures.log

Apply complete! Resources: 120 added, 5 changed, 2 destroyed.
When the sync fails, function apps may not trigger as expected. Failed subscriptions are recorded as log files in the terraform-sync-logs folder in the installation directory, with filenames in the format <subscription_id>_sync_failures.log.

Prerequisites

  • Azure CLI installed and signed in (az login)
  • Appropriate permissions to manage function apps in the target subscriptions
  • The terraform-sync-logs folder exists in your installation directory (created automatically during deployment)

Solution

Copy the manual-sync-failed-subscriptions.sh script to your installation directory (the same directory that contains the terraform-sync-logs folder), then complete the following steps.
  1. Make the script executable:
    chmod +x manual-sync-failed-subscriptions.sh
  2. Run the script. The script automatically scans the terraform-sync-logs folder and syncs all failed subscriptions:
    ./manual-sync-failed-subscriptions.sh
    The script completes the following actions:
    • Scans terraform-sync-logs for failure logs
    • Lists all failed subscriptions and prompts for confirmation
    • Syncs function triggers (updaters, pattern updaters, vnet watchers) for each subscription
    • Waits for triggers to stabilize
    • Invokes the functions (pattern updater, vnet watcher, updater)
    • Records results in terraform-sync-logs/manual-sync.log
    Note
    Note
    To sync specific subscriptions instead of all failed ones, use the -s or --subscription flag with a comma-separated list of subscription IDs:
    ./manual-sync-failed-subscriptions.sh -s sub-id-1,sub-id-2
    To clear all checkpoints and restart from scratch, use the --reset flag:
    ./manual-sync-failed-subscriptions.sh --reset
  3. Verify the results after the script completes:
    • Check the summary output — the script prints a summary showing successful, skipped, and failed sync counts.
    • Review terraform-sync-logs/manual-sync.log for detailed results.
    • Check the terraform-sync-logs/sync-success/ folder — each <subscription_id>.done file confirms a successful sync.
    • If any subscriptions still failed, re-run the script to retry the remaining failures.

Script options reference

Option
Description
(no arguments)
Syncs all failed subscriptions from terraform-sync-logs
-s, --subscription <id1,id2,...>
Syncs specific subscription(s)
-r, --reset
Clears all checkpoints and re-syncs from scratch
-h, --help
Shows help message