Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ hooks:
run: |
Write-Host "Web app URL: "
Write-Host "$env:WEB_APP_URL" -ForegroundColor Cyan
Write-Host "✅ If you want to use the Sample Data, run the following command in the Bash terminal to process it:"
./infra/scripts/process_sample_data.sh <storage_account_name> <storage_container_name> <managed_client_id> <key_vault_name> <sql_server_name> <sql_database_name> <resource_group_name>
shell: pwsh
continueOnError: false
interactive: true
posix:
run: |
echo "Web app URL: "
echo $WEB_APP_URL
echo "✅ If you want to use the Sample Data, run the following command in the Bash terminal to process it:"
./infra/scripts/process_sample_data.sh <storage_account_name> <storage_container_name> <managed_client_id> <key_vault_name> <sql_server_name> <sql_database_name> <resource_group_name>
shell: sh
continueOnError: false
interactive: true
Expand Down
93 changes: 0 additions & 93 deletions infra/deploy_post_deployment_scripts.bicep

This file was deleted.

51 changes: 28 additions & 23 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -157,29 +157,34 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
}

//========== Deployment script to upload sample data ========== //
module uploadFiles 'deploy_post_deployment_scripts.bicep' = {
name : 'deploy_post_deployment_scripts'
params:{
solutionName: solutionPrefix
solutionLocation: secondaryLocation
baseUrl: baseUrl
storageAccountName: storageAccount.outputs.storageName
containerName: storageAccount.outputs.storageContainer
managedIdentityObjectId:managedIdentityModule.outputs.managedIdentityOutput.id
managedIdentityClientId:managedIdentityModule.outputs.managedIdentityOutput.clientId
keyVaultName:aifoundry.outputs.keyvaultName
logAnalyticsWorkspaceResourceName: aifoundry.outputs.logAnalyticsWorkspaceResourceName
sqlServerName: sqlDBModule.outputs.sqlServerName
sqlDbName: sqlDBModule.outputs.sqlDbName
sqlUsers: [
{
principalId: managedIdentityModule.outputs.managedIdentityBackendAppOutput.clientId // Replace with actual Principal ID
principalName: managedIdentityModule.outputs.managedIdentityBackendAppOutput.name // Replace with actual user email or name
databaseRoles: ['db_datareader', 'db_datawriter']
}
]
}
}
// module uploadFiles 'deploy_post_deployment_scripts.bicep' = {
// name : 'deploy_post_deployment_scripts'
// params:{
// solutionName: solutionPrefix
// solutionLocation: secondaryLocation
// baseUrl: baseUrl
// storageAccountName: storageAccount.outputs.storageName
// containerName: storageAccount.outputs.storageContainer
// managedIdentityObjectId:managedIdentityModule.outputs.managedIdentityOutput.id
// managedIdentityClientId:managedIdentityModule.outputs.managedIdentityOutput.clientId
// keyVaultName:aifoundry.outputs.keyvaultName
// logAnalyticsWorkspaceResourceName: aifoundry.outputs.logAnalyticsWorkspaceResourceName
// sqlServerName: sqlDBModule.outputs.sqlServerName
// sqlDbName: sqlDBModule.outputs.sqlDbName
// sqlUsers: [
// {
// principalId: managedIdentityModule.outputs.managedIdentityChartsOutput.clientId // Replace with actual Principal ID
// principalName: managedIdentityModule.outputs.managedIdentityChartsOutput.name // Replace with actual user email or name
// databaseRoles: ['db_datareader', 'db_datawriter']
// }
// {
// principalId: managedIdentityModule.outputs.managedIdentityRagOutput.clientId // Replace with actual Principal ID
// principalName: managedIdentityModule.outputs.managedIdentityRagOutput.name // Replace with actual user email or name
// databaseRoles: ['db_datareader']
// }
// ]
// }
// }

module hostingplan 'deploy_app_service_plan.bicep' = {
name: 'deploy_app_service_plan'
Expand Down
2 changes: 1 addition & 1 deletion infra/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,7 @@
"resources": [
{
"copy": {
"name": "database::list",
"name": "list",
"count": "[length(variables('containers'))]"
},
"type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers",
Expand Down
50 changes: 28 additions & 22 deletions infra/scripts/add_user_scripts/create-sql-user-and-role.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
.DESCRIPTION
During an application deployment, the managed identity (and potentially the developer identity)
must be added to the SQL database as a user and assigned to one or more roles. This script
accomplishes this task using the owner-managed identity for authentication.
accomplishes this task using Azure AD authentication.

.PARAMETER SqlServerName
The name of the Azure SQL Server resource.
Expand All @@ -21,43 +21,36 @@
.PARAMETER DisplayName
The Object (Principal) display name of the identity to be added.

.PARAMETER ManagedIdentityClientId
The Client ID of the managed identity that will authenticate to the SQL database.
.PARAMETER UseManagedIdentity
Switch to indicate whether to use a Managed Identity for authentication (useful for automation).
If not provided, it will use your currently logged-in Azure AD account.

.PARAMETER DatabaseRole
The database role that should be assigned to the user (e.g., db_datareader, db_datawriter, db_owner).
#>

Param(
param (
[string] $SqlServerName,
[string] $SqlDatabaseName,
[string] $ClientId,
[string] $DisplayName,
[string] $ManagedIdentityClientId,
[switch] $UseManagedIdentity,
[string] $DatabaseRole
)

function Resolve-Module($moduleName) {
# If module is imported; say that and do nothing
if (Get-Module | Where-Object { $_.Name -eq $moduleName }) {
Write-Debug "Module $moduleName is already imported"
} elseif (Get-Module -ListAvailable | Where-Object { $_.Name -eq $moduleName }) {
Import-Module $moduleName
} elseif (Find-Module -Name $moduleName | Where-Object { $_.Name -eq $moduleName }) {
Install-Module $moduleName -Force -Scope CurrentUser
Import-Module $moduleName
} else {
Write-Error "Module $moduleName not found"
[Environment]::exit(1)
if (-not (Get-Module -ListAvailable -Name $moduleName)) {
Install-Module -Name $moduleName -Scope CurrentUser -Force -AllowClobber
}
Import-Module -Name $moduleName -Force
}

###
### MAIN SCRIPT
###
### Load Required Modules
Resolve-Module -moduleName Az.Accounts
Resolve-Module -moduleName Az.Resources
Resolve-Module -moduleName SqlServer

### Generate SQL Script
$sql = @"
DECLARE @username nvarchar(max) = N'$($DisplayName)';
DECLARE @clientId uniqueidentifier = '$($ClientId)';
Expand All @@ -70,8 +63,21 @@ END
EXEC sp_addrolemember '$($DatabaseRole)', @username;
"@

Write-Output "`nSQL:`n$($sql)`n`n"
Write-Output "`nSQL to be executed:`n$($sql)`n"

### Authenticate and Get Access Token
if ($UseManagedIdentity) {
Write-Host "[INFO] Logging in using Managed Identity..."
Connect-AzAccount -Identity
} else {
Write-Host "[INFO] Logging in using current user identity..."
Connect-AzAccount
}

Connect-AzAccount -Identity -AccountId $ManagedIdentityClientId
$token = (Get-AzAccessToken -ResourceUrl https://database.windows.net/).Token
Invoke-SqlCmd -ServerInstance "$SqlServerName" -Database $SqlDatabaseName -AccessToken $token -Query $sql -ErrorAction 'Stop'

### Execute the SQL Command
Write-Host "[INFO] Executing SQL against $SqlDatabaseName..."
Invoke-Sqlcmd -ServerInstance "$SqlServerName.database.windows.net" -Database $SqlDatabaseName -AccessToken $token -Query $sql -ErrorAction Stop

Write-Host "[SUCCESS] User and role assignment completed."
74 changes: 56 additions & 18 deletions infra/scripts/copy_kb_files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,71 @@
# Variables
storageAccount="$1"
fileSystem="$2"
baseUrl="$3"
# baseUrl="$3"
managedIdentityClientId="$4"
keyVaultName="$5" # ✅ NEW ARG REQUIRED

zipFileName1="call_transcripts.zip"
extractedFolder1="call_transcripts"
zipUrl1=${baseUrl}"infra/data/call_transcripts.zip"
zipUrl1="infra/data/call_transcripts.zip"

zipFileName2="audio_data.zip"
extractedFolder2="audiodata"
zipUrl2=${baseUrl}"infra/data/audio_data.zip"
zipUrl2="infra/data/audio_data.zip"

# Create folders if they do not exist
mkdir -p "/mnt/azscripts/azscriptinput/$extractedFolder1"
mkdir -p "/mnt/azscripts/azscriptinput/$extractedFolder2"
unzip infra/data/"$zipFileName1" -d infra/data/"$extractedFolder1"
unzip infra/data/"$zipFileName2" -d infra/data/"$extractedFolder2"

# Download the zip file
curl --output /mnt/azscripts/azscriptinput/"$zipFileName1" "$zipUrl1"
curl --output /mnt/azscripts/azscriptinput/"$zipFileName2" "$zipUrl2"
echo "Script Started"

# Extract the zip file
unzip /mnt/azscripts/azscriptinput/"$zipFileName1" -d /mnt/azscripts/azscriptinput/"$extractedFolder1"
unzip /mnt/azscripts/azscriptinput/"$zipFileName2" -d /mnt/azscripts/azscriptinput/"$extractedFolder2"
# Authenticate with Azure
if az account show &> /dev/null; then
echo "Already authenticated with Azure."
else
if [ -n "$managedIdentityClientId" ]; then
echo "Authenticating with Managed Identity..."
az login --identity --client-id ${managedIdentityClientId}
else
echo "Authenticating with Azure CLI..."
az login
fi
echo "Not authenticated with Azure. Attempting to authenticate..."
fi

echo "Script Started"
echo "Getting signed in user id"
signed_user_id=$(az ad signed-in-user show --query id -o tsv)

echo "Getting storage account resource id"
storage_account_resource_id=$(az storage account show --name $storageAccount --query id --output tsv)

# ✅ Assign Storage Blob Data Contributor role (if not already assigned)
echo "Checking if user has the Storage Blob Data Contributor role"
storage_role_assignment=$(az role assignment list --assignee $signed_user_id --role "Storage Blob Data Contributor" --scope $storage_account_resource_id --query "[].roleDefinitionId" -o tsv)

if [ -z "$storage_role_assignment" ]; then
echo "Assigning Storage Blob Data Contributor role..."
az role assignment create --assignee $signed_user_id --role "Storage Blob Data Contributor" --scope $storage_account_resource_id --output none
echo "Role assignment for Blob Storage completed."
else
echo "User already has Storage Blob Data Contributor role."
fi

# ✅ Assign Key Vault Secrets User role (NEW BLOCK)
echo "Getting Key Vault resource ID"
key_vault_resource_id=$(az keyvault show --name $keyVaultName --query id --output tsv)

echo "Checking if user has Key Vault Secrets User role"
kv_role_assignment=$(az role assignment list --assignee $signed_user_id --role "Key Vault Secrets User" --scope $key_vault_resource_id --query "[].roleDefinitionId" -o tsv)

if [ -z "$kv_role_assignment" ]; then
echo "Assigning Key Vault Secrets User role..."
az role assignment create --assignee $signed_user_id --role "Key Vault Secrets User" --scope $key_vault_resource_id --output none
echo "Role assignment for Key Vault completed."
else
echo "User already has Key Vault Secrets User role."
fi

# Authenticate with Azure using managed identity
az login --identity --client-id ${managedIdentityClientId}
# Using az storage blob upload-batch to upload files with managed identity authentication, as the az storage fs directory upload command is not working with managed identity authentication.
az storage blob upload-batch --account-name "$storageAccount" --destination data/"$extractedFolder1" --source /mnt/azscripts/azscriptinput/"$extractedFolder1" --auth-mode login --pattern '*' --overwrite
az storage blob upload-batch --account-name "$storageAccount" --destination data/"$extractedFolder2" --source /mnt/azscripts/azscriptinput/"$extractedFolder2" --auth-mode login --pattern '*' --overwrite
# Upload files to Azure Storage
echo "Uploading files to Azure Storage"
az storage blob upload-batch --account-name "$storageAccount" --destination "$fileSystem"/"$extractedFolder1" --source infra/data/"$extractedFolder1" --auth-mode login --pattern '*' --overwrite --output none
az storage blob upload-batch --account-name "$storageAccount" --destination "$fileSystem"/"$extractedFolder2" --source infra/data/"$extractedFolder2" --auth-mode login --pattern '*' --overwrite --output none
5 changes: 3 additions & 2 deletions infra/scripts/index_scripts/01_create_search_index.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
import sys

key_vault_name = 'kv_to-be-replaced'
managed_identity_client_id = 'mici_to-be-replaced'
key_vault_name=sys.argv[1]
managed_identity_client_id = sys.argv[2]
index_name = "call_transcripts_index"

def get_secrets_from_kv(kv_name, secret_name):
Expand Down
4 changes: 2 additions & 2 deletions infra/scripts/index_scripts/02_create_cu_template_audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from pathlib import Path
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

key_vault_name = 'kv_to-be-replaced'
managed_identity_client_id = 'mici_to-be-replaced'
key_vault_name=sys.argv[1]
managed_identity_client_id = sys.argv[2]

def get_secrets_from_kv(kv_name, secret_name):

Expand Down
4 changes: 2 additions & 2 deletions infra/scripts/index_scripts/02_create_cu_template_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from pathlib import Path
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

key_vault_name = 'kv_to-be-replaced'
managed_identity_client_id = 'mici_to-be-replaced'
key_vault_name=sys.argv[1]
managed_identity_client_id = sys.argv[2]

def get_secrets_from_kv(kv_name, secret_name):

Expand Down
Loading
Loading