From c4655fd83a7c272a2329d5cc8394daea6cfbd208 Mon Sep 17 00:00:00 2001 From: Harsh-Microsoft Date: Tue, 8 Jul 2025 18:50:52 +0530 Subject: [PATCH 1/7] remove useLocalBuild flag and update docker-build scripts --- infra/deploy_app_service.bicep | 4 +- infra/deploy_backend_docker.bicep | 34 +++--- infra/deploy_container_registry.bicep | 21 +++- infra/deploy_frontend_docker.bicep | 34 +++--- infra/main.bicep | 23 ++-- infra/scripts/docker-build.ps1 | 158 +++++++++++++++++++++----- infra/scripts/docker-build.sh | 129 +++++++++++++++++---- 7 files changed, 305 insertions(+), 98 deletions(-) diff --git a/infra/deploy_app_service.bicep b/infra/deploy_app_service.bicep index d1857fe72..ecb4a8a1a 100644 --- a/infra/deploy_app_service.bicep +++ b/infra/deploy_app_service.bicep @@ -12,7 +12,7 @@ param appSettings object = {} param appServicePlanId string param appImageName string param userassignedIdentityId string = '' -param useLocalBuild string +// param useLocalBuild string resource appService 'Microsoft.Web/sites@2020-06-01' = { name: solutionName @@ -28,7 +28,7 @@ resource appService 'Microsoft.Web/sites@2020-06-01' = { properties: { serverFarmId: appServicePlanId siteConfig: { - acrUseManagedIdentityCreds: useLocalBuild == 'true' + // acrUseManagedIdentityCreds: useLocalBuild == 'true' alwaysOn: true ftpsState: 'Disabled' linuxFxVersion: appImageName diff --git a/infra/deploy_backend_docker.bicep b/infra/deploy_backend_docker.bicep index 9354448d1..86f683e33 100644 --- a/infra/deploy_backend_docker.bicep +++ b/infra/deploy_backend_docker.bicep @@ -11,7 +11,7 @@ param appServicePlanId string param userassignedIdentityId string param keyVaultName string param aiServicesName string -param useLocalBuild string +// param useLocalBuild string param azureExistingAIProjectResourceId string = '' param aiSearchName string var existingAIServiceSubscription = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[2] : subscription().subscriptionId @@ -92,7 +92,7 @@ module appService 'deploy_app_service.bicep' = { appServicePlanId: appServicePlanId appImageName: imageName userassignedIdentityId:userassignedIdentityId - useLocalBuild: useLocalBuild + // useLocalBuild: useLocalBuild appSettings: union( appSettings, { @@ -176,23 +176,25 @@ module assignAiUserRoleToAiProject 'deploy_foundry_role_assignment.bicep' = { } } -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = if (useLocalBuild == 'true') { - name: acrName -} +// resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = if (useLocalBuild == 'true') { +// name: acrName +// } -resource AcrPull 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = if (useLocalBuild == 'true') { - name: '7f951dda-4ed3-4680-a7ca-43fe172d538d' -} +// resource AcrPull 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = if (useLocalBuild == 'true') { +// name: '7f951dda-4ed3-4680-a7ca-43fe172d538d' +// } -resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (useLocalBuild == 'true') { - name: guid(appService.name, AcrPull.id) - scope: containerRegistry - properties: { - roleDefinitionId: AcrPull.id - principalId: appService.outputs.identityPrincipalId - } -} +// resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (useLocalBuild == 'true') { +// name: guid(appService.name, AcrPull.id) +// scope: containerRegistry +// properties: { +// roleDefinitionId: AcrPull.id +// principalId: appService.outputs.identityPrincipalId +// } +// } output appUrl string = appService.outputs.appUrl output reactAppLayoutConfig string = reactAppLayoutConfig output appInsightInstrumentationKey string = reference(applicationInsightsId, '2015-05-01').InstrumentationKey +output backendManagedIdentityPrincipalId string = appService.outputs.identityPrincipalId +output backendAppName string = name diff --git a/infra/deploy_container_registry.bicep b/infra/deploy_container_registry.bicep index dfd0addb7..e942d1abb 100644 --- a/infra/deploy_container_registry.bicep +++ b/infra/deploy_container_registry.bicep @@ -8,12 +8,18 @@ var solutionName = 'km${padLeft(take(uniqueId, 12), 12, '0')}' var abbrs = loadJsonContent('./abbreviations.json') var containerRegistryName = '${abbrs.containers.containerRegistry}${solutionName}' var containerRegistryNameCleaned = replace(containerRegistryName, '-', '') + +@description('List of Principal Ids to which ACR pull role assignment is required') +param acrPullPrincipalIds array = [] + +@description('Provide a tier of your Azure Container Registry.') +param acrSku string = 'Premium' resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' = { name: containerRegistryName location: solutionLocation sku: { - name: 'Premium' + name: acrSku } properties: { dataEndpointEnabled: false @@ -38,6 +44,19 @@ resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' = zoneRedundancy: 'Disabled' } } + +// Add Role assignments for required principal id's +resource acrPullRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in acrPullPrincipalIds: { + name: guid(principalId, 'acrpull') + scope: containerRegistry + properties: { + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7f951dda-4ed3-4680-a7ca-43fe172d538d' + ) + principalId: principalId + } +}] output createdAcrName string = containerRegistryNameCleaned output createdAcrId string = containerRegistry.id diff --git a/infra/deploy_frontend_docker.bicep b/infra/deploy_frontend_docker.bicep index e1c13f237..79820f048 100644 --- a/infra/deploy_frontend_docker.bicep +++ b/infra/deploy_frontend_docker.bicep @@ -8,7 +8,7 @@ param solutionLocation string @secure() param appSettings object = {} param appServicePlanId string -param useLocalBuild string +// param useLocalBuild string var imageName = 'DOCKER|${acrName}.azurecr.io/km-app:${imageTag}' //var name = '${solutionName}-app' @@ -20,7 +20,7 @@ module appService 'deploy_app_service.bicep' = { solutionName: name appServicePlanId: appServicePlanId appImageName: imageName - useLocalBuild: useLocalBuild + // useLocalBuild: useLocalBuild appSettings: union( appSettings, { @@ -30,21 +30,23 @@ module appService 'deploy_app_service.bicep' = { } } -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = if (useLocalBuild == 'true') { - name: acrName -} +// resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = if (useLocalBuild == 'true') { +// name: acrName +// } -resource AcrPull 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = if (useLocalBuild == 'true') { - name: '7f951dda-4ed3-4680-a7ca-43fe172d538d' -} +// resource AcrPull 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = if (useLocalBuild == 'true') { +// name: '7f951dda-4ed3-4680-a7ca-43fe172d538d' +// } -resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (useLocalBuild == 'true') { - name: guid(appService.name, AcrPull.id) - scope: containerRegistry - properties: { - roleDefinitionId: AcrPull.id - principalId: appService.outputs.identityPrincipalId - } -} +// resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (useLocalBuild == 'true') { +// name: guid(appService.name, AcrPull.id) +// scope: containerRegistry +// properties: { +// roleDefinitionId: AcrPull.id +// principalId: appService.outputs.identityPrincipalId +// } +// } output appUrl string = appService.outputs.appUrl +output frontendManagedIdentityPrincipalId string = appService.outputs.identityPrincipalId +output frontendAppName string = name diff --git a/infra/main.bicep b/infra/main.bicep index a1f36a6ac..2cd08724b 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -66,11 +66,11 @@ param imageTag string = 'latest_fdp' param AZURE_LOCATION string='' var solutionLocation = empty(AZURE_LOCATION) ? resourceGroup().location : AZURE_LOCATION -@description('Set this flag to true only if you are deploying from Local') -param useLocalBuild string = 'false' +// @description('Set this flag to true only if you are deploying from Local') +// param useLocalBuild string = 'false' -// Convert input to lowercase -var useLocalBuildLower = toLower(useLocalBuild) +// // Convert input to lowercase +// var useLocalBuildLower = toLower(useLocalBuild) var uniqueId = toLower(uniqueString(subscription().id, environmentName, solutionLocation)) @@ -89,9 +89,9 @@ param aiDeploymentsLocation string var solutionPrefix = 'km${padLeft(take(uniqueId, 12), 12, '0')}' -var containerRegistryName = '${abbrs.containers.containerRegistry}${solutionPrefix}' -var containerRegistryNameCleaned = replace(containerRegistryName, '-', '') -var acrName = useLocalBuildLower == 'true' ? containerRegistryNameCleaned : 'kmcontainerreg' +// var containerRegistryName = '${abbrs.containers.containerRegistry}${solutionPrefix}' +// var containerRegistryNameCleaned = replace(containerRegistryName, '-', '') +var acrName = 'kmcontainerreg' var baseUrl = 'https://raw.githubusercontent.com/microsoft/Conversation-Knowledge-Mining-Solution-Accelerator/main/' @@ -226,7 +226,7 @@ module backend_docker 'deploy_backend_docker.bicep' = { userassignedIdentityId: managedIdentityModule.outputs.managedIdentityBackendAppOutput.id keyVaultName: kvault.outputs.keyvaultName aiServicesName: aifoundry.outputs.aiServicesName - useLocalBuild: useLocalBuildLower + // useLocalBuild: useLocalBuildLower azureExistingAIProjectResourceId: azureExistingAIProjectResourceId aiSearchName: aifoundry.outputs.aiSearchName appSettings: { @@ -269,7 +269,7 @@ module frontend_docker 'deploy_frontend_docker.bicep' = { acrName: acrName appServicePlanId: hostingplan.outputs.name applicationInsightsId: aifoundry.outputs.applicationInsightsId - useLocalBuild: useLocalBuildLower + // useLocalBuild: useLocalBuildLower appSettings:{ APP_API_BASE_URL:backend_docker.outputs.appUrl } @@ -319,3 +319,8 @@ output AZURE_ENV_IMAGETAG string = imageTag output API_APP_URL string = backend_docker.outputs.appUrl output WEB_APP_URL string = frontend_docker.outputs.appUrl output APPLICATIONINSIGHTS_CONNECTION_STRING string = aifoundry.outputs.applicationInsightsConnectionString + +output BACKEND_APP_NAME string = backend_docker.outputs.backendAppName +output FRONTEND_APP_NAME string = frontend_docker.outputs.frontendAppName +output BACKEND_MANAGED_IDENTITY_PRINCIPAL_ID string = backend_docker.outputs.backendManagedIdentityPrincipalId +output FRONTEND_MANAGED_IDENTITY_PRINCIPAL_ID string = frontend_docker.outputs.frontendManagedIdentityPrincipalId diff --git a/infra/scripts/docker-build.ps1 b/infra/scripts/docker-build.ps1 index 64510d6f0..cda645628 100644 --- a/infra/scripts/docker-build.ps1 +++ b/infra/scripts/docker-build.ps1 @@ -1,33 +1,82 @@ # Define script parameters -param ( - [string]$AZURE_SUBSCRIPTION_ID, - [string]$ENV_NAME, - [string]$AZURE_LOCATION, - [string]$AZURE_RESOURCE_GROUP, - [string]$USE_LOCAL_BUILD, - [string]$AZURE_ENV_IMAGETAG -) - -# Convert USE_LOCAL_BUILD to Boolean -$USE_LOCAL_BUILD = if ($USE_LOCAL_BUILD -match "^(?i:true)$") { $true } else { $false } - -if ([string]::IsNullOrEmpty($AZURE_ENV_IMAGETAG)) { - $AZURE_ENV_IMAGETAG = "latest_fdp" -} +# param ( +# [string]$AZURE_SUBSCRIPTION_ID, +# [string]$ENV_NAME, +# [string]$AZURE_LOCATION, +# [string]$AZURE_RESOURCE_GROUP, +# [string]$USE_LOCAL_BUILD, +# [string]$AZURE_ENV_IMAGETAG +# ) + +# # Convert USE_LOCAL_BUILD to Boolean +# $USE_LOCAL_BUILD = if ($USE_LOCAL_BUILD -match "^(?i:true)$") { $true } else { $false } + +# if ([string]::IsNullOrEmpty($AZURE_ENV_IMAGETAG)) { +# $AZURE_ENV_IMAGETAG = "latest_fdp" +# } # Validate required parameters -if (-not $AZURE_SUBSCRIPTION_ID -or -not $ENV_NAME -or -not $AZURE_LOCATION -or -not $AZURE_RESOURCE_GROUP) { - Write-Error "Missing required arguments. Usage: docker-build.ps1 " - exit 1 -} +# if (-not $AZURE_SUBSCRIPTION_ID -or -not $ENV_NAME -or -not $AZURE_LOCATION -or -not $AZURE_RESOURCE_GROUP) { +# Write-Error "Missing required arguments. Usage: docker-build.ps1 " +# exit 1 +# } # Exit early if local build is not requested -if ($USE_LOCAL_BUILD -eq $false) { - Write-Output "Local Build not enabled. Using prebuilt image." - exit 0 +# if ($USE_LOCAL_BUILD -eq $false) { +# Write-Output "Local Build not enabled. Using prebuilt image." +# exit 0 +# } + +# Get all environment values +$envValues = azd env get-values --output json | ConvertFrom-Json + +# Validate and fetch required parameters from azd env if missing +function Get-AzdEnvValueOrDefault { + param ( + [Parameter(Mandatory = $true)] + [string]$KeyName, + + [Parameter(Mandatory = $false)] + [string]$DefaultValue = "", + + [Parameter(Mandatory = $false)] + [bool]$Required = $false + ) + + # Check if key exists + if ($envValues.PSObject.Properties.Name -contains $KeyName) { + return $envValues.$KeyName + } + + # Key doesn't exist + if ($Required) { + Write-Error "Required environment key '$KeyName' not found in azd environment." + exit 1 + } else { + return $DefaultValue + } } -Write-Output "Local Build enabled. Starting build process." +# Read the required details from Bicep deployment output +$AZURE_SUBSCRIPTION_ID = Get-AzdEnvValueOrDefault -KeyName "AZURE_SUBSCRIPTION_ID" -Required $true +$ENV_NAME = Get-AzdEnvValueOrDefault -KeyName "AZURE_ENV_NAME" -Required $true +$WEB_APP_IDENTITY_PRINCIPAL_ID = Get-AzdEnvValueOrDefault -KeyName "FRONTEND_MANAGED_IDENTITY_PRINCIPAL_ID" -Required $true +$API_APP_IDENTITY_PRINCIPAL_ID = Get-AzdEnvValueOrDefault -KeyName "BACKEND_MANAGED_IDENTITY_PRINCIPAL_ID" -Required $true +$AZURE_RESOURCE_GROUP = Get-AzdEnvValueOrDefault -KeyName "AZURE_RESOURCE_GROUP" -Required $true +$AZURE_ENV_IMAGETAG = Get-AzdEnvValueOrDefault -KeyName "AZURE_ENV_IMAGETAG" -DefaultValue "latest" +$WEB_APP_NAME=Get-AzdEnvValueOrDefault -KeyName "FRONTEND_APP_NAME" -Required $true +$API_APP_NAME=Get-AzdEnvValueOrDefault -KeyName "BACKEND_APP_NAME" -Required $true + +# Export the variables for later use +Write-Host "Using the following parameters:" +Write-Host "AZURE_SUBSCRIPTION_ID = $AZURE_SUBSCRIPTION_ID" +Write-Host "ENV_NAME = $ENV_NAME" +Write-Host "AZURE_RESOURCE_GROUP = $AZURE_RESOURCE_GROUP" +Write-Host "AZURE_ENV_IMAGETAG = $AZURE_ENV_IMAGETAG" +Write-Host "WEB_APP_NAME = $WEB_APP_NAME" +Write-Host "API_APP_NAME = $API_APP_NAME" + +Write-Output "Starting build process." # STEP 1: Ensure user is logged into Azure Write-Host "Checking Azure login status..." @@ -51,16 +100,20 @@ if ($LASTEXITCODE -ne 0) { exit 1 } -# STEP 3: Deploy container registry -Write-Host "Deploying container registry in location: $AZURE_LOCATION" -$OUTPUTS = az deployment group create --resource-group $AZURE_RESOURCE_GROUP --template-file "./infra/deploy_container_registry.bicep" --parameters environmentName=$ENV_NAME --query "properties.outputs" --output json | ConvertFrom-Json +# STEP 3: Get current script directory +$ScriptDir = $PSScriptRoot + +# STEP 4: Deploy container registry +Write-Host "Deploying container registry" +$TemplateFile = Join-Path $ScriptDir "..\deploy_container_registry.bicep" | Resolve-Path +$OUTPUTS = az deployment group create --resource-group $AZURE_RESOURCE_GROUP --template-file $TemplateFile --parameters environmentName=$ENV_NAME --query "properties.outputs" --output json | ConvertFrom-Json # Extract ACR name and endpoint $ACR_NAME = $OUTPUTS.createdAcrName.value Write-Host "Extracted ACR Name: $ACR_NAME" -# STEP 4: Login to Azure Container Registry +# STEP 5: Login to Azure Container Registry Write-Host "Logging into Azure Container Registry: $ACR_NAME" az acr login -n $ACR_NAME if ($LASTEXITCODE -ne 0) { @@ -68,9 +121,6 @@ if ($LASTEXITCODE -ne 0) { exit 1 } -# STEP 5: Get current script directory -$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path - # STEP 6: Resolve full paths to Dockerfiles and build contexts $WebAppDockerfilePath = Join-Path $ScriptDir "..\..\src\App\WebApp.Dockerfile" | Resolve-Path $WebAppContextPath = Join-Path $ScriptDir "..\..\src\App" | Resolve-Path @@ -111,3 +161,51 @@ Build-And-Push-Image "km-api" $ApiAppDockerfilePath $ApiAppContextPath $AZURE_EN Build-And-Push-Image "km-app" $WebAppDockerfilePath $WebAppContextPath $AZURE_ENV_IMAGETAG Write-Host "`nAll Docker images built and pushed successfully with tag: $AZURE_ENV_IMAGETAG" + +# STEP 9: Define Function to Update Web App settings to use Managed Identity for ACR pull +function Update-WebApp-Settings { + param ( + [string]$WebAppName, + [string]$ResourceGroup + ) + + Write-Host "Updating Web App settings for $WebAppName" + $webAppConfig = az webapp config show --resource-group $ResourceGroup --name $WebAppName --query id --output tsv + if (-not $webAppConfig) { + Write-Error "Error: Web App configuration not found for $WebAppName" + exit 1 + } + az resource update --ids $webAppConfig --set properties.acrUseManagedIdentityCreds=True --output none + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to update Web App settings for $WebAppName" + exit 1 + } + Write-Host "Web App settings updated successfully for $WebAppName" +} + +# STEP 10: Update Web App settings to use the new image +Update-WebApp-Settings -WebAppName $WEB_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP +Update-WebApp-Settings -WebAppName $API_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP + +# STEP 11: Define function to update Web App to use new image +function Update-WebApp-Image { + param ( + [string]$WebAppName, + [string]$ResourceGroup, + [string]$Image + ) + + Write-Host "Updating Web App $WebAppName to use image: $Image" + az webapp config container set --name $WebAppName --resource-group $ResourceGroup --container-image-name $Image + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to update Web App $WebAppName to use image: $Image" + exit 1 + } + Write-Host "Web App $WebAppName updated successfully to use image: $Image" +} + +# STEP 12: Update Web Apps to use new images +Update-WebApp-Image -WebAppName $WEB_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP -Image "$ACR_NAME.azurecr.io/km-app:$AZURE_ENV_IMAGETAG" +Update-WebApp-Image -WebAppName $API_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP -Image "$ACR_NAME.azurecr.io/km-api:$AZURE_ENV_IMAGETAG" + +Write-Host "Web Apps updated successfully to use new images" \ No newline at end of file diff --git a/infra/scripts/docker-build.sh b/infra/scripts/docker-build.sh index 8fdac8088..abd4b2d2c 100644 --- a/infra/scripts/docker-build.sh +++ b/infra/scripts/docker-build.sh @@ -2,31 +2,66 @@ set -e -AZURE_SUBSCRIPTION_ID="$1" -ENV_NAME="$2" -AZURE_LOCATION="$3" -AZURE_RESOURCE_GROUP="$4" -USE_LOCAL_BUILD="$5" -AZURE_ENV_IMAGETAG="$6" +# AZURE_SUBSCRIPTION_ID="$1" +# ENV_NAME="$2" +# AZURE_RESOURCE_GROUP="$4" +# USE_LOCAL_BUILD="$5" +# AZURE_ENV_IMAGETAG="$6" + +get_azd_env_value_or_default() { + local key="$1" + local default="$2" + local required="${3:-false}" + + value=$(azd env get-value "$key" 2>/dev/null || echo "") + + if [ -z "$value" ]; then + if [ "$required" = true ]; then + echo "❌ Required environment key '$key' not found." >&2 + exit 1 + else + value="$default" + fi + fi + + echo "$value" +} +# Required env variables +AZURE_SUBSCRIPTION_ID=$(get_azd_env_value_or_default "AZURE_SUBSCRIPTION_ID" "" true) +ENV_NAME=$(get_azd_env_value_or_default "AZURE_ENV_NAME" "" true) +WEB_APP_IDENTITY_PRINCIPAL_ID=$(get_azd_env_value_or_default "FRONTEND_MANAGED_IDENTITY_PRINCIPAL_ID" "" true) +API_APP_IDENTITY_PRINCIPAL_ID=$(get_azd_env_value_or_default "BACKEND_MANAGED_IDENTITY_PRINCIPAL_ID" "" true) +AZURE_RESOURCE_GROUP=$(get_azd_env_value_or_default "AZURE_RESOURCE_GROUP" "" true) +AZURE_ENV_IMAGETAG=$(get_azd_env_value_or_default "AZURE_ENV_IMAGETAG" "latest" false) +WEB_APP_NAME=$(get_azd_env_value_or_default "FRONTEND_APP_NAME" "" true) +API_APP_NAME=$(get_azd_env_value_or_default "BACKEND_APP_NAME" "" true) + +echo "Using the following parameters:" +echo "AZURE_SUBSCRIPTION_ID = $AZURE_SUBSCRIPTION_ID" +echo "ENV_NAME = $ENV_NAME" +echo "AZURE_RESOURCE_GROUP = $AZURE_RESOURCE_GROUP" +echo "AZURE_ENV_IMAGETAG = $AZURE_ENV_IMAGETAG" +echo "WEB_APP_NAME = $WEB_APP_NAME" +echo "API_APP_NAME = $API_APP_NAME" # Validate required parameters -if [[ -z "$AZURE_SUBSCRIPTION_ID" || -z "$ENV_NAME" || -z "$AZURE_LOCATION" || -z "$AZURE_RESOURCE_GROUP" ]]; then - echo "Missing required arguments. Usage: docker-build.sh " - exit 1 -fi +# if [[ -z "$AZURE_SUBSCRIPTION_ID" || -z "$ENV_NAME" || -z "$AZURE_LOCATION" || -z "$AZURE_RESOURCE_GROUP" ]]; then +# echo "Missing required arguments. Usage: docker-build.sh " +# exit 1 +# fi # Ensure jq is installed which jq || { echo "jq is not installed"; exit 1; } # Exit early if local build is not requested -if [[ "${USE_LOCAL_BUILD,,}" != "true" ]]; then - echo "Local Build not enabled. Using prebuilt image." - exit 0 -fi +# if [[ "${USE_LOCAL_BUILD,,}" != "true" ]]; then +# echo "Local Build not enabled. Using prebuilt image." +# exit 0 +# fi -AZURE_ENV_IMAGETAG=${AZURE_ENV_IMAGETAG:-latest} +# AZURE_ENV_IMAGETAG=${AZURE_ENV_IMAGETAG:-latest} -echo "Local Build enabled. Starting build process." +echo "Starting build process." # STEP 1: Ensure user is logged into Azure if ! az account show > /dev/null 2>&1; then @@ -47,12 +82,16 @@ if [[ $? -ne 0 ]]; then exit 1 fi -# STEP 3: Deploy container registry -echo "Deploying container registry in location: $AZURE_LOCATION" +# STEP 3: Get current script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# STEP 4: Deploy container registry +TEMPLATE_FILE="$SCRIPT_DIR/../deploy_container_registry.bicep" +echo "Deploying container registry" OUTPUTS=$(az deployment group create \ --resource-group "$AZURE_RESOURCE_GROUP" \ - --template-file "./infra/deploy_container_registry.bicep" \ - --parameters environmentName="$ENV_NAME" \ + --template-file "$TEMPLATE_FILE" \ + --parameters environmentName="$ENV_NAME" acrPullPrincipalIds="['$WEB_APP_IDENTITY_PRINCIPAL_ID', '$API_APP_IDENTITY_PRINCIPAL_ID']" \ --query "properties.outputs" \ --output json) @@ -60,7 +99,7 @@ ACR_NAME=$(echo "$OUTPUTS" | jq -r '.createdAcrName.value') echo "Extracted ACR Name: $ACR_NAME" -# STEP 4: Login to Azure Container Registry +# STEP 5: Login to Azure Container Registry echo "Logging into Azure Container Registry: $ACR_NAME" az acr login -n "$ACR_NAME" if [[ $? -ne 0 ]]; then @@ -68,9 +107,6 @@ if [[ $? -ne 0 ]]; then exit 1 fi -# STEP 5: Get current script directory -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - # STEP 6: Resolve full paths to Dockerfiles and build contexts WEBAPP_DOCKERFILE_PATH="$SCRIPT_DIR/../../src/App/WebApp.Dockerfile" WEBAPP_CONTEXT_PATH="$SCRIPT_DIR/../../src/App" @@ -108,3 +144,48 @@ build_and_push_image "km-api" "$APIAPP_DOCKERFILE_PATH" "$APIAPP_CONTEXT_PATH" " build_and_push_image "km-app" "$WEBAPP_DOCKERFILE_PATH" "$WEBAPP_CONTEXT_PATH" "$AZURE_ENV_IMAGETAG" echo -e "\nAll Docker images built and pushed successfully with tag: $AZURE_ENV_IMAGETAG" + +# STEP 9: Function to Update Web App settings to use Managed Identity for ACR pull +update_web_app_settings() { + local webAppName="$1" + local resourceGroup="$2" + + echo "Updating Web App settings for $webAppName" + webAppConfig=$(az webapp config show --resource-group "$resourceGroup" --name "$webAppName" --query id --output tsv) + if [[ -z "$webAppConfig" ]]; then + echo "Error: Web App configuration not found for $webAppName" + exit 1 + fi + az resource update --ids "$webAppConfig" --set properties.acrUseManagedIdentityCreds=True --output none + if [[ $? -ne 0 ]]; then + echo "Failed to update Web App settings for $webAppName" + exit 1 + fi + echo "Web App settings updated successfully for $webAppName" +} + +# STEP 10: Update Web App settings +update_web_app_settings "$WEB_APP_NAME" "$AZURE_RESOURCE_GROUP" +update_web_app_settings "$API_APP_NAME" "$AZURE_RESOURCE_GROUP" + +# STEP 11: Function to Update Web App to use new image +update_web_app_image() { + local webAppName="$1" + local resourceGroup="$2" + local image="$3" + + echo "Updating Web App $webAppName to use new image tag: $image" + az webapp config container set --name "$webAppName" --resource-group "$resourceGroup" --container-image-name "$image" + if [[ $? -ne 0 ]]; then + echo "Failed to update Web App $webAppName to use new image: $image" + exit 1 + fi + echo "Web App $webAppName updated successfully to use new image: $image" + +} + +# STEP 12: Update Web Apps to use new images +update_web_app_image "$WEB_APP_NAME" "$AZURE_RESOURCE_GROUP" "$ACR_NAME.azurecr.io/km-app:$AZURE_ENV_IMAGETAG" +update_web_app_image "$API_APP_NAME" "$AZURE_RESOURCE_GROUP" "$ACR_NAME.azurecr.io/km-api:$AZURE_ENV_IMAGETAG" + +echo "Web Apps updated successfully to use new images" From 701c1d8f54f0d3b7907e0a65d107147378bbcf90 Mon Sep 17 00:00:00 2001 From: Harsh-Microsoft Date: Wed, 9 Jul 2025 18:08:38 +0530 Subject: [PATCH 2/7] docs: remove USE_LOCAL_BUILD parameter from documentation and add instructions for publishing local build container manually --- documents/CustomizingAzdParameters.md | 1 - documents/DeploymentGuide.md | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/documents/CustomizingAzdParameters.md b/documents/CustomizingAzdParameters.md index 59bf9dc5f..b1708e42e 100644 --- a/documents/CustomizingAzdParameters.md +++ b/documents/CustomizingAzdParameters.md @@ -22,7 +22,6 @@ By default this template will use the environment name as the prefix to prevent | `AZURE_ENV_IMAGETAG` | string | `latest` | Sets the image tag (`latest`, `dev`, `hotfix`, etc.). | | `AZURE_OPENAI_EMBEDDING_MODEL_CAPACITY` | integer | `80` | Sets the capacity for the embedding model deployment. | | `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | Guide to get your [Existing Workspace ID](/documents/re-use-log-analytics.md) | Reuses an existing Log Analytics Workspace instead of creating a new one. | -| `USE_LOCAL_BUILD` | string | `false` | Indicates whether to use a local container build for deployment. | | `AZURE_EXISTING_AI_PROJECT_RESOURCE_ID` | string | `` | Reuses an existing AIFoundry and AIFoundryProject instead of creating a new one. | diff --git a/documents/DeploymentGuide.md b/documents/DeploymentGuide.md index 5a0c17c41..ed879ff97 100644 --- a/documents/DeploymentGuide.md +++ b/documents/DeploymentGuide.md @@ -120,7 +120,6 @@ When you start the deployment, most parameters will have **default values**, but | **Embedding Model Capacity** | Set the capacity for **embedding models** (in thousands). | 80k | | **Image Tag** | Docker image tag to deploy. Common values: `latest`, `dev`, `hotfix`. | latest | | **Existing Log Analytics Workspace** | To reuse an existing Log Analytics Workspace ID. | *(empty)* | -| **Use Local Build** | Boolean flag to determine if local container builds should be used. | false | @@ -187,6 +186,24 @@ Once you've opened the project in [Codespaces](#github-codespaces), [Dev Contain - Follow steps in [Delete Resource Group](./DeleteResourceGroup.md) if your deployment fails and/or you need to clean up the resources. +3. **Optional: Publishing Local Build Container to Azure Container Registry** + + If you need to rebuild the source code and push the updated container to the deployed Azure Container Registry, follow these steps: + + - **Linux/macOS**: + ```bash + cd ./infra/scripts/ + ./docker-build.sh + ``` + + - **Windows (PowerShell)**: + ```powershell + cd .\infra\scripts\ + .\docker-build.ps1 + ``` + + This will create a new Azure Container Registry, rebuild the source code, package it into a container, and push it to the Container Registry created. + ## Sample Questions To help you get started, here are some **Sample Questions** you can ask in the app: From 97c23064eb123c8442b2620420d7c8b522908a77 Mon Sep 17 00:00:00 2001 From: Harsh-Microsoft Date: Wed, 9 Jul 2025 18:10:09 +0530 Subject: [PATCH 3/7] refactor: remove useLocalBuild parameter and related comments from deployment scripts --- infra/deploy_app_service.bicep | 2 -- infra/deploy_backend_docker.bicep | 18 ------------------ infra/deploy_frontend_docker.bicep | 18 ------------------ infra/main.bicep | 10 ---------- 4 files changed, 48 deletions(-) diff --git a/infra/deploy_app_service.bicep b/infra/deploy_app_service.bicep index ecb4a8a1a..1b9eae21b 100644 --- a/infra/deploy_app_service.bicep +++ b/infra/deploy_app_service.bicep @@ -12,7 +12,6 @@ param appSettings object = {} param appServicePlanId string param appImageName string param userassignedIdentityId string = '' -// param useLocalBuild string resource appService 'Microsoft.Web/sites@2020-06-01' = { name: solutionName @@ -28,7 +27,6 @@ resource appService 'Microsoft.Web/sites@2020-06-01' = { properties: { serverFarmId: appServicePlanId siteConfig: { - // acrUseManagedIdentityCreds: useLocalBuild == 'true' alwaysOn: true ftpsState: 'Disabled' linuxFxVersion: appImageName diff --git a/infra/deploy_backend_docker.bicep b/infra/deploy_backend_docker.bicep index 86f683e33..aeaddef8b 100644 --- a/infra/deploy_backend_docker.bicep +++ b/infra/deploy_backend_docker.bicep @@ -11,7 +11,6 @@ param appServicePlanId string param userassignedIdentityId string param keyVaultName string param aiServicesName string -// param useLocalBuild string param azureExistingAIProjectResourceId string = '' param aiSearchName string var existingAIServiceSubscription = !empty(azureExistingAIProjectResourceId) ? split(azureExistingAIProjectResourceId, '/')[2] : subscription().subscriptionId @@ -92,7 +91,6 @@ module appService 'deploy_app_service.bicep' = { appServicePlanId: appServicePlanId appImageName: imageName userassignedIdentityId:userassignedIdentityId - // useLocalBuild: useLocalBuild appSettings: union( appSettings, { @@ -176,22 +174,6 @@ module assignAiUserRoleToAiProject 'deploy_foundry_role_assignment.bicep' = { } } -// resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = if (useLocalBuild == 'true') { -// name: acrName -// } - -// resource AcrPull 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = if (useLocalBuild == 'true') { -// name: '7f951dda-4ed3-4680-a7ca-43fe172d538d' -// } - -// resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (useLocalBuild == 'true') { -// name: guid(appService.name, AcrPull.id) -// scope: containerRegistry -// properties: { -// roleDefinitionId: AcrPull.id -// principalId: appService.outputs.identityPrincipalId -// } -// } output appUrl string = appService.outputs.appUrl output reactAppLayoutConfig string = reactAppLayoutConfig diff --git a/infra/deploy_frontend_docker.bicep b/infra/deploy_frontend_docker.bicep index 79820f048..5502f40e3 100644 --- a/infra/deploy_frontend_docker.bicep +++ b/infra/deploy_frontend_docker.bicep @@ -8,7 +8,6 @@ param solutionLocation string @secure() param appSettings object = {} param appServicePlanId string -// param useLocalBuild string var imageName = 'DOCKER|${acrName}.azurecr.io/km-app:${imageTag}' //var name = '${solutionName}-app' @@ -20,7 +19,6 @@ module appService 'deploy_app_service.bicep' = { solutionName: name appServicePlanId: appServicePlanId appImageName: imageName - // useLocalBuild: useLocalBuild appSettings: union( appSettings, { @@ -30,22 +28,6 @@ module appService 'deploy_app_service.bicep' = { } } -// resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = if (useLocalBuild == 'true') { -// name: acrName -// } - -// resource AcrPull 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = if (useLocalBuild == 'true') { -// name: '7f951dda-4ed3-4680-a7ca-43fe172d538d' -// } - -// resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (useLocalBuild == 'true') { -// name: guid(appService.name, AcrPull.id) -// scope: containerRegistry -// properties: { -// roleDefinitionId: AcrPull.id -// principalId: appService.outputs.identityPrincipalId -// } -// } output appUrl string = appService.outputs.appUrl output frontendManagedIdentityPrincipalId string = appService.outputs.identityPrincipalId diff --git a/infra/main.bicep b/infra/main.bicep index 2cd08724b..5f8fdb48a 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -66,12 +66,6 @@ param imageTag string = 'latest_fdp' param AZURE_LOCATION string='' var solutionLocation = empty(AZURE_LOCATION) ? resourceGroup().location : AZURE_LOCATION -// @description('Set this flag to true only if you are deploying from Local') -// param useLocalBuild string = 'false' - -// // Convert input to lowercase -// var useLocalBuildLower = toLower(useLocalBuild) - var uniqueId = toLower(uniqueString(subscription().id, environmentName, solutionLocation)) @@ -89,8 +83,6 @@ param aiDeploymentsLocation string var solutionPrefix = 'km${padLeft(take(uniqueId, 12), 12, '0')}' -// var containerRegistryName = '${abbrs.containers.containerRegistry}${solutionPrefix}' -// var containerRegistryNameCleaned = replace(containerRegistryName, '-', '') var acrName = 'kmcontainerreg' var baseUrl = 'https://raw.githubusercontent.com/microsoft/Conversation-Knowledge-Mining-Solution-Accelerator/main/' @@ -226,7 +218,6 @@ module backend_docker 'deploy_backend_docker.bicep' = { userassignedIdentityId: managedIdentityModule.outputs.managedIdentityBackendAppOutput.id keyVaultName: kvault.outputs.keyvaultName aiServicesName: aifoundry.outputs.aiServicesName - // useLocalBuild: useLocalBuildLower azureExistingAIProjectResourceId: azureExistingAIProjectResourceId aiSearchName: aifoundry.outputs.aiSearchName appSettings: { @@ -269,7 +260,6 @@ module frontend_docker 'deploy_frontend_docker.bicep' = { acrName: acrName appServicePlanId: hostingplan.outputs.name applicationInsightsId: aifoundry.outputs.applicationInsightsId - // useLocalBuild: useLocalBuildLower appSettings:{ APP_API_BASE_URL:backend_docker.outputs.appUrl } From d7b299ce94a3495e6701e16c16a971585e8f3643 Mon Sep 17 00:00:00 2001 From: Harsh-Microsoft Date: Wed, 9 Jul 2025 18:14:13 +0530 Subject: [PATCH 4/7] fix: add step to restart the web app in docker-build scripts --- infra/scripts/docker-build.ps1 | 55 +++++++++++----------------------- infra/scripts/docker-build.sh | 46 +++++++++++----------------- 2 files changed, 34 insertions(+), 67 deletions(-) diff --git a/infra/scripts/docker-build.ps1 b/infra/scripts/docker-build.ps1 index cda645628..0509a46cd 100644 --- a/infra/scripts/docker-build.ps1 +++ b/infra/scripts/docker-build.ps1 @@ -1,32 +1,3 @@ -# Define script parameters -# param ( -# [string]$AZURE_SUBSCRIPTION_ID, -# [string]$ENV_NAME, -# [string]$AZURE_LOCATION, -# [string]$AZURE_RESOURCE_GROUP, -# [string]$USE_LOCAL_BUILD, -# [string]$AZURE_ENV_IMAGETAG -# ) - -# # Convert USE_LOCAL_BUILD to Boolean -# $USE_LOCAL_BUILD = if ($USE_LOCAL_BUILD -match "^(?i:true)$") { $true } else { $false } - -# if ([string]::IsNullOrEmpty($AZURE_ENV_IMAGETAG)) { -# $AZURE_ENV_IMAGETAG = "latest_fdp" -# } - -# Validate required parameters -# if (-not $AZURE_SUBSCRIPTION_ID -or -not $ENV_NAME -or -not $AZURE_LOCATION -or -not $AZURE_RESOURCE_GROUP) { -# Write-Error "Missing required arguments. Usage: docker-build.ps1 " -# exit 1 -# } - -# Exit early if local build is not requested -# if ($USE_LOCAL_BUILD -eq $false) { -# Write-Output "Local Build not enabled. Using prebuilt image." -# exit 0 -# } - # Get all environment values $envValues = azd env get-values --output json | ConvertFrom-Json @@ -76,10 +47,10 @@ Write-Host "AZURE_ENV_IMAGETAG = $AZURE_ENV_IMAGETAG" Write-Host "WEB_APP_NAME = $WEB_APP_NAME" Write-Host "API_APP_NAME = $API_APP_NAME" -Write-Output "Starting build process." +Write-Output "`nStarting build process..." # STEP 1: Ensure user is logged into Azure -Write-Host "Checking Azure login status..." +Write-Host "`nChecking Azure login status..." $account = az account show 2>$null | ConvertFrom-Json if (-not $account) { @@ -104,14 +75,14 @@ if ($LASTEXITCODE -ne 0) { $ScriptDir = $PSScriptRoot # STEP 4: Deploy container registry -Write-Host "Deploying container registry" +Write-Host "`nDeploying container registry" $TemplateFile = Join-Path $ScriptDir "..\deploy_container_registry.bicep" | Resolve-Path $OUTPUTS = az deployment group create --resource-group $AZURE_RESOURCE_GROUP --template-file $TemplateFile --parameters environmentName=$ENV_NAME --query "properties.outputs" --output json | ConvertFrom-Json # Extract ACR name and endpoint $ACR_NAME = $OUTPUTS.createdAcrName.value -Write-Host "Extracted ACR Name: $ACR_NAME" +Write-Host "ACR Name: $ACR_NAME" # STEP 5: Login to Azure Container Registry Write-Host "Logging into Azure Container Registry: $ACR_NAME" @@ -160,7 +131,7 @@ function Build-And-Push-Image { Build-And-Push-Image "km-api" $ApiAppDockerfilePath $ApiAppContextPath $AZURE_ENV_IMAGETAG Build-And-Push-Image "km-app" $WebAppDockerfilePath $WebAppContextPath $AZURE_ENV_IMAGETAG -Write-Host "`nAll Docker images built and pushed successfully with tag: $AZURE_ENV_IMAGETAG" +Write-Host "`nAll Docker images built and pushed successfully with tag: $AZURE_ENV_IMAGETAG`n" # STEP 9: Define Function to Update Web App settings to use Managed Identity for ACR pull function Update-WebApp-Settings { @@ -175,7 +146,7 @@ function Update-WebApp-Settings { Write-Error "Error: Web App configuration not found for $WebAppName" exit 1 } - az resource update --ids $webAppConfig --set properties.acrUseManagedIdentityCreds=True --output none + az resource update --ids $webAppConfig --set properties.acrUseManagedIdentityCreds=True --output none --only-show-errors if ($LASTEXITCODE -ne 0) { Write-Error "Failed to update Web App settings for $WebAppName" exit 1 @@ -195,17 +166,25 @@ function Update-WebApp-Image { [string]$Image ) - Write-Host "Updating Web App $WebAppName to use image: $Image" - az webapp config container set --name $WebAppName --resource-group $ResourceGroup --container-image-name $Image + Write-Host "`nUpdating Web App $WebAppName to use image: $Image" + az webapp config container set --name $WebAppName --resource-group $ResourceGroup --container-image-name $Image --only-show-errors if ($LASTEXITCODE -ne 0) { Write-Error "Failed to update Web App $WebAppName to use image: $Image" exit 1 } Write-Host "Web App $WebAppName updated successfully to use image: $Image" + + Write-Host "`nRestarting Web App $WebAppName to apply changes" + az webapp restart --name $WebAppName --resource-group $ResourceGroup --output none --only-show-errors + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to restart Web App $WebAppName" + exit 1 + } + Write-Host "Web App $WebAppName restarted successfully" } # STEP 12: Update Web Apps to use new images Update-WebApp-Image -WebAppName $WEB_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP -Image "$ACR_NAME.azurecr.io/km-app:$AZURE_ENV_IMAGETAG" Update-WebApp-Image -WebAppName $API_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP -Image "$ACR_NAME.azurecr.io/km-api:$AZURE_ENV_IMAGETAG" -Write-Host "Web Apps updated successfully to use new images" \ No newline at end of file +Write-Host "`nWeb Apps updated successfully to use new images" \ No newline at end of file diff --git a/infra/scripts/docker-build.sh b/infra/scripts/docker-build.sh index abd4b2d2c..f6d429cef 100644 --- a/infra/scripts/docker-build.sh +++ b/infra/scripts/docker-build.sh @@ -2,12 +2,6 @@ set -e -# AZURE_SUBSCRIPTION_ID="$1" -# ENV_NAME="$2" -# AZURE_RESOURCE_GROUP="$4" -# USE_LOCAL_BUILD="$5" -# AZURE_ENV_IMAGETAG="$6" - get_azd_env_value_or_default() { local key="$1" local default="$2" @@ -26,6 +20,7 @@ get_azd_env_value_or_default() { echo "$value" } + # Required env variables AZURE_SUBSCRIPTION_ID=$(get_azd_env_value_or_default "AZURE_SUBSCRIPTION_ID" "" true) ENV_NAME=$(get_azd_env_value_or_default "AZURE_ENV_NAME" "" true) @@ -44,24 +39,10 @@ echo "AZURE_ENV_IMAGETAG = $AZURE_ENV_IMAGETAG" echo "WEB_APP_NAME = $WEB_APP_NAME" echo "API_APP_NAME = $API_APP_NAME" -# Validate required parameters -# if [[ -z "$AZURE_SUBSCRIPTION_ID" || -z "$ENV_NAME" || -z "$AZURE_LOCATION" || -z "$AZURE_RESOURCE_GROUP" ]]; then -# echo "Missing required arguments. Usage: docker-build.sh " -# exit 1 -# fi - # Ensure jq is installed -which jq || { echo "jq is not installed"; exit 1; } - -# Exit early if local build is not requested -# if [[ "${USE_LOCAL_BUILD,,}" != "true" ]]; then -# echo "Local Build not enabled. Using prebuilt image." -# exit 0 -# fi +which jq || { echo -e "\njq is not installed"; exit 1; } -# AZURE_ENV_IMAGETAG=${AZURE_ENV_IMAGETAG:-latest} - -echo "Starting build process." +echo -e "\nStarting build process..." # STEP 1: Ensure user is logged into Azure if ! az account show > /dev/null 2>&1; then @@ -87,7 +68,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # STEP 4: Deploy container registry TEMPLATE_FILE="$SCRIPT_DIR/../deploy_container_registry.bicep" -echo "Deploying container registry" +echo -e "\nDeploying container registry" OUTPUTS=$(az deployment group create \ --resource-group "$AZURE_RESOURCE_GROUP" \ --template-file "$TEMPLATE_FILE" \ @@ -97,7 +78,7 @@ OUTPUTS=$(az deployment group create \ ACR_NAME=$(echo "$OUTPUTS" | jq -r '.createdAcrName.value') -echo "Extracted ACR Name: $ACR_NAME" +echo "ACR Name: $ACR_NAME" # STEP 5: Login to Azure Container Registry echo "Logging into Azure Container Registry: $ACR_NAME" @@ -143,7 +124,7 @@ build_and_push_image() { build_and_push_image "km-api" "$APIAPP_DOCKERFILE_PATH" "$APIAPP_CONTEXT_PATH" "$AZURE_ENV_IMAGETAG" build_and_push_image "km-app" "$WEBAPP_DOCKERFILE_PATH" "$WEBAPP_CONTEXT_PATH" "$AZURE_ENV_IMAGETAG" -echo -e "\nAll Docker images built and pushed successfully with tag: $AZURE_ENV_IMAGETAG" +echo -e "\nAll Docker images built and pushed successfully with tag: $AZURE_ENV_IMAGETAG\n" # STEP 9: Function to Update Web App settings to use Managed Identity for ACR pull update_web_app_settings() { @@ -156,7 +137,7 @@ update_web_app_settings() { echo "Error: Web App configuration not found for $webAppName" exit 1 fi - az resource update --ids "$webAppConfig" --set properties.acrUseManagedIdentityCreds=True --output none + az resource update --ids "$webAppConfig" --set properties.acrUseManagedIdentityCreds=True --output none --only-show-errors if [[ $? -ne 0 ]]; then echo "Failed to update Web App settings for $webAppName" exit 1 @@ -174,18 +155,25 @@ update_web_app_image() { local resourceGroup="$2" local image="$3" - echo "Updating Web App $webAppName to use new image tag: $image" - az webapp config container set --name "$webAppName" --resource-group "$resourceGroup" --container-image-name "$image" + echo -e "\nUpdating Web App $webAppName to use new image tag: $image" + az webapp config container set --name "$webAppName" --resource-group "$resourceGroup" --container-image-name "$image" --only-show-errors if [[ $? -ne 0 ]]; then echo "Failed to update Web App $webAppName to use new image: $image" exit 1 fi echo "Web App $webAppName updated successfully to use new image: $image" + echo -e "\nRestarting Web App $webAppName to apply changes" + az webapp restart --name "$webAppName" --resource-group "$resourceGroup" --output none --only-show-errors + if [[ $? -ne 0 ]]; then + echo "Failed to restart Web App $webAppName" + exit 1 + fi + echo "Web App $webAppName restarted successfully" } # STEP 12: Update Web Apps to use new images update_web_app_image "$WEB_APP_NAME" "$AZURE_RESOURCE_GROUP" "$ACR_NAME.azurecr.io/km-app:$AZURE_ENV_IMAGETAG" update_web_app_image "$API_APP_NAME" "$AZURE_RESOURCE_GROUP" "$ACR_NAME.azurecr.io/km-api:$AZURE_ENV_IMAGETAG" -echo "Web Apps updated successfully to use new images" +echo -e "\nWeb Apps updated successfully to use new images" From 0cacaf13811bdbd5ebd4ca87599251f22cb1788b Mon Sep 17 00:00:00 2001 From: Harsh-Microsoft Date: Wed, 9 Jul 2025 18:15:11 +0530 Subject: [PATCH 5/7] refactor: update test automation workflow to remove unnecessary triggers --- .github/workflows/test-automation.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/test-automation.yml b/.github/workflows/test-automation.yml index 528d5ad07..8d7044bcb 100644 --- a/.github/workflows/test-automation.yml +++ b/.github/workflows/test-automation.yml @@ -1,15 +1,6 @@ name: Test Automation KMGeneric on: - push: - branches: - - main - - dev - paths: - - 'tests/e2e-test/**' - - workflow_dispatch: - # NEW: Add workflow_call to make it reusable workflow_call: inputs: KMGENERIC_URL: From b8f90011cdd9d240e2b78866c3d1033a272842ca Mon Sep 17 00:00:00 2001 From: Harsh-Microsoft Date: Wed, 9 Jul 2025 18:42:30 +0530 Subject: [PATCH 6/7] add a comment to address delay to reflect changes in docker-build scripts --- infra/scripts/docker-build.ps1 | 4 +++- infra/scripts/docker-build.sh | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/infra/scripts/docker-build.ps1 b/infra/scripts/docker-build.ps1 index 0509a46cd..b745920a0 100644 --- a/infra/scripts/docker-build.ps1 +++ b/infra/scripts/docker-build.ps1 @@ -187,4 +187,6 @@ function Update-WebApp-Image { Update-WebApp-Image -WebAppName $WEB_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP -Image "$ACR_NAME.azurecr.io/km-app:$AZURE_ENV_IMAGETAG" Update-WebApp-Image -WebAppName $API_APP_NAME -ResourceGroup $AZURE_RESOURCE_GROUP -Image "$ACR_NAME.azurecr.io/km-api:$AZURE_ENV_IMAGETAG" -Write-Host "`nWeb Apps updated successfully to use new images" \ No newline at end of file +Write-Host "`nWeb Apps updated successfully to use new images" + +Write-Host "`nIt might take a few minutes for the changes to take effect.`n" \ No newline at end of file diff --git a/infra/scripts/docker-build.sh b/infra/scripts/docker-build.sh index f6d429cef..c149fa1e7 100644 --- a/infra/scripts/docker-build.sh +++ b/infra/scripts/docker-build.sh @@ -177,3 +177,5 @@ update_web_app_image "$WEB_APP_NAME" "$AZURE_RESOURCE_GROUP" "$ACR_NAME.azurecr. update_web_app_image "$API_APP_NAME" "$AZURE_RESOURCE_GROUP" "$ACR_NAME.azurecr.io/km-api:$AZURE_ENV_IMAGETAG" echo -e "\nWeb Apps updated successfully to use new images" + +echo -e "\nIt might take a few minutes for the changes to take effect.\n" From 3c0fefc77707dfd50734f21588f85c6bb3a12781 Mon Sep 17 00:00:00 2001 From: Pavan-Microsoft Date: Tue, 12 Aug 2025 10:21:59 +0530 Subject: [PATCH 7/7] correct env name as per required. --- infra/deploy_container_registry.bicep | 4 +--- infra/scripts/docker-build.ps1 | 6 +++--- infra/scripts/docker-build.sh | 11 ++++------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/infra/deploy_container_registry.bicep b/infra/deploy_container_registry.bicep index e942d1abb..85c2e2b34 100644 --- a/infra/deploy_container_registry.bicep +++ b/infra/deploy_container_registry.bicep @@ -1,10 +1,8 @@ targetScope = 'resourceGroup' -param environmentName string +param solutionName string param solutionLocation string = resourceGroup().location -var uniqueId = toLower(uniqueString(subscription().id, environmentName, solutionLocation)) -var solutionName = 'km${padLeft(take(uniqueId, 12), 12, '0')}' var abbrs = loadJsonContent('./abbreviations.json') var containerRegistryName = '${abbrs.containers.containerRegistry}${solutionName}' var containerRegistryNameCleaned = replace(containerRegistryName, '-', '') diff --git a/infra/scripts/docker-build.ps1 b/infra/scripts/docker-build.ps1 index b745920a0..35e0aaa62 100644 --- a/infra/scripts/docker-build.ps1 +++ b/infra/scripts/docker-build.ps1 @@ -30,7 +30,7 @@ function Get-AzdEnvValueOrDefault { # Read the required details from Bicep deployment output $AZURE_SUBSCRIPTION_ID = Get-AzdEnvValueOrDefault -KeyName "AZURE_SUBSCRIPTION_ID" -Required $true -$ENV_NAME = Get-AzdEnvValueOrDefault -KeyName "AZURE_ENV_NAME" -Required $true +$SOLUTION_NAME = Get-AzdEnvValueOrDefault -KeyName "SOLUTION_NAME" -Required $true $WEB_APP_IDENTITY_PRINCIPAL_ID = Get-AzdEnvValueOrDefault -KeyName "FRONTEND_MANAGED_IDENTITY_PRINCIPAL_ID" -Required $true $API_APP_IDENTITY_PRINCIPAL_ID = Get-AzdEnvValueOrDefault -KeyName "BACKEND_MANAGED_IDENTITY_PRINCIPAL_ID" -Required $true $AZURE_RESOURCE_GROUP = Get-AzdEnvValueOrDefault -KeyName "AZURE_RESOURCE_GROUP" -Required $true @@ -41,7 +41,7 @@ $API_APP_NAME=Get-AzdEnvValueOrDefault -KeyName "BACKEND_APP_NAME" -Required $tr # Export the variables for later use Write-Host "Using the following parameters:" Write-Host "AZURE_SUBSCRIPTION_ID = $AZURE_SUBSCRIPTION_ID" -Write-Host "ENV_NAME = $ENV_NAME" +Write-Host "SOLUTION_NAME = $SOLUTION_NAME" Write-Host "AZURE_RESOURCE_GROUP = $AZURE_RESOURCE_GROUP" Write-Host "AZURE_ENV_IMAGETAG = $AZURE_ENV_IMAGETAG" Write-Host "WEB_APP_NAME = $WEB_APP_NAME" @@ -77,7 +77,7 @@ $ScriptDir = $PSScriptRoot # STEP 4: Deploy container registry Write-Host "`nDeploying container registry" $TemplateFile = Join-Path $ScriptDir "..\deploy_container_registry.bicep" | Resolve-Path -$OUTPUTS = az deployment group create --resource-group $AZURE_RESOURCE_GROUP --template-file $TemplateFile --parameters environmentName=$ENV_NAME --query "properties.outputs" --output json | ConvertFrom-Json +$OUTPUTS = az deployment group create --resource-group $AZURE_RESOURCE_GROUP --template-file $TemplateFile --parameters solutionName=$SOLUTION_NAME acrPullPrincipalIds="['$WEB_APP_IDENTITY_PRINCIPAL_ID', '$API_APP_IDENTITY_PRINCIPAL_ID']" --query "properties.outputs" --output json | ConvertFrom-Json # Extract ACR name and endpoint $ACR_NAME = $OUTPUTS.createdAcrName.value diff --git a/infra/scripts/docker-build.sh b/infra/scripts/docker-build.sh index c149fa1e7..83b2fb80d 100644 --- a/infra/scripts/docker-build.sh +++ b/infra/scripts/docker-build.sh @@ -23,7 +23,7 @@ get_azd_env_value_or_default() { # Required env variables AZURE_SUBSCRIPTION_ID=$(get_azd_env_value_or_default "AZURE_SUBSCRIPTION_ID" "" true) -ENV_NAME=$(get_azd_env_value_or_default "AZURE_ENV_NAME" "" true) +SOLUTION_NAME=$(get_azd_env_value_or_default "SOLUTION_NAME" "" true) WEB_APP_IDENTITY_PRINCIPAL_ID=$(get_azd_env_value_or_default "FRONTEND_MANAGED_IDENTITY_PRINCIPAL_ID" "" true) API_APP_IDENTITY_PRINCIPAL_ID=$(get_azd_env_value_or_default "BACKEND_MANAGED_IDENTITY_PRINCIPAL_ID" "" true) AZURE_RESOURCE_GROUP=$(get_azd_env_value_or_default "AZURE_RESOURCE_GROUP" "" true) @@ -33,15 +33,12 @@ API_APP_NAME=$(get_azd_env_value_or_default "BACKEND_APP_NAME" "" true) echo "Using the following parameters:" echo "AZURE_SUBSCRIPTION_ID = $AZURE_SUBSCRIPTION_ID" -echo "ENV_NAME = $ENV_NAME" +echo "SOLUTION_NAME = $SOLUTION_NAME" echo "AZURE_RESOURCE_GROUP = $AZURE_RESOURCE_GROUP" echo "AZURE_ENV_IMAGETAG = $AZURE_ENV_IMAGETAG" echo "WEB_APP_NAME = $WEB_APP_NAME" echo "API_APP_NAME = $API_APP_NAME" -# Ensure jq is installed -which jq || { echo -e "\njq is not installed"; exit 1; } - echo -e "\nStarting build process..." # STEP 1: Ensure user is logged into Azure @@ -72,11 +69,11 @@ echo -e "\nDeploying container registry" OUTPUTS=$(az deployment group create \ --resource-group "$AZURE_RESOURCE_GROUP" \ --template-file "$TEMPLATE_FILE" \ - --parameters environmentName="$ENV_NAME" acrPullPrincipalIds="['$WEB_APP_IDENTITY_PRINCIPAL_ID', '$API_APP_IDENTITY_PRINCIPAL_ID']" \ + --parameters solutionName="$SOLUTION_NAME" acrPullPrincipalIds="['$WEB_APP_IDENTITY_PRINCIPAL_ID', '$API_APP_IDENTITY_PRINCIPAL_ID']" \ --query "properties.outputs" \ --output json) -ACR_NAME=$(echo "$OUTPUTS" | jq -r '.createdAcrName.value') +ACR_NAME=$(echo "$OUTPUTS" | grep -o '"createdAcrName"[^}]*"value"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"value"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') echo "ACR Name: $ACR_NAME"