Skip to content

Commit de9ddab

Browse files
committed
feat: add productionRevisionName parameter and update traffic management logic for API and UI
1 parent bcfb23f commit de9ddab

File tree

5 files changed

+121
-18
lines changed

5 files changed

+121
-18
lines changed

.azdo/pipelines/azure-dev.yml

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ variables:
3838
azureResourceGroup: rg-fake-survey-generator
3939
azureResourceManagerConnection: "Azure Service Connection"
4040
azureLocation: "South Africa North"
41-
apiActiveLabel: "blue"
42-
apiPromotePreview: "false"
43-
uiActiveLabel: "blue"
44-
uiPromotePreview: "false"
4541
NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
4642

4743
stages:
@@ -258,6 +254,82 @@ stages:
258254
AZURE_LOCATION: $(azureLocation)
259255
AZURE_RESOURCE_GROUP: $(azureResourceGroup)
260256

257+
- task: AzureCLI@2
258+
displayName: Resolve Active/Preview Labels + Production Revisions
259+
inputs:
260+
azureSubscription: $(azureResourceManagerConnection)
261+
scriptType: bash
262+
scriptLocation: inlineScript
263+
inlineScript: |
264+
set -euo pipefail
265+
266+
API_APP_NAME=$(azd env get-values | sed -n 's/^SERVICE_API_NAME="\(.*\)"/\1/p')
267+
UI_APP_NAME=$(azd env get-values | sed -n 's/^SERVICE_UI_NAME="\(.*\)"/\1/p')
268+
269+
API_ACTIVE_LABEL="blue"
270+
UI_ACTIVE_LABEL="blue"
271+
API_PREVIEW_LABEL="green"
272+
UI_PREVIEW_LABEL="green"
273+
API_REVISION=""
274+
UI_REVISION=""
275+
276+
if [[ -n "${API_APP_NAME}" ]]; then
277+
API_ACTIVE_LABEL=$(az containerapp ingress traffic show \
278+
--resource-group "${AZURE_RESOURCE_GROUP}" \
279+
--name "${API_APP_NAME}" \
280+
--query "[?weight==\`100\` && label!=null].label | [0]" \
281+
-o tsv 2>/dev/null || true)
282+
283+
if [[ -z "${API_ACTIVE_LABEL}" ]]; then
284+
API_ACTIVE_LABEL="blue"
285+
fi
286+
287+
API_PREVIEW_LABEL=$([[ "${API_ACTIVE_LABEL}" == "blue" ]] && echo "green" || echo "blue")
288+
289+
API_REVISION=$(az containerapp ingress traffic show \
290+
--resource-group "${AZURE_RESOURCE_GROUP}" \
291+
--name "${API_APP_NAME}" \
292+
--query "[?label=='${API_ACTIVE_LABEL}'].revisionName | [0]" \
293+
-o tsv 2>/dev/null || true)
294+
fi
295+
296+
if [[ -n "${UI_APP_NAME}" ]]; then
297+
UI_ACTIVE_LABEL=$(az containerapp ingress traffic show \
298+
--resource-group "${AZURE_RESOURCE_GROUP}" \
299+
--name "${UI_APP_NAME}" \
300+
--query "[?weight==\`100\` && label!=null].label | [0]" \
301+
-o tsv 2>/dev/null || true)
302+
303+
if [[ -z "${UI_ACTIVE_LABEL}" ]]; then
304+
UI_ACTIVE_LABEL="blue"
305+
fi
306+
307+
UI_PREVIEW_LABEL=$([[ "${UI_ACTIVE_LABEL}" == "blue" ]] && echo "green" || echo "blue")
308+
309+
UI_REVISION=$(az containerapp ingress traffic show \
310+
--resource-group "${AZURE_RESOURCE_GROUP}" \
311+
--name "${UI_APP_NAME}" \
312+
--query "[?label=='${UI_ACTIVE_LABEL}'].revisionName | [0]" \
313+
-o tsv 2>/dev/null || true)
314+
fi
315+
316+
echo "Resolved API labels: active=${API_ACTIVE_LABEL}, preview=${API_PREVIEW_LABEL}"
317+
echo "Resolved UI labels: active=${UI_ACTIVE_LABEL}, preview=${UI_PREVIEW_LABEL}"
318+
echo "Resolved API production revision: ${API_REVISION:-<none>}"
319+
echo "Resolved UI production revision: ${UI_REVISION:-<none>}"
320+
321+
echo "##vso[task.setvariable variable=apiActiveLabel]${API_ACTIVE_LABEL}"
322+
echo "##vso[task.setvariable variable=uiActiveLabel]${UI_ACTIVE_LABEL}"
323+
echo "##vso[task.setvariable variable=apiPreviewLabel]${API_PREVIEW_LABEL}"
324+
echo "##vso[task.setvariable variable=uiPreviewLabel]${UI_PREVIEW_LABEL}"
325+
echo "##vso[task.setvariable variable=apiProductionRevisionName]${API_REVISION}"
326+
echo "##vso[task.setvariable variable=uiProductionRevisionName]${UI_REVISION}"
327+
env:
328+
AZURE_SUBSCRIPTION_ID: $(azureSubscriptionId)
329+
AZURE_ENV_NAME: $(azureEnvName)
330+
AZURE_LOCATION: $(azureLocation)
331+
AZURE_RESOURCE_GROUP: $(azureResourceGroup)
332+
261333
- task: AzureCLI@2
262334
displayName: Deploy Application (Preview)
263335
inputs:
@@ -275,8 +347,10 @@ stages:
275347
API_VERSION: $(apiSemVerVersionTag)
276348
UI_ACTIVE_LABEL: $(uiActiveLabel)
277349
UI_PROMOTE_PREVIEW: "false"
350+
UI_PRODUCTION_REVISION_NAME: $(uiProductionRevisionName)
278351
API_ACTIVE_LABEL: $(apiActiveLabel)
279352
API_PROMOTE_PREVIEW: "false"
353+
API_PRODUCTION_REVISION_NAME: $(apiProductionRevisionName)
280354
VITE_APP_VERSION: $(uiSemVerVersionTag)
281355

282356
- task: AzureCLI@2
@@ -296,11 +370,14 @@ stages:
296370
exit 1
297371
fi
298372
299-
API_HOST=$(az containerapp show --resource-group "${AZURE_RESOURCE_GROUP}" --name "${API_APP_NAME}" --query properties.latestRevisionFqdn -o tsv)
300-
UI_HOST=$(az containerapp show --resource-group "${AZURE_RESOURCE_GROUP}" --name "${UI_APP_NAME}" --query properties.latestRevisionFqdn -o tsv)
373+
API_FQDN=$(az containerapp show --resource-group "${AZURE_RESOURCE_GROUP}" --name "${API_APP_NAME}" --query properties.configuration.ingress.fqdn -o tsv)
374+
UI_FQDN=$(az containerapp show --resource-group "${AZURE_RESOURCE_GROUP}" --name "${UI_APP_NAME}" --query properties.configuration.ingress.fqdn -o tsv)
375+
376+
API_DOMAIN="${API_FQDN#${API_APP_NAME}.}"
377+
UI_DOMAIN="${UI_FQDN#${UI_APP_NAME}.}"
301378
302-
API_URL="https://${API_HOST}/health/ready"
303-
UI_URL="https://${UI_HOST}"
379+
API_URL="https://${API_APP_NAME}---${API_PREVIEW_LABEL}.${API_DOMAIN}/health/ready"
380+
UI_URL="https://${UI_APP_NAME}---${UI_PREVIEW_LABEL}.${UI_DOMAIN}"
304381
305382
echo "Validating API URL: ${API_URL}"
306383
echo "Validating UI URL: ${UI_URL}"
@@ -325,6 +402,8 @@ stages:
325402
AZURE_ENV_NAME: $(azureEnvName)
326403
AZURE_LOCATION: $(azureLocation)
327404
AZURE_RESOURCE_GROUP: $(azureResourceGroup)
405+
API_PREVIEW_LABEL: $(apiPreviewLabel)
406+
UI_PREVIEW_LABEL: $(uiPreviewLabel)
328407

329408
- task: AzureCLI@2
330409
displayName: Promote Preview to Production Label
@@ -343,8 +422,10 @@ stages:
343422
API_VERSION: $(apiSemVerVersionTag)
344423
UI_ACTIVE_LABEL: $(uiActiveLabel)
345424
UI_PROMOTE_PREVIEW: "true"
425+
UI_PRODUCTION_REVISION_NAME: ""
346426
API_ACTIVE_LABEL: $(apiActiveLabel)
347427
API_PROMOTE_PREVIEW: "true"
428+
API_PRODUCTION_REVISION_NAME: ""
348429
VITE_APP_VERSION: $(uiSemVerVersionTag)
349430

350431
- stage: Database_Deployment

infra/api.bicep

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ param version string
1515
])
1616
param activeLabel string = 'blue'
1717
param promotePreview bool = false
18+
param productionRevisionName string = ''
1819

1920
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2025-01-31-preview' existing = {
2021
name: managedIdentityName
@@ -39,6 +40,8 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing
3940

4041
var previewLabel = activeLabel == 'blue' ? 'green' : 'blue'
4142
var productionLabel = promotePreview ? previewLabel : activeLabel
43+
var targetLabel = promotePreview ? productionLabel : previewLabel
44+
var useLatestForProductionTraffic = promotePreview || empty(productionRevisionName)
4245

4346
var apiEnvironmentVariables = [
4447
{
@@ -83,7 +86,7 @@ resource containerApp 'Microsoft.App/containerApps@2025-10-02-preview' = {
8386
managedEnvironmentId: containerAppEnvironmentId
8487
configuration: {
8588
activeRevisionsMode: 'Labels'
86-
targetLabel: productionLabel
89+
targetLabel: targetLabel
8790
maxInactiveRevisions: 5
8891
registries: [
8992
{
@@ -101,10 +104,17 @@ resource containerApp 'Microsoft.App/containerApps@2025-10-02-preview' = {
101104
latestRevision: true
102105
weight: 0
103106
}
104-
{
105-
label: productionLabel
106-
weight: 100
107-
}
107+
useLatestForProductionTraffic
108+
? {
109+
label: productionLabel
110+
latestRevision: true
111+
weight: 100
112+
}
113+
: {
114+
label: productionLabel
115+
revisionName: productionRevisionName
116+
weight: 100
117+
}
108118
]
109119
}
110120
dapr: {

infra/api.bicepparam

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ param applicationInsightsName = readEnvironmentVariable('AZURE_APPLICATION_INSIG
1212
param version = readEnvironmentVariable('API_VERSION', 'latest')
1313
param activeLabel = readEnvironmentVariable('API_ACTIVE_LABEL', 'blue')
1414
param promotePreview = toLower(readEnvironmentVariable('API_PROMOTE_PREVIEW', 'false')) == 'true'
15+
param productionRevisionName = readEnvironmentVariable('API_PRODUCTION_REVISION_NAME', '')

infra/ui.bicep

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ param version string
1111
])
1212
param activeLabel string = 'blue'
1313
param promotePreview bool = false
14+
param productionRevisionName string = ''
1415

1516
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2025-01-31-preview' existing = {
1617
name: managedIdentityName
1718
}
1819

1920
var previewLabel = activeLabel == 'blue' ? 'green' : 'blue'
2021
var productionLabel = promotePreview ? previewLabel : activeLabel
22+
var targetLabel = promotePreview ? productionLabel : previewLabel
23+
var useLatestForProductionTraffic = promotePreview || empty(productionRevisionName)
2124

2225
resource containerApp 'Microsoft.App/containerApps@2025-10-02-preview' = {
2326
name: containerAppName
@@ -35,7 +38,7 @@ resource containerApp 'Microsoft.App/containerApps@2025-10-02-preview' = {
3538
managedEnvironmentId: containerAppEnvironmentId
3639
configuration: {
3740
activeRevisionsMode: 'Labels'
38-
targetLabel: productionLabel
41+
targetLabel: targetLabel
3942
maxInactiveRevisions: 5
4043
registries: [
4144
{
@@ -53,10 +56,17 @@ resource containerApp 'Microsoft.App/containerApps@2025-10-02-preview' = {
5356
latestRevision: true
5457
weight: 0
5558
}
56-
{
57-
label: productionLabel
58-
weight: 100
59-
}
59+
useLatestForProductionTraffic
60+
? {
61+
label: productionLabel
62+
latestRevision: true
63+
weight: 100
64+
}
65+
: {
66+
label: productionLabel
67+
revisionName: productionRevisionName
68+
weight: 100
69+
}
6070
]
6171
}
6272
}

infra/ui.bicepparam

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ param managedIdentityName = readEnvironmentVariable('SERVICE_UI_IDENTITY_NAME',
88
param version = readEnvironmentVariable('UI_VERSION', 'latest')
99
param activeLabel = readEnvironmentVariable('UI_ACTIVE_LABEL', 'blue')
1010
param promotePreview = toLower(readEnvironmentVariable('UI_PROMOTE_PREVIEW', 'false')) == 'true'
11+
param productionRevisionName = readEnvironmentVariable('UI_PRODUCTION_REVISION_NAME', '')

0 commit comments

Comments
 (0)