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.ps1
1# Grant Azure SQL data-plane access to the App Service / Container App managed identity.2#3# USAGE: Copy this file to scripts/grant-sql-access.ps1 in your project root and add4# a postprovision hook in azure.yaml:5#6# hooks:7# postprovision:8# posix:9# shell: sh10# run: ./scripts/grant-sql-access.sh11# windows:12# shell: pwsh13# run: ./scripts/grant-sql-access.ps114#15# ENVIRONMENT VARIABLES (sourced from azd env):16# SQL_SERVER - SQL server name (without .database.windows.net)17# SQL_DATABASE - Database name18# AZURE_RESOURCE_GROUP - Resource group name19# SERVICE_WEB_NAME - App Service name (used when set, takes priority)20# SERVICE_API_NAME - API service name (fallback when SERVICE_WEB_NAME is not set)21# SQL_GRANT_DDLADMIN - Set to "true" to also grant db_ddladmin (needed for EF migrations)2223$ErrorActionPreference = 'Stop'2425# Load azd environment variables26azd env get-values | ForEach-Object {27$name, $value = $_.Split('=', 2)28Set-Item "env:$name" $value.Trim('"')29}3031# Determine app identity name (App Service uses SERVICE_WEB_NAME, APIs use SERVICE_API_NAME)32$AppName = if ($env:SERVICE_WEB_NAME) { $env:SERVICE_WEB_NAME } else { $env:SERVICE_API_NAME }3334if (-not $AppName) {35throw "ERROR: Neither SERVICE_WEB_NAME nor SERVICE_API_NAME is set in azd environment."36}3738Write-Host "Granting SQL data-plane access to managed identity: $AppName"3940# Build idempotent SQL grant queries (reader + writer, required for all apps)41$SqlQuery = @"42IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = '$AppName')43CREATE USER [$AppName] FROM EXTERNAL PROVIDER;4445IF NOT EXISTS (46SELECT 1 FROM sys.database_role_members drm47JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id48JOIN sys.database_principals m ON drm.member_principal_id = m.principal_id49WHERE r.name = 'db_datareader' AND m.name = '$AppName'50)51ALTER ROLE db_datareader ADD MEMBER [$AppName];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_datawriter' AND m.name = '$AppName'58)59ALTER ROLE db_datawriter ADD MEMBER [$AppName];60"@6162# Optionally grant db_ddladmin (needed when EF Core migrations run at startup or via hook)63$GrantDdlAdmin = $env:SQL_GRANT_DDLADMIN -eq 'true'64if ($GrantDdlAdmin) {65$SqlQuery += @"6667IF NOT EXISTS (68SELECT 1 FROM sys.database_role_members drm69JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id70JOIN sys.database_principals m ON drm.member_principal_id = m.principal_id71WHERE r.name = 'db_ddladmin' AND m.name = '$AppName'72)73ALTER ROLE db_ddladmin ADD MEMBER [$AppName];74"@75}7677# Ensure the rdbms-connect extension is installed (provides 'az sql db query')78az extension show --name rdbms-connect *> $null79if ($LASTEXITCODE -ne 0) {80Write-Host "Azure CLI extension 'rdbms-connect' is not installed. Installing..."81az extension add --name rdbms-connect --yes82if ($LASTEXITCODE -ne 0) {83throw "ERROR: Failed to install Azure CLI extension 'rdbms-connect'. Cannot continue because 'az sql db query' requires it."84}85}8687az sql db query `88--server $env:SQL_SERVER `89--database $env:SQL_DATABASE `90--resource-group $env:AZURE_RESOURCE_GROUP `91--auth-mode ActiveDirectoryDefault `92--queries $SqlQuery9394Write-Host "SQL access granted successfully."95