Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Prepare Azure environments for new workloads—subscriptions, networking, identity, and landing zones
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/sql-database/scripts/grant-sql-access.sh
1#!/bin/bash2# Grant Azure SQL data-plane access to the App Service / Container App managed identity.3#4# USAGE: Copy this file to scripts/grant-sql-access.sh in your project root and add5# a postprovision hook in azure.yaml:6#7# hooks:8# postprovision:9# posix:10# shell: sh11# run: ./scripts/grant-sql-access.sh12# windows:13# shell: pwsh14# run: ./scripts/grant-sql-access.ps115#16# ENVIRONMENT VARIABLES (sourced from azd env):17# SQL_SERVER - SQL server name (without .database.windows.net)18# SQL_DATABASE - Database name19# AZURE_RESOURCE_GROUP - Resource group name20# SERVICE_WEB_NAME - App Service name (used when set, takes priority)21# SERVICE_API_NAME - API service name (fallback when SERVICE_WEB_NAME is not set)22# SQL_GRANT_DDLADMIN - Set to "true" to also grant db_ddladmin (needed for EF migrations)2324set -e2526# Safely load azd environment variables without eval27while IFS= read -r line; do28[ -n "$line" ] || continue29key=${line%%=*}30value=${line#*=}31case "$value" in32\"*\") value=${value#\"}; value=${value%\"} ;;33\'*\') value=${value#\'}; value=${value%\'} ;;34esac35export "$key=$value"36done < <(azd env get-values)3738# Determine app identity name (App Service uses SERVICE_WEB_NAME, APIs use SERVICE_API_NAME)39APP_NAME=${SERVICE_WEB_NAME:-$SERVICE_API_NAME}4041if [ -z "$APP_NAME" ]; then42echo "ERROR: Neither SERVICE_WEB_NAME nor SERVICE_API_NAME is set in azd environment." >&243exit 144fi4546echo "Granting SQL data-plane access to managed identity: $APP_NAME"4748# Build idempotent SQL grant queries (reader + writer, required for all apps)49SQL_QUERIES="50IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = '$APP_NAME')51CREATE USER [$APP_NAME] FROM EXTERNAL PROVIDER;5253IF NOT EXISTS (54SELECT 1 FROM sys.database_role_members drm55JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id56JOIN sys.database_principals m ON drm.member_principal_id = m.principal_id57WHERE r.name = 'db_datareader' AND m.name = '$APP_NAME'58)59ALTER ROLE db_datareader ADD MEMBER [$APP_NAME];6061IF NOT EXISTS (62SELECT 1 FROM sys.database_role_members drm63JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id64JOIN sys.database_principals m ON drm.member_principal_id = m.principal_id65WHERE r.name = 'db_datawriter' AND m.name = '$APP_NAME'66)67ALTER ROLE db_datawriter ADD MEMBER [$APP_NAME];68"6970# Optionally grant db_ddladmin (needed when EF Core migrations run at startup or via hook)71SQL_GRANT_DDLADMIN="${SQL_GRANT_DDLADMIN:-false}"72if [ "$SQL_GRANT_DDLADMIN" = "true" ]; then73SQL_QUERIES="$SQL_QUERIES74IF NOT EXISTS (75SELECT 1 FROM sys.database_role_members drm76JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id77JOIN sys.database_principals m ON drm.member_principal_id = m.principal_id78WHERE r.name = 'db_ddladmin' AND m.name = '$APP_NAME'79)80ALTER ROLE db_ddladmin ADD MEMBER [$APP_NAME];81"82fi8384# Ensure the rdbms-connect extension is installed (provides 'az sql db query')85if ! az extension show --name rdbms-connect >/dev/null 2>&1; then86echo "Azure CLI extension 'rdbms-connect' is not installed. Installing..."87if ! az extension add --name rdbms-connect --yes; then88echo "ERROR: Failed to install Azure CLI extension 'rdbms-connect'. Ensure Azure CLI has network access and retry." >&289exit 190fi91fi9293az sql db query \94--server "$SQL_SERVER" \95--database "$SQL_DATABASE" \96--resource-group "$AZURE_RESOURCE_GROUP" \97--auth-mode ActiveDirectoryDefault \98--queries "$SQL_QUERIES"99100echo "SQL access granted successfully."101