@@ -294,6 +294,116 @@ resource "azurerm_container_registry_webhook" "webhook" {
294294 ]
295295}
296296
297+ # Standalone Docker Image Build - Always runs to ensure ACR has the required image
298+ resource "null_resource" "docker_image_build" {
299+ # Trigger rebuild when:
300+ # 1. Dockerfile changes
301+ # 2. Application source code changes
302+ # 3. Requirements.txt changes
303+ # 4. ACR or app changes
304+ # 5. Force rebuild on every apply (always_run ensures terraform always executes the provisioner)
305+ triggers = {
306+ dockerfile_hash = local.dockerfile_hash
307+ app_source_hash = local.app_source_hash
308+ requirements_hash = fileexists (" ../src/requirements.txt" ) ? filesha256 (" ../src/requirements.txt" ) : " missing"
309+ acr_id = azurerm_container_registry.acr.id
310+ always_run = timestamp () # Forces provisioner to run on every apply
311+ }
312+
313+ depends_on = [
314+ azurerm_container_registry . acr
315+ ]
316+
317+ provisioner "local-exec" {
318+ command = <<- EOT
319+ Write-Host ""
320+ Write-Host "=========================================="
321+ Write-Host "Building & Pushing Docker Image to ACR"
322+ Write-Host "=========================================="
323+ Write-Host ""
324+
325+ $ErrorActionPreference = "Continue" # Don't stop on warnings
326+ cd ..
327+ $srcPath = "src"
328+
329+ Write-Host "Starting Docker build and push to ACR..."
330+ Write-Host "Registry: ${ local . registry_name } "
331+ Write-Host "Image: zava-chat-app:latest"
332+ Write-Host "Dockerfile: $srcPath/Dockerfile"
333+ Write-Host "Source Path: $srcPath"
334+ Write-Host ""
335+
336+ # Set encoding for Azure CLI
337+ $env:PYTHONIOENCODING = "utf-8"
338+ chcp 65001 > $null
339+
340+ Write-Host "Executing ACR build command..."
341+ Write-Host ""
342+
343+ try {
344+ # Build and push image
345+ az acr build `
346+ --resource-group ${ azurerm_resource_group . rg . name } `
347+ --registry ${ local . registry_name } `
348+ --image zava-chat-app:latest `
349+ --file "$srcPath\Dockerfile" `
350+ "$srcPath" `
351+ --no-logs
352+
353+ if ($LASTEXITCODE -eq 0) {
354+ Write-Host ""
355+ Write-Host "[SUCCESS] Docker image successfully built and pushed to ACR"
356+ Write-Host ""
357+ Write-Host "Image details:"
358+ Write-Host " Registry: ${ local . registry_name } .azurecr.io"
359+ Write-Host " Repository: zava-chat-app"
360+ Write-Host " Tag: latest"
361+ Write-Host ""
362+
363+ # Wait for image to be available
364+ Write-Host "Waiting for image to be available in registry..."
365+ Start-Sleep -Seconds 10
366+
367+ # Verify image exists in ACR
368+ Write-Host "Verifying image in ACR..."
369+ $imgCheck = az acr repository show --name ${ local . registry_name } --image zava-chat-app:latest --query "name" -o tsv 2>$null
370+
371+ if ($LASTEXITCODE -eq 0 -and $imgCheck -eq "zava-chat-app") {
372+ Write-Host "[VERIFIED] Image confirmed in ACR registry"
373+ Write-Host ""
374+ exit 0
375+ } else {
376+ Write-Host "[WARNING] Image verification failed but build succeeded"
377+ Write-Host "This may be a timing issue. Image should be available shortly."
378+ Write-Host ""
379+ exit 0
380+ }
381+ } else {
382+ Write-Host ""
383+ Write-Host "[ERROR] ACR build failed with exit code: $LASTEXITCODE"
384+ Write-Host ""
385+ Write-Host "Troubleshooting steps:"
386+ Write-Host " 1. Check requirements.txt for dependency conflicts"
387+ Write-Host " 2. Verify Dockerfile paths are correct"
388+ Write-Host " 3. Manual build command:"
389+ Write-Host " az acr build --resource-group ${ azurerm_resource_group . rg . name } --registry ${ local . registry_name } --image zava-chat-app:latest --file $srcPath\Dockerfile $srcPath"
390+ Write-Host ""
391+ exit 1
392+ }
393+ } catch {
394+ Write-Host ""
395+ Write-Host "[ERROR] Exception during build: $_"
396+ Write-Host "Manual build command:"
397+ Write-Host "az acr build --resource-group ${ azurerm_resource_group . rg . name } --registry ${ local . registry_name } --image zava-chat-app:latest --file $srcPath\Dockerfile $srcPath"
398+ Write-Host ""
399+ exit 1
400+ }
401+ EOT
402+ interpreter = [" PowerShell" , " -Command" ]
403+ working_dir = path. module
404+ }
405+ }
406+
297407resource "azurerm_service_plan" "appserviceplan" {
298408 name = local. app_service_plan
299409 resource_group_name = azurerm_resource_group. rg . name
@@ -373,7 +483,8 @@ resource "azurerm_linux_web_app" "app" {
373483
374484 depends_on = [
375485 azurerm_container_registry . acr ,
376- null_resource. ai_model_deployments
486+ null_resource. ai_model_deployments ,
487+ null_resource. docker_image_build
377488 ]
378489}
379490
@@ -1677,68 +1788,9 @@ resource "null_resource" "deploy_multi_agents" {
16771788 }
16781789
16791790 Write-Host ""
1680- Write-Host "Triggering container rebuild with agent configuration..."
1681- cd ..
1682- $srcPath = "src"
1683- [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
1684- $env:PYTHONIOENCODING = "utf-8"
1685-
1686- Write-Host "Building container image in Azure Container Registry..."
1687- Write-Host "This may take 2-3 minutes..."
1688-
1689- # Build with logs enabled to see progress
1690- $buildSuccess = $false
1691- try {
1692- az acr build `
1693- --resource-group ${ azurerm_resource_group . rg . name } `
1694- --registry ${ local . registry_name } `
1695- --image zava-chat-app:latest `
1696- --file "$srcPath\Dockerfile" `
1697- "$srcPath"
1698-
1699- if ($LASTEXITCODE -eq 0) {
1700- Write-Host "[SUCCESS] ACR build completed successfully"
1701- $buildSuccess = $true
1702- } else {
1703- Write-Host "[ERROR] ACR build failed with exit code: $LASTEXITCODE"
1704- }
1705- } catch {
1706- Write-Host "[ERROR] ACR build exception: $_"
1707- }
1708-
1709- # Verify image exists
1710- Write-Host ""
1711- Write-Host "Verifying image in ACR..."
1712- $imageExists = $false
1713- for ($attempt = 1; $attempt -le 3; $attempt++) {
1714- try {
1715- $imgCheck = az acr repository show --name ${ local . registry_name } --image zava-chat-app:latest --query "name" -o tsv 2>&1
1716- if ($LASTEXITCODE -eq 0 -and $imgCheck -eq "zava-chat-app") {
1717- Write-Host "[OK] Image verified in ACR: zava-chat-app:latest"
1718- $imageExists = $true
1719- break
1720- }
1721- } catch { }
1722- if ($attempt -lt 3) {
1723- Write-Host "Image not found yet, waiting 10s... (attempt $attempt/3)"
1724- Start-Sleep -Seconds 10
1725- }
1726- }
1727-
1728- if (-not $imageExists) {
1729- Write-Host "[CRITICAL] Image not found in ACR after build. Web App cannot start."
1730- Write-Host "Please check ACR build logs in Azure Portal."
1731- exit 0 # Non-blocking but logged
1732- }
1733-
1734- # Web App will automatically pull image using managed identity (AcrPull role)
1735- # No need to set ACR credentials - managed identity handles authentication
1736- Write-Host ""
1737- Write-Host "[INFO] Web App configured to use managed identity for ACR access"
1738- Write-Host "[INFO] Webhook will trigger automatic deployment on image push"
1739-
1791+ Write-Host "Docker image already built by standalone resource."
17401792 Write-Host ""
1741- Write-Host "Restarting Web App to pull new image ..."
1793+ Write-Host "Restarting Web App to ensure latest configuration ..."
17421794 az webapp restart --resource-group ${ azurerm_resource_group . rg . name } --name ${ local . web_app_name } | Out-Null
17431795 Write-Host "[OK] Web App restarted"
17441796 Write-Host ""
0 commit comments