1+ # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
2+ name : byoc-research-assistant
3+
4+ requiredVersions :
5+ azd : " >= 1.18.0"
6+
7+ metadata :
8+ 9+ description : Research Assistant with local container builds
10+
11+ hooks :
12+ # Pre-package hook to set container registry variables
13+ prepackage :
14+ windows :
15+ run : |
16+ Write-Host "Setting up container registry variables..."
17+
18+ # Get the ACR name from the deployed infrastructure
19+ $acrName = azd env get-values --output json | ConvertFrom-Json | Select-Object -ExpandProperty "AZURE_CONTAINER_REGISTRY_NAME" -ErrorAction SilentlyContinue
20+
21+ if ($acrName) {
22+ Write-Host "Using deployed ACR: $acrName"
23+ azd env set AZURE_CONTAINER_REGISTRY_ENDPOINT "$acrName.azurecr.io"
24+ azd env set CONTAINER_REGISTRY_HOSTNAME "$acrName.azurecr.io"
25+ }
26+ shell : pwsh
27+ continueOnError : true
28+ posix :
29+ run : |
30+ echo "Setting up container registry variables..."
31+
32+ # Get the ACR name from the deployed infrastructure
33+ ACR_NAME=$(azd env get-values --output json | jq -r '.AZURE_CONTAINER_REGISTRY_NAME // empty')
34+
35+ if [ ! -z "$ACR_NAME" ]; then
36+ echo "Using deployed ACR: $ACR_NAME"
37+ azd env set AZURE_CONTAINER_REGISTRY_ENDPOINT "$ACR_NAME.azurecr.io"
38+ azd env set CONTAINER_REGISTRY_HOSTNAME "$ACR_NAME.azurecr.io"
39+ fi
40+ shell : sh
41+ continueOnError : true
42+
43+ # Pre-deploy hook to build and push containers
44+ predeploy :
45+ windows :
46+ run : |
47+ Write-Host "`n========================================"
48+ Write-Host " Research Assistant Container Deployer"
49+ Write-Host " Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
50+ Write-Host "========================================`n"
51+
52+ # Generate unique tag
53+ $imageTag = "v$(Get-Date -Format 'yyyyMMddHHmmss')"
54+ azd env set IMAGE_TAG $imageTag
55+
56+ # Get environment variables from azd - auto-discover if not set
57+ $resourceGroup = azd env get-value AZURE_RESOURCE_GROUP
58+ if (-not $resourceGroup) {
59+ Write-Host "🔍 Auto-discovering resource group..."
60+ $resourceGroup = az group list --query "[?starts_with(name, 'rg-')].name" -o tsv | Select-Object -First 1
61+ if ($resourceGroup) {
62+ azd env set AZURE_RESOURCE_GROUP $resourceGroup
63+ Write-Host " Found: $resourceGroup"
64+ } else {
65+ Write-Host "❌ No resource group found. Run 'azd provision' first."
66+ exit 1
67+ }
68+ }
69+
70+ $acrName = azd env get-value AZURE_CONTAINER_REGISTRY_NAME
71+ if (-not $acrName) {
72+ Write-Host "🔍 Auto-discovering ACR in resource group..."
73+ $acrName = az acr list --resource-group $resourceGroup --query "[0].name" -o tsv
74+ if ($acrName) {
75+ azd env set AZURE_CONTAINER_REGISTRY_NAME $acrName
76+ Write-Host " Found: $acrName"
77+ } else {
78+ Write-Host "❌ No ACR found in resource group. Run 'azd provision' first."
79+ exit 1
80+ }
81+ }
82+
83+ $webAppName = azd env get-value WEB_APP_NAME
84+ if (-not $webAppName) {
85+ Write-Host "🔍 Auto-discovering Web App in resource group..."
86+ $webAppName = az webapp list --resource-group $resourceGroup --query "[0].name" -o tsv
87+ if ($webAppName) {
88+ azd env set WEB_APP_NAME $webAppName
89+ Write-Host " Found: $webAppName"
90+ } else {
91+ Write-Host "❌ No Web App found in resource group. Run 'azd provision' first."
92+ exit 1
93+ }
94+ }
95+
96+ $imageName = "byoaia-app"
97+
98+ Write-Host "📋 Configuration:"
99+ Write-Host " ACR Name: $acrName"
100+ Write-Host " Resource Group: $resourceGroup"
101+ Write-Host " Web App: $webAppName"
102+ Write-Host " Image: ${imageName}:${imageTag}"
103+
104+ # Login to ACR
105+ Write-Host "`n🔐 Logging into ACR..."
106+ az acr login --name $acrName
107+
108+ if ($LASTEXITCODE -ne 0) {
109+ Write-Host "❌ Failed to login to ACR"
110+ exit 1
111+ }
112+
113+ # Build and push the container image
114+ Write-Host "`n🏗️ Building container image..."
115+ $fullImageName = "$acrName.azurecr.io/${imageName}:${imageTag}"
116+ Write-Host " Command: docker build -f ./src/WebApp.Dockerfile -t $fullImageName ./src"
117+ docker build --progress=plain -f "./src/WebApp.Dockerfile" -t $fullImageName "./src"
118+
119+ if ($LASTEXITCODE -ne 0) {
120+ Write-Host "❌ Failed to build container image"
121+ exit 1
122+ }
123+
124+ Write-Host "`n📤 Pushing container image to ACR..."
125+ docker push $fullImageName
126+
127+ if ($LASTEXITCODE -ne 0) {
128+ Write-Host "❌ Failed to push container image"
129+ exit 1
130+ }
131+
132+ # Update environment variables
133+ Write-Host "`n🔧 Updating azd environment variables..."
134+ azd env set CONTAINER_REGISTRY_HOSTNAME "$acrName.azurecr.io"
135+ azd env set CONTAINER_IMAGE_NAME $imageName
136+
137+ # Configure web app ACR authentication using managed identity
138+ Write-Host "`n🔑 Configuring ACR authentication for web app..."
139+ $webappIdentity = az webapp identity show --name $webAppName --resource-group $resourceGroup --query principalId --output tsv
140+
141+ if (-not $webappIdentity -or $webappIdentity -eq "null") {
142+ Write-Host "🔄 Enabling managed identity for web app..."
143+ $webappIdentity = az webapp identity assign --name $webAppName --resource-group $resourceGroup --query principalId --output tsv
144+ }
145+
146+ Write-Host " Web app identity: $webappIdentity"
147+
148+ # Assign AcrPull role to web app managed identity
149+ Write-Host "`n🔐 Assigning AcrPull role to web app..."
150+ $acrResourceId = az acr show --name $acrName --resource-group $resourceGroup --query id --output tsv
151+ az role assignment create --assignee $webappIdentity --role AcrPull --scope $acrResourceId 2>$null
152+ if ($LASTEXITCODE -ne 0) {
153+ Write-Host "⚠️ Role assignment may already exist (this is OK)"
154+ }
155+
156+ # Configure web app to use ACR with managed identity
157+ Write-Host "`n🔧 Configuring web app container settings..."
158+ az webapp config appsettings set --name $webAppName --resource-group $resourceGroup --settings `
159+ DOCKER_REGISTRY_SERVER_URL="https://$acrName.azurecr.io" `
160+ DOCKER_ENABLE_CI=true `
161+ WEBSITES_ENABLE_APP_SERVICE_STORAGE=false
162+
163+ # Configure web app to use managed identity for ACR authentication
164+ Write-Host "`n🔐 Enabling ACR managed identity authentication..."
165+ az webapp config set --name $webAppName --resource-group $resourceGroup --acr-use-identity true
166+
167+ # Update web app to use the new container image
168+ Write-Host "`n🚀 Updating web app container image..."
169+ $dockerImage = "DOCKER|$fullImageName"
170+
171+ # Use cmd to avoid PowerShell pipe interpretation issues
172+ $cmd = "az webapp config set --name `"$webAppName`" --resource-group `"$resourceGroup`" --linux-fx-version `"$dockerImage`""
173+ cmd /c $cmd
174+
175+ if ($LASTEXITCODE -ne 0) {
176+ Write-Host "❌ Failed to update web app configuration"
177+ exit 1
178+ }
179+
180+ # Restart the web app to ensure it picks up the new configuration
181+ Write-Host "`n🔄 Restarting web app..."
182+ az webapp restart --name $webAppName --resource-group $resourceGroup
183+
184+ Write-Host "`n========================================"
185+ Write-Host "✅ DEPLOYMENT COMPLETED SUCCESSFULLY!"
186+ Write-Host "========================================"
187+ Write-Host "🌐 Web app URL: https://$webAppName.azurewebsites.net"
188+ Write-Host "📦 Container image: $fullImageName"
189+ Write-Host "⏱️ Deployed at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
190+ Write-Host ""
191+ Write-Host "⏳ The web app may take 2-3 minutes to start with the new container..."
192+ Write-Host " Monitor logs with:"
193+ Write-Host " az webapp log tail --name $webAppName --resource-group $resourceGroup"
194+ Write-Host "========================================`n"
195+ shell : pwsh
196+ continueOnError : false
197+ posix :
198+ run : |
199+ echo ""
200+ echo "========================================"
201+ echo " Research Assistant Container Deployer"
202+ echo " Time: $(date '+%Y-%m-%d %H:%M:%S')"
203+ echo "========================================"
204+ echo ""
205+
206+ # Generate unique tag
207+ IMAGE_TAG="v$(date +%Y%m%d%H%M%S)"
208+ azd env set IMAGE_TAG $IMAGE_TAG
209+
210+ # Get environment variables from azd - auto-discover if not set
211+ RESOURCE_GROUP=$(azd env get-value AZURE_RESOURCE_GROUP)
212+ if [ -z "$RESOURCE_GROUP" ]; then
213+ echo "🔍 Auto-discovering resource group..."
214+ RESOURCE_GROUP=$(az group list --query "[?starts_with(name, 'rg-')].name" -o tsv | head -n 1)
215+ if [ ! -z "$RESOURCE_GROUP" ]; then
216+ azd env set AZURE_RESOURCE_GROUP $RESOURCE_GROUP
217+ echo " Found: $RESOURCE_GROUP"
218+ else
219+ echo "❌ No resource group found. Run 'azd provision' first."
220+ exit 1
221+ fi
222+ fi
223+
224+ ACR_NAME=$(azd env get-value AZURE_CONTAINER_REGISTRY_NAME)
225+ if [ -z "$ACR_NAME" ]; then
226+ echo "🔍 Auto-discovering ACR in resource group..."
227+ ACR_NAME=$(az acr list --resource-group $RESOURCE_GROUP --query "[0].name" -o tsv)
228+ if [ ! -z "$ACR_NAME" ]; then
229+ azd env set AZURE_CONTAINER_REGISTRY_NAME $ACR_NAME
230+ echo " Found: $ACR_NAME"
231+ else
232+ echo "❌ No ACR found in resource group. Run 'azd provision' first."
233+ exit 1
234+ fi
235+ fi
236+
237+ WEB_APP_NAME=$(azd env get-value WEB_APP_NAME)
238+ if [ -z "$WEB_APP_NAME" ]; then
239+ echo "🔍 Auto-discovering Web App in resource group..."
240+ WEB_APP_NAME=$(az webapp list --resource-group $RESOURCE_GROUP --query "[0].name" -o tsv)
241+ if [ ! -z "$WEB_APP_NAME" ]; then
242+ azd env set WEB_APP_NAME $WEB_APP_NAME
243+ echo " Found: $WEB_APP_NAME"
244+ else
245+ echo "❌ No Web App found in resource group. Run 'azd provision' first."
246+ exit 1
247+ fi
248+ fi
249+
250+ IMAGE_NAME="byoaia-app"
251+
252+ echo "📋 Configuration:"
253+ echo " ACR Name: $ACR_NAME"
254+ echo " Resource Group: $RESOURCE_GROUP"
255+ echo " Web App: $WEB_APP_NAME"
256+ echo " Image: $IMAGE_NAME:$IMAGE_TAG"
257+
258+ # Login to ACR
259+ echo ""
260+ echo "🔐 Logging into ACR..."
261+ az acr login --name $ACR_NAME
262+
263+ # Build and push the container image
264+ echo ""
265+ echo "🏗️ Building container image..."
266+ FULL_IMAGE_NAME="$ACR_NAME.azurecr.io/$IMAGE_NAME:$IMAGE_TAG"
267+ echo " Command: docker build -f ./src/WebApp.Dockerfile -t $FULL_IMAGE_NAME ./src"
268+ docker build --progress=plain -f "./src/WebApp.Dockerfile" -t $FULL_IMAGE_NAME "./src"
269+
270+ echo ""
271+ echo "📤 Pushing container image to ACR..."
272+ docker push $FULL_IMAGE_NAME
273+
274+ # Update environment variables
275+ echo ""
276+ echo "🔧 Updating azd environment variables..."
277+ azd env set CONTAINER_REGISTRY_HOSTNAME "$ACR_NAME.azurecr.io"
278+ azd env set CONTAINER_IMAGE_NAME $IMAGE_NAME
279+
280+ # Configure web app ACR authentication using managed identity
281+ echo ""
282+ echo "🔑 Configuring ACR authentication for web app..."
283+ WEBAPP_IDENTITY=$(az webapp identity show --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --query principalId --output tsv)
284+
285+ if [ -z "$WEBAPP_IDENTITY" ] || [ "$WEBAPP_IDENTITY" = "null" ]; then
286+ echo "🔄 Enabling managed identity for web app..."
287+ WEBAPP_IDENTITY=$(az webapp identity assign --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --query principalId --output tsv)
288+ fi
289+
290+ echo " Web app identity: $WEBAPP_IDENTITY"
291+
292+ # Assign AcrPull role to web app managed identity
293+ echo ""
294+ echo "🔐 Assigning AcrPull role to web app..."
295+ ACR_RESOURCE_ID=$(az acr show --name $ACR_NAME --resource-group $RESOURCE_GROUP --query id --output tsv)
296+ az role assignment create --assignee $WEBAPP_IDENTITY --role AcrPull --scope $ACR_RESOURCE_ID || echo "⚠️ Role assignment may already exist (this is OK)"
297+
298+ # Configure web app to use ACR with managed identity
299+ echo ""
300+ echo "🔧 Configuring web app container settings..."
301+ az webapp config appsettings set --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --settings \
302+ DOCKER_REGISTRY_SERVER_URL="https://$ACR_NAME.azurecr.io" \
303+ DOCKER_ENABLE_CI=true \
304+ WEBSITES_ENABLE_APP_SERVICE_STORAGE=false
305+
306+ # Configure web app to use managed identity for ACR authentication
307+ echo ""
308+ echo "🔐 Enabling ACR managed identity authentication..."
309+ az webapp config set --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --acr-use-identity true
310+
311+ # Update web app to use the new container image
312+ echo ""
313+ echo "🚀 Updating web app container image..."
314+ DOCKER_IMAGE="DOCKER|$FULL_IMAGE_NAME"
315+ az webapp config set --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --linux-fx-version "$DOCKER_IMAGE"
316+
317+ # Restart the web app to ensure it picks up the new configuration
318+ echo ""
319+ echo "🔄 Restarting web app..."
320+ az webapp restart --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP
321+
322+ echo ""
323+ echo "========================================"
324+ echo "✅ DEPLOYMENT COMPLETED SUCCESSFULLY!"
325+ echo "========================================"
326+ echo "🌐 Web app URL: https://$WEB_APP_NAME.azurewebsites.net"
327+ echo "📦 Container image: $FULL_IMAGE_NAME"
328+ echo "⏱️ Deployed at: $(date '+%Y-%m-%d %H:%M:%S')"
329+ echo ""
330+ echo "⏳ The web app may take 2-3 minutes to start with the new container..."
331+ echo " Monitor logs with:"
332+ echo " az webapp log tail --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP"
333+ echo "========================================"
334+ shell : sh
335+ continueOnError : false
336+
337+ postprovision :
338+ windows :
339+ run : |
340+ Write-Host "✅ Infrastructure provisioned successfully!"
341+ $webAppUrl = azd env get-value WEB_APP_URL
342+ if ($webAppUrl) {
343+ Write-Host "Web app URL: $webAppUrl"
344+ }
345+ shell : pwsh
346+ continueOnError : true
347+ posix :
348+ run : |
349+ echo "✅ Infrastructure provisioned successfully!"
350+ WEB_APP_URL=$(azd env get-value WEB_APP_URL)
351+ if [ ! -z "$WEB_APP_URL" ]; then
352+ echo "Web app URL: $WEB_APP_URL"
353+ fi
354+ shell : sh
355+ continueOnError : true
356+
357+ postdeploy :
358+ windows :
359+ run : |
360+ Write-Host "✅ All deployment steps completed!"
361+ Write-Host "Container deployment was handled by predeploy hook."
362+ shell : pwsh
363+ continueOnError : true
364+ posix :
365+ run : |
366+ echo "✅ All deployment steps completed!"
367+ echo "Container deployment was handled by predeploy hook."
368+ shell : sh
369+ continueOnError : true
370+
371+ # Infrastructure configuration
372+ infra :
373+ provider : bicep
374+ path : infra
375+ module : main
376+ parameters :
377+ containerRegistryHostname : ${CONTAINER_REGISTRY_HOSTNAME}
378+ containerImageName : ${CONTAINER_IMAGE_NAME}
379+ containerImageTag : ${IMAGE_TAG}
0 commit comments