🛢️ Run Database Migrations

Execute SQL migrations against your Azure SQL database with proper authentication and error handling.

Bash Script

#!/bin/bash
set -e
echo "Running database migration for: $AZURE_ENV_NAME"
# Get database connection details
DB_SERVER="sql-$AZURE_ENV_NAME.database.windows.net"
DB_NAME="db-$AZURE_ENV_NAME"
RESOURCE_GROUP="rg-$AZURE_ENV_NAME"
# Get current user for Azure AD authentication
CURRENT_USER=$(az account show --query user.name -o tsv)
echo "Connecting as: $CURRENT_USER"
# Run migrations in order
for migration in migrations/*.sql; do
echo "Applying migration: $migration"
sqlcmd -S "$DB_SERVER" \
-d "$DB_NAME" \
-G \
-i "$migration"
if [ $? -eq 0 ]; then
echo "✅ $migration applied successfully"
else
echo "❌ Failed to apply $migration"
exit 1
fi
done
echo "All migrations completed successfully!"

Usage

Terminal window
azd exec ./run-migrations.sh

🔐 Access Environment Variables

Read Azure configuration and custom environment variables in your scripts.

PowerShell Script

Terminal window
# List all Azure-related environment variables
Write-Host "Azure Environment Configuration:"
Write-Host "================================"
Get-ChildItem env: | Where-Object { $_.Name -like "AZURE_*" } | Format-Table Name, Value
# Use specific variables
$resourceGroup = "rg-$($env:AZURE_ENV_NAME)"
$location = $env:AZURE_LOCATION
Write-Host ""
Write-Host "Creating resource group: $resourceGroup"
az group create --name $resourceGroup --location $location
# Access custom environment variables from .env
$apiKey = $env:MY_API_KEY
if ($apiKey) {
Write-Host "API Key configured: $($apiKey.Substring(0, 4))****"
}

Usage

Terminal window
azd exec ./env-config.ps1

🔨 Multi-Step Build Pipeline

Orchestrate multiple build steps with proper error handling and logging.

Bash Script

#!/bin/bash
set -euo pipefail
log() {
echo "[\$(date +'%Y-%m-%d %H:%M:%S')] \$*"
}
log "Starting build pipeline for \$AZURE_ENV_NAME"
# Step 1: Clean
log "Cleaning previous builds..."
rm -rf dist/ build/ || true
# Step 2: Install dependencies
log "Installing dependencies..."
npm ci
# Step 3: Run linter
log "Running linter..."
npm run lint
# Step 4: Run tests
log "Running tests..."
npm run test -- --ci --coverage
# Step 5: Build for production
log "Building for production..."
export NODE_ENV=production
export API_ENDPOINT="https://\$AZURE_ENV_NAME-api.azurewebsites.net"
npm run build
# Step 6: Upload coverage to Azure Storage
log "Uploading test coverage..."
az storage blob upload-batch \\
--destination "coverage-\$AZURE_ENV_NAME" \\
--source ./coverage \\
--account-name "\${AZURE_STORAGE_ACCOUNT:-azdexecstorage}"
log "Build pipeline completed successfully!"

Usage

Terminal window
azd exec ./build-pipeline.sh

🌍 Cross-Platform Script

Write scripts that work on both Windows and Unix systems.

Python Script

#!/usr/bin/env python3
import os
import platform
import subprocess
def main():
# Access Azure environment variables
env_name = os.getenv('AZURE_ENV_NAME', 'dev')
location = os.getenv('AZURE_LOCATION', 'eastus')
subscription_id = os.getenv('AZURE_SUBSCRIPTION_ID')
print(f"Environment: {env_name}")
print(f"Location: {location}")
print(f"Platform: {platform.system()}")
# Cross-platform Azure CLI usage
resource_group = f"rg-{env_name}"
# Create resource group
cmd = [
"az", "group", "create",
"--name", resource_group,
"--location", location,
"--subscription", subscription_id
]
print(f"\nCreating resource group: {resource_group}")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print("✅ Resource group created successfully")
else:
print(f"❌ Error: {result.stderr}")
exit(1)
if __name__ == "__main__":
main()

Usage

Terminal window
azd exec ./setup.py

🔐 Using Azure Key Vault Secrets

Securely store and access secrets from Azure Key Vault in your scripts without hardcoding credentials.

Bash Example

#!/bin/bash
set -e
echo "Setting up application with Key Vault secrets..."
# Step 1: Store secrets in Key Vault
echo "Storing secrets in Key Vault..."
az keyvault secret set \
--vault-name "kv-$AZURE_ENV_NAME" \
--name "database-password" \
--value "SuperSecret123!"
az keyvault secret set \
--vault-name "kv-$AZURE_ENV_NAME" \
--name "api-key" \
--value "sk-1234567890abcdef"
# Step 2: Set environment variables with Key Vault references
echo "Configuring environment variables..."
azd env set-secret DATABASE_PASSWORD
azd env set-secret API_KEY
echo "Setup complete! Secrets are now securely referenced."

PowerShell Example

Terminal window
# Use Key Vault secrets in a PowerShell script
Write-Host "Deploying with secure credentials..."
# DATABASE_PASSWORD and API_KEY are automatically resolved from Key Vault
$connectionString = "Server=$($env:DATABASE_SERVER);Database=mydb;User=admin;Password=$($env:DATABASE_PASSWORD)"
# Call API with resolved API key
$headers = @{
"Authorization" = "Bearer $($env:API_KEY)"
}
Invoke-RestMethod -Uri "https://api.example.com/deploy" \
-Method Post \
-Headers $headers \
-Body @{ connectionString = $connectionString } \
-ContentType "application/json"
Write-Host "Deployment completed successfully!"

Setting Secrets with azd env set-secret

Terminal window
# Interactive prompt to select/create Key Vault secret
azd env set-secret DB_PASSWORD
# The command will:
# 1. Prompt you to select an existing Key Vault or create a new one
# 2. Prompt you to select an existing secret or create a new one
# 3. Automatically set the environment variable with the Key Vault reference
# Verify the secret reference is set
azd env get-values | grep DB_PASSWORD

Error Handling with --stop-on-keyvault-error

deploy-critical.sh
#!/bin/bash
# For production deployments, fail immediately if secrets can't be resolved
echo "Starting critical production deployment..."
echo "Environment: $AZURE_ENV_NAME"
# This script requires all secrets to be accessible
# Use --stop-on-keyvault-error to fail fast
# Run the deployment
azd exec --stop-on-keyvault-error ./deploy-critical.sh
# If we get here, all Key Vault secrets were successfully resolved
echo "Deployment completed with all secrets verified!"

Security Benefits

  • No secrets in code: Store references, not actual secrets
  • Centralized management: Update secrets in Key Vault, not in code
  • Access control: Use Azure RBAC to control who can access secrets
  • Audit trail: Key Vault logs all secret access
  • Automatic rotation: Update secrets without changing code

💬 Interactive Setup Wizard

Create interactive scripts that prompt for user input.

Bash Script

#!/bin/bash
echo "Azure Resource Setup Wizard"
echo "============================"
echo ""
echo "Environment: $AZURE_ENV_NAME"
echo "Location: $AZURE_LOCATION"
echo ""
# Prompt for resource type
echo "What type of resource would you like to create?"
echo "1) Azure Function App"
echo "2) Azure Static Web App"
echo "3) Azure Container App"
read -p "Select option (1-3): " choice
case $choice in
1)
read -p "Enter function app name: " app_name
az functionapp create \
--name "$app_name" \
--resource-group "rg-$AZURE_ENV_NAME" \
--consumption-plan-location "$AZURE_LOCATION" \
--runtime node
;;
2)
read -p "Enter static web app name: " app_name
az staticwebapp create \
--name "$app_name" \
--resource-group "rg-$AZURE_ENV_NAME" \
--location "$AZURE_LOCATION"
;;
3)
read -p "Enter container app name: " app_name
read -p "Enter container image: " image
az containerapp create \
--name "$app_name" \
--resource-group "rg-$AZURE_ENV_NAME" \
--environment "env-$AZURE_ENV_NAME" \
--image "$image"
;;
*)
echo "Invalid option"
exit 1
;;
esac
echo ""
echo "Resource created successfully!"

Usage

Terminal window
azd exec --interactive ./setup-wizard.sh

⚠️ Error Handling & Rollback

Implement robust error handling with automatic rollback on failure.

Bash Script

#!/bin/bash
# Cleanup function for rollback
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "❌ Error detected (exit code: $exit_code). Rolling back..."
# Rollback: Delete created resources
if [ -n "$CREATED_APP_SERVICE" ]; then
echo "Deleting app service: $CREATED_APP_SERVICE"
az webapp delete --name "$CREATED_APP_SERVICE" \
--resource-group "rg-$AZURE_ENV_NAME" || true
fi
if [ -n "$CREATED_DB" ]; then
echo "Deleting database: $CREATED_DB"
az sql db delete --name "$CREATED_DB" \
--server "sql-$AZURE_ENV_NAME" \
--resource-group "rg-$AZURE_ENV_NAME" \
--yes || true
fi
echo "Rollback complete"
fi
}
# Register cleanup function
trap cleanup EXIT
# Enable strict error handling
set -euo pipefail
echo "Deploying application to $AZURE_ENV_NAME"
# Step 1: Create database
echo "Creating database..."
CREATED_DB="db-$AZURE_ENV_NAME-$(date +%s)"
az sql db create \
--name "$CREATED_DB" \
--server "sql-$AZURE_ENV_NAME" \
--resource-group "rg-$AZURE_ENV_NAME" \
--service-objective S0
# Step 2: Create app service
echo "Creating app service..."
CREATED_APP_SERVICE="app-$AZURE_ENV_NAME"
az webapp create \
--name "$CREATED_APP_SERVICE" \
--resource-group "rg-$AZURE_ENV_NAME" \
--plan "plan-$AZURE_ENV_NAME" \
--runtime "NODE:18-lts"
# Step 3: Configure connection string
echo "Configuring app settings..."
az webapp config connection-string set \
--name "$CREATED_APP_SERVICE" \
--resource-group "rg-$AZURE_ENV_NAME" \
--settings "DefaultConnection=Server=sql-$AZURE_ENV_NAME.database.windows.net;Database=$CREATED_DB;" \
--connection-string-type SQLAzure
# Step 4: Deploy code
echo "Deploying application code..."
az webapp deployment source config-zip \
--name "$CREATED_APP_SERVICE" \
--resource-group "rg-$AZURE_ENV_NAME" \
--src ./app.zip
echo "✅ Deployment completed successfully!"

Usage

Terminal window
azd exec ./deploy-with-rollback.sh

More Resources