scripts/post-provision.ps1 (271 lines of code) (raw):

<# .SYNOPSIS Post Provision Script .DESCRIPTION This script performs post-provisioning tasks, waiting for software to install, and then updating the Application. .PARAMETER SubscriptionId Specify a particular SubscriptionId to use. .PARAMETER ResourceGroup Specify a particular Resource Group to use. .PARAMETER ApplicationId Specify a particular Application to use. .PARAMETER Help Print help message and exit. .EXAMPLE .\post-provision.ps1 -SubscriptionId <SubscriptionId> #> #Requires -Version 7.4 param ( [ValidateNotNullOrEmpty()] [string]$SubscriptionId = $env:AZURE_SUBSCRIPTION_ID, [ValidateNotNullOrEmpty()] [string]$ResourceGroup = $env:AZURE_RESOURCE_GROUP, [ValidateNotNullOrEmpty()] [string]$ApplicationId = $env:AZURE_CLIENT_ID, [switch]$Help ) function Show-Help { Write-Host "Usage: .\hook-postprovision.ps1 [-SubscriptionId SUBSCRIPTION_ID]" Write-Host "Options:" Write-Host " -SubscriptionId : Specify a particular Subscription ID to use." Write-Host " -ResourceGroup : Specify a particular ResourceGroup to use." Write-Host " -ApplicationId : Specify a particular ApplicationId to use." Write-Host " -Help : Print this help message and exit" } function Set-Login { try { # Check if the user is logged in $user = az ad signed-in-user show --query userPrincipalName -o tsv $accountInfo = az account show -o json 2>$null | ConvertFrom-Json if ($user) { Write-Host "`n==================================================================" Write-Host "Logged in as: $user" Write-Host "==================================================================" } else { Write-Host "`n==================================================================" Write-Host "Azure CLI Login Required" Write-Host "==================================================================" az login --scope https://graph.microsoft.com//.default # Recheck if the user is logged in $accountInfo = az account show -o json | ConvertFrom-Json if ($accountInfo) { Write-Host "`n==================================================================" Write-Host "Logged in as: $($accountInfo.user.name)" Write-Host "==================================================================" } else { Write-Host " Failed to log in. Exiting." exit 1 } } # Ensure the subscription ID is set Write-Host "`n==================================================================" Write-Host "Azure Subscription: $($SubscriptionId)" Write-Host "==================================================================" az account set --subscription $SubscriptionId } catch { Write-Host "Error during login check: $_" exit 1 } } function Get-AKSName { try { # Check if AKS_NAME is provided, if not retrieve it if (-not $env:AKS_NAME) { Write-Host " AKS_NAME not provided. Retrieving AKS name." $aksList = az aks list -g $ResourceGroup --query '[0].name' -o tsv if ($aksList) { return $aksList } else { Write-Host " No AKS cluster found in the resource group." exit 1 } } else { return $env:AKS_NAME } } catch { Write-Host "Error retrieving AKS name: $_" exit 1 } Write-Output "`n==================================================================" Write-Output "Azure Kubernetes Cluster: $env:AKS_NAME" Write-Output "==================================================================" } function Set-LocalAuth { try { $appConfig = az appconfig list -g $ResourceGroup --query '[0].name' -o tsv Write-Host "`n==================================================================" Write-Host "Enabling Local Authentication for App Configuration: $appConfig" Write-Host "==================================================================" az appconfig update -g $ResourceGroup -n $appConfig --disable-local-auth true -o none } catch { Write-Host "Error enabling local authentication: $_" exit 1 } } function Get-Software { try { # Check if the Flux configuration exists $fluxExists = az k8s-configuration flux list -t managedClusters -g $ResourceGroup --cluster-name $AKS_NAME --query "[?name=='flux-system']" -o tsv if (-not $fluxExists) { Write-Host "`n==================================================================" Write-Host "Software Installation: disabled" Write-Host "==================================================================" exit 0 } $complianceState = az k8s-configuration flux show -t managedClusters -g $ResourceGroup --cluster-name $AKS_NAME --name flux-system --query 'complianceState' -o tsv Write-Host "`n==================================================================" Write-Host "Software Installation: $complianceState" Write-Host "==================================================================" return $complianceState } catch { Write-Host "Error during software check: $_" exit 1 } } function Get-Software-Original { $end = (Get-Date).AddMinutes(35) try { $complianceState = az k8s-configuration flux show -t managedClusters -g $ResourceGroup --cluster-name $AKS_NAME --name flux-system --query 'complianceState' -o tsv Write-Host "`n==================================================================" Write-Host "Software Installation: $complianceState" Write-Host "==================================================================" # If compliant right away, skip the while loop otherwise wait initially for 5 minutes. if ($complianceState -eq "Compliant") { return } else { Write-Host " Software installing, retry in 10 minutes." Start-Sleep -Seconds 300 } while ((Get-Date) -lt $end) { $complianceState = az k8s-configuration flux show -t managedClusters -g $ResourceGroup --cluster-name $AKS_NAME --name flux-system --query 'complianceState' -o tsv Write-Host " Current Software State: $complianceState" if ($complianceState -eq "Compliant") { Write-Host " Software has been installed." break } else { Write-Host " Software installing, retry in 2 minute." Start-Sleep -Seconds 120 } } if ((Get-Date) -ge $end) { Write-Host " Software check timed out - 35 minutes." } } catch { Write-Host "Error during software check: $_" exit 1 } } function Update-Application { try { $redirectUris = @() $nodeResourceGroup = az aks show -g $ResourceGroup -n $AKS_NAME --query nodeResourceGroup -o tsv $publicIp = az network public-ip list -g "$nodeResourceGroup" --query "[?contains(name, 'kubernetes')].ipAddress" -o tsv if ($publicIp) { Write-Host "`n==================================================================" Write-Host "Adding Public Web Endpoint: $publicIp" Write-Host "==================================================================" $redirectUris += "https://$publicIp/auth/" } azd env set INGRESS_EXTERNAL "https://$publicIp/auth/" $privateIp = az network lb frontend-ip list --lb-name kubernetes-internal -g "$nodeResourceGroup" --query [].privateIPAddress -o tsv if ($privateIp) { Write-Host "`n==================================================================" Write-Host "Adding Private Web Endpoint: $privateIp" Write-Host "==================================================================" $redirectUris += "https://$privateIp/auth/" } azd env set INGRESS_INTERNAL "https://$privateIp/auth/" $azureClientOid = az ad app show --id $ApplicationId --query id -o tsv Write-Host "`n==================================================================" Write-Host "Updating AD Application (OID): $azureClientOid" Write-Host "==================================================================" if ($redirectUris.Count -gt 0) { Write-Host " Adding Redirect URIs: $($redirectUris -join ', ')" $webUris = $($redirectUris | ConvertTo-Json -Compress) $spaUris = $($redirectUris | ForEach-Object { "$_`spa/" } | ConvertTo-Json -Compress) # Replace double quotes with single quotes in the JSON strings $webUris = $webUris -replace '"', "'" $spaUris = $spaUris -replace '"', "'" # $spaUris += "http://localhost:8080" $jsonPayload = @" { 'web': {'redirectUris': $($webUris),'implicitGrantSettings': {'enableAccessTokenIssuance': false,'enableIdTokenIssuance': false}}, 'spa': {'redirectUris': $($spaUris)} } "@ if (-not $IsWindows) { $jsonPayload = $jsonPayload -replace "'", '"' } # Remove whitespaces $jsonPayload = $jsonPayload -replace '\s+', '' az rest --method PATCH ` --url "https://graph.microsoft.com/v1.0/applications/$azureClientOid" ` --headers 'Content-Type=application/json' ` --body $jsonPayload } } catch { Write-Host "Error during application update: $_" exit 1 } } # Main script execution if ($Help) { Show-Help exit 0 } if ($SKIP_POST) { exit 0 } if (-not $SubscriptionId) { Write-Host "Error: You must provide a SubscriptionId" Show-Help exit 1 } if (-not $ResourceGroup) { Write-Host "Error: You must provide a ResourceGroup" Show-Help exit 1 } if (-not $ApplicationId) { Write-Host "Error: You must provide an ApplicationId" Show-Help exit 1 } do { Set-Login $AKS_NAME = Get-AKSName $complianceState = Get-Software $elapsedTime = 0 while ($complianceState -ne "Compliant" -and $elapsedTime -lt 300) { Start-Sleep -Seconds 30 $complianceState = Get-Software $elapsedTime += 30 } if ($complianceState -ne "Compliant") { Write-Host " Software is not compliant yet. Retrying in 5 minutes." } } while ($complianceState -ne "Compliant") Set-LocalAuth Update-Application Start-Sleep -Seconds 30 # Open the web browser $os = ($PSVersionTable.OS).Split(' ')[0] $url = [string]((azd env get-values | Where-Object { $_ -match "INGRESS_EXTERNAL" }) -split '=')[1].Trim() $url = $url -replace '"', '' ### --> This is the https hack. # if ($os -ne "Darwin") { # $url = $url -replace '^https:', 'http:' # } if ($IsWindows) { Start-Process $url } else { if ($os -eq "Darwin" -or $os -eq "Ubuntu") { open $url } else { if (Get-Command powershell.exe -ErrorAction SilentlyContinue) { powershell.exe /c start "$url" } else { Write-Host "Please manually open the URL: $url" } } }