Validate Deployment - Client Advisor #1028
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Validate Deployment - Client Advisor | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - dev | |
| - demo | |
| schedule: | |
| - cron: "0 6 * * *" # Runs at 6:00 AM UTC daily | |
| workflow_dispatch: | |
| inputs: | |
| DEPLOYMENT_TYPE: | |
| description: 'Specify deployment type: WAF or Non-WAF' | |
| required: false | |
| type: choice | |
| options: | |
| - WAF | |
| - Non-WAF | |
| default: 'Non-WAF' | |
| env: | |
| GPT_MIN_CAPACITY: 200 | |
| TEXT_EMBEDDING_MIN_CAPACITY: 80 | |
| BRANCH_NAME: ${{ github.head_ref || github.ref_name }} | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| RESOURCE_GROUP_NAME: ${{ steps.check_create_rg.outputs.RESOURCE_GROUP_NAME }} | |
| WEBAPP_URL: ${{ steps.get_output.outputs.WEBAPP_URL }} | |
| DEPLOYMENT_SUCCESS: ${{ steps.deployment_status.outputs.SUCCESS }} | |
| AZURE_LOCATION: ${{ steps.set_region.outputs.AZURE_LOCATION }} | |
| ENV_NAME: ${{ steps.generate_env_name.outputs.ENV_NAME }} | |
| DEPLOYMENT_TYPE: ${{ steps.determine_deployment_type.outputs.DEPLOYMENT_TYPE }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install ODBC Driver 18 for SQL Server | |
| run: | | |
| curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - | |
| sudo add-apt-repository "$(curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list)" | |
| sudo apt-get update | |
| sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 | |
| sudo apt-get install -y unixodbc-dev | |
| - name: Setup Azure CLI | |
| run: | | |
| curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash | |
| az --version | |
| - name: Setup Azure Developer CLI | |
| run: | | |
| curl -fsSL https://aka.ms/install-azd.sh | sudo bash | |
| azd version | |
| - name: Login to Azure | |
| run: | | |
| echo "Logging into Azure..." | |
| az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }} | |
| azd auth login --client-id ${{ secrets.AZURE_CLIENT_ID }} --client-secret ${{ secrets.AZURE_CLIENT_SECRET }} --tenant-id ${{ secrets.AZURE_TENANT_ID }} | |
| echo "Setting default subscription..." | |
| az account set --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| azd config set defaults.subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Run Quota Check | |
| id: quota-check | |
| run: | | |
| export AZURE_CLIENT_ID="${{ secrets.AZURE_CLIENT_ID }}" | |
| export AZURE_TENANT_ID="${{ secrets.AZURE_TENANT_ID }}" | |
| export AZURE_CLIENT_SECRET="${{ secrets.AZURE_CLIENT_SECRET }}" | |
| export AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}" | |
| export GPT_MIN_CAPACITY="${{ env.GPT_MIN_CAPACITY }}" | |
| export TEXT_EMBEDDING_MIN_CAPACITY="${{ env.TEXT_EMBEDDING_MIN_CAPACITY }}" | |
| export AZURE_REGIONS="${{ vars.AZURE_REGIONS_CA }}" | |
| chmod +x infra/scripts/checkquota.sh | |
| if ! infra/scripts/checkquota.sh; then | |
| if grep -q "No region with sufficient quota found" infra/scripts/checkquota_ca.sh; then | |
| echo "QUOTA_FAILED=true" >> $GITHUB_ENV | |
| fi | |
| exit 1 | |
| fi | |
| - name: Notify on Quota Failure | |
| if: env.QUOTA_FAILED == 'true' | |
| run: | | |
| RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| curl -X POST "${{ secrets.LOGIC_APP_URL }}" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "subject": "CA Deployment - Quota Check Failed", | |
| "body": "<p>Dear Team,</p><p>We would like to inform you that the Build-your-own-copilot-Solution-Accelerator(Client Advisor) Deployment Automation process has encountered a quota issue. Hence, unable to proceed with the deployment.</p><p><a href=\"'${RUN_URL}'\">View run</a></p>" | |
| }' | |
| - name: Fail on Quota Check | |
| if: env.QUOTA_FAILED == 'true' | |
| run: exit 1 | |
| - name: Install Bicep CLI | |
| run: az bicep install | |
| - name: Set Deployment Region | |
| id: set_region | |
| run: | | |
| echo "Selected Region: $VALID_REGION" | |
| echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_ENV | |
| echo "AZURE_LOCATION=$VALID_REGION" >> $GITHUB_OUTPUT | |
| - name: Generate Resource Group Name | |
| id: generate_rg_name | |
| run: | | |
| echo "Generating a unique resource group name..." | |
| ACCL_NAME="ca" # Account name as specified | |
| SHORT_UUID=$(uuidgen | cut -d'-' -f1) | |
| UNIQUE_RG_NAME="arg-${ACCL_NAME}-${SHORT_UUID}" | |
| echo "RESOURCE_GROUP_NAME=${UNIQUE_RG_NAME}" >> $GITHUB_ENV | |
| echo "Generated RESOURCE_GROUP_NAME: ${UNIQUE_RG_NAME}" | |
| - name: Check and Create Resource Group | |
| id: check_create_rg | |
| run: | | |
| echo "RESOURCE_GROUP: ${{ env.RESOURCE_GROUP_NAME }}" | |
| set -e | |
| echo "Checking if resource group exists..." | |
| rg_exists=$(az group exists --name ${{ env.RESOURCE_GROUP_NAME }}) | |
| if [ "$rg_exists" = "false" ]; then | |
| echo "Resource group does not exist. Creating..." | |
| az group create --name ${{ env.RESOURCE_GROUP_NAME }} --location ${{ env.AZURE_LOCATION }} || { echo "Error creating resource group"; exit 1; } | |
| else | |
| echo "Resource group already exists." | |
| fi | |
| # Set output for other jobs | |
| echo "RESOURCE_GROUP_NAME=${{ env.RESOURCE_GROUP_NAME }}" >> $GITHUB_OUTPUT | |
| - name: Generate Unique Environment Name | |
| id: generate_env_name | |
| run: | | |
| set -e | |
| COMMON_PART="pslc" | |
| TIMESTAMP=$(date +%s) | |
| UPDATED_TIMESTAMP=$(echo $TIMESTAMP | tail -c 3) | |
| UNIQUE_ENV_NAME="${COMMON_PART}${UPDATED_TIMESTAMP}" | |
| echo "ENV_NAME=${UNIQUE_ENV_NAME}" >> $GITHUB_ENV | |
| echo "ENV_NAME=${UNIQUE_ENV_NAME}" >> $GITHUB_OUTPUT | |
| echo "Generated ENV_NAME: ${UNIQUE_ENV_NAME}" | |
| - name: Determine Tag | |
| id: determine_tag | |
| run: | | |
| BRANCH=${{ github.ref_name }} | |
| if [[ "$BRANCH" == "main" ]]; then TAG="latest_waf" | |
| elif [[ "$BRANCH" == "dev" ]]; then TAG="dev" | |
| elif [[ "$BRANCH" == "demo" ]]; then TAG="demo" | |
| else TAG="latest_waf"; fi | |
| echo "IMAGE_TAG=$TAG" >> $GITHUB_ENV | |
| echo "Image Tag: $TAG" | |
| - name: Determine Deployment Type | |
| id: determine_deployment_type | |
| run: | | |
| set -e | |
| # Get day of month (1-31) | |
| DAY=$(date +%d) | |
| # Remove leading zero | |
| DAY=$((10#$DAY)) | |
| # Check if deployment type is provided via workflow dispatch | |
| if [ "${{ github.event.inputs.DEPLOYMENT_TYPE }}" != "" ]; then | |
| DEPLOYMENT_TYPE="${{ github.event.inputs.DEPLOYMENT_TYPE }}" | |
| echo "DEPLOYMENT_TYPE=$DEPLOYMENT_TYPE" >> $GITHUB_OUTPUT | |
| echo "DEPLOYMENT_TYPE=$DEPLOYMENT_TYPE" >> $GITHUB_ENV | |
| echo "Deployment type provided via workflow dispatch: $DEPLOYMENT_TYPE" | |
| exit 0 | |
| fi | |
| # Alternate based on odd/even day | |
| if [ $((DAY % 2)) -eq 0 ]; then | |
| echo "DEPLOYMENT_TYPE=WAF" >> $GITHUB_OUTPUT | |
| echo "DEPLOYMENT_TYPE=WAF" >> $GITHUB_ENV | |
| echo "Even day detected ($DAY). Setting deployment type to WAF." | |
| else | |
| echo "DEPLOYMENT_TYPE=Non-WAF" >> $GITHUB_OUTPUT | |
| echo "DEPLOYMENT_TYPE=Non-WAF" >> $GITHUB_ENV | |
| echo "Odd day detected ($DAY). Setting deployment type to Non-WAF." | |
| fi | |
| - name: Copy Parameters File Based on Deployment Type | |
| id: copy_parameters_file | |
| run: | | |
| set -e | |
| if [ "${{ env.DEPLOYMENT_TYPE }}" == "WAF" ]; then | |
| echo "Using WAF parameters file." | |
| cp -f infra/main.waf.parameters.json infra/main.parameters.json | |
| else | |
| echo "Using Non-WAF parameters file." | |
| fi | |
| - name: Create azd environment | |
| id: create_azd_env | |
| run: | | |
| set -e | |
| echo "Creating azd environment..." | |
| azd env new ${{ env.ENV_NAME }} --no-prompt | |
| echo "Environment created: ${{ env.ENV_NAME }}" | |
| echo "Setting environment variables..." | |
| azd env set AZURE_RESOURCE_GROUP="${{ env.RESOURCE_GROUP_NAME }}" | |
| azd env set AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}" | |
| azd env set AZURE_LOCATION="${{ env.AZURE_LOCATION }}" | |
| azd env set AZURE_ENV_AI_SERVICE_LOCATION="${{ env.AZURE_LOCATION }}" | |
| azd env set AZURE_ENV_MODEL_CAPACITY="${{ env.GPT_MIN_CAPACITY }}" | |
| azd env set AZURE_ENV_EMBEDDING_MODEL_CAPACITY="${{ env.TEXT_EMBEDDING_MIN_CAPACITY }}" | |
| azd env set AZURE_ENV_IMAGETAG="${IMAGE_TAG}" | |
| echo "Environment variables set successfully:" | |
| azd env get-values | |
| - name: Deploy using azd | |
| id: deploy | |
| run: | | |
| set -e | |
| azd up --no-prompt | |
| echo "Deployment completed successfully." | |
| - name: Extract values from deployment output | |
| id: get_output | |
| run: | | |
| set -e | |
| echo "Fetching deployment output..." | |
| AI_FOUNDRY_RESOURCE_ID=$(azd env get-value AI_FOUNDRY_RESOURCE_ID) | |
| echo "AI_FOUNDRY_RESOURCE_ID=$AI_FOUNDRY_RESOURCE_ID" >> $GITHUB_ENV | |
| echo "Deployed AI_FOUNDRY_RESOURCE_ID: $AI_FOUNDRY_RESOURCE_ID" | |
| SEARCH_SERVICE_NAME=$(azd env get-value AI_SEARCH_SERVICE_NAME) | |
| echo "SEARCH_SERVICE_NAME=$SEARCH_SERVICE_NAME" >> $GITHUB_ENV | |
| echo "Deployed SEARCH_SERVICE_NAME: $SEARCH_SERVICE_NAME" | |
| COSMOS_DB_ACCOUNT_NAME=$(azd env get-value COSMOSDB_ACCOUNT_NAME) | |
| echo "COSMOS_DB_ACCOUNT_NAME=$COSMOS_DB_ACCOUNT_NAME" >> $GITHUB_ENV | |
| echo "Deployed COSMOS_DB_ACCOUNT_NAME: $COSMOS_DB_ACCOUNT_NAME" | |
| STORAGE_ACCOUNT=$(azd env get-value STORAGE_ACCOUNT_NAME) | |
| echo "STORAGE_ACCOUNT=$STORAGE_ACCOUNT" >> $GITHUB_ENV | |
| echo "Deployed STORAGE_ACCOUNT: $STORAGE_ACCOUNT" | |
| STORAGE_CONTAINER=$(azd env get-value STORAGE_CONTAINER_NAME) | |
| echo "STORAGE_CONTAINER=$STORAGE_CONTAINER" >> $GITHUB_ENV | |
| echo "Deployed STORAGE_CONTAINER: $STORAGE_CONTAINER" | |
| KEYVAULT_NAME=$(azd env get-value KEY_VAULT_NAME) | |
| echo "KEYVAULT_NAME=$KEYVAULT_NAME" >> $GITHUB_ENV | |
| echo "Deployed KEYVAULT_NAME: $KEYVAULT_NAME" | |
| SQL_SERVER_NAME=$(azd env get-value SQLDB_SERVER_NAME) | |
| echo "SQL_SERVER_NAME=$SQL_SERVER_NAME" >> $GITHUB_ENV | |
| echo "Deployed SQL_SERVER_NAME: $SQL_SERVER_NAME" | |
| SQL_DATABASE=$(azd env get-value SQLDB_DATABASE) | |
| echo "SQL_DATABASE=$SQL_DATABASE" >> $GITHUB_ENV | |
| echo "Deployed SQL_DATABASE: $SQL_DATABASE" | |
| CLIENT_ID=$(azd env get-value MANAGEDIDENTITY_SQL_CLIENTID) | |
| echo "CLIENT_ID=$CLIENT_ID" >> $GITHUB_ENV | |
| echo "Deployed MANAGED IDENTITY CLIENT_ID: $CLIENT_ID" | |
| CLIENT_NAME=$(azd env get-value MANAGEDIDENTITY_SQL_NAME) | |
| echo "CLIENT_NAME=$CLIENT_NAME" >> $GITHUB_ENV | |
| echo "Deployed MANAGED IDENTITY CLIENT_NAME: $CLIENT_NAME" | |
| RG_NAME=$(azd env get-value RESOURCE_GROUP_NAME) | |
| echo "RG_NAME=$RG_NAME" >> $GITHUB_ENV | |
| WEBAPP_URL=$(azd env get-value WEB_APP_URL) | |
| echo "WEBAPP_URL=$WEBAPP_URL" >> $GITHUB_OUTPUT | |
| echo "Deployed WEB APP URL: $WEBAPP_URL" | |
| WEB_APP_NAME=$(azd env get-value WEB_APP_NAME) | |
| echo "WEB_APP_NAME=$WEB_APP_NAME" >> $GITHUB_ENV | |
| echo "🔧 Disabling AUTH_ENABLED for the web app..." | |
| az webapp config appsettings set -g "$RG_NAME" -n "$WEB_APP_NAME" --settings AUTH_ENABLED=false | |
| sleep 30 | |
| - name: Enable Public Network Access (WAF Only) | |
| if: env.DEPLOYMENT_TYPE == 'WAF' | |
| run: | | |
| set -e | |
| echo "=== Temporarily enabling public network access for WAF deployment ===" | |
| # Enable public access for Storage Account | |
| echo "Enabling public access for Storage Account: ${{ env.STORAGE_ACCOUNT }}" | |
| ORIGINAL_STORAGE_PUBLIC_ACCESS=$(az storage account show \ | |
| --name "${{ env.STORAGE_ACCOUNT }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --query "publicNetworkAccess" \ | |
| -o tsv) | |
| echo "ORIGINAL_STORAGE_PUBLIC_ACCESS=$ORIGINAL_STORAGE_PUBLIC_ACCESS" >> $GITHUB_ENV | |
| ORIGINAL_STORAGE_DEFAULT_ACTION=$(az storage account show \ | |
| --name "${{ env.STORAGE_ACCOUNT }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --query "networkRuleSet.defaultAction" \ | |
| -o tsv) | |
| echo "ORIGINAL_STORAGE_DEFAULT_ACTION=$ORIGINAL_STORAGE_DEFAULT_ACTION" >> $GITHUB_ENV | |
| if [ "$ORIGINAL_STORAGE_PUBLIC_ACCESS" != "Enabled" ]; then | |
| az storage account update \ | |
| --name "${{ env.STORAGE_ACCOUNT }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --public-network-access Enabled \ | |
| --output none | |
| echo "✓ Storage Account public access enabled" | |
| fi | |
| if [ "$ORIGINAL_STORAGE_DEFAULT_ACTION" != "Allow" ]; then | |
| az storage account update \ | |
| --name "${{ env.STORAGE_ACCOUNT }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --default-action Allow \ | |
| --output none | |
| echo "✓ Storage Account network default action set to Allow" | |
| fi | |
| # Enable public access for AI Foundry | |
| AIF_ACCOUNT_RESOURCE_ID=$(echo "${{ env.AI_FOUNDRY_RESOURCE_ID }}" | sed 's|/projects/.*||') | |
| AIF_RESOURCE_NAME=$(basename "$AIF_ACCOUNT_RESOURCE_ID") | |
| AIF_RESOURCE_GROUP=$(echo "$AIF_ACCOUNT_RESOURCE_ID" | sed -n 's|.*/resourceGroups/\([^/]*\)/.*|\1|p') | |
| AIF_SUBSCRIPTION_ID=$(echo "$AIF_ACCOUNT_RESOURCE_ID" | sed -n 's|.*/subscriptions/\([^/]*\)/.*|\1|p') | |
| echo "AIF_ACCOUNT_RESOURCE_ID=$AIF_ACCOUNT_RESOURCE_ID" >> $GITHUB_ENV | |
| ORIGINAL_FOUNDRY_PUBLIC_ACCESS=$(az cognitiveservices account show \ | |
| --name "$AIF_RESOURCE_NAME" \ | |
| --resource-group "$AIF_RESOURCE_GROUP" \ | |
| --subscription "$AIF_SUBSCRIPTION_ID" \ | |
| --query "properties.publicNetworkAccess" \ | |
| --output tsv || echo "") | |
| echo "ORIGINAL_FOUNDRY_PUBLIC_ACCESS=$ORIGINAL_FOUNDRY_PUBLIC_ACCESS" >> $GITHUB_ENV | |
| if [ -n "$ORIGINAL_FOUNDRY_PUBLIC_ACCESS" ] && [ "$ORIGINAL_FOUNDRY_PUBLIC_ACCESS" != "Enabled" ]; then | |
| az resource update \ | |
| --ids "$AIF_ACCOUNT_RESOURCE_ID" \ | |
| --api-version 2024-10-01 \ | |
| --set properties.publicNetworkAccess=Enabled properties.apiProperties="{}" \ | |
| --output none || echo "⚠ Warning: Failed to enable AI Foundry public access" | |
| echo "✓ AI Foundry public access enabled" | |
| fi | |
| # Enable public access for Key Vault | |
| echo "Enabling public access for Key Vault: ${{ env.KEYVAULT_NAME }}" | |
| ORIGINAL_KEYVAULT_PUBLIC_ACCESS=$(az keyvault show \ | |
| --name "${{ env.KEYVAULT_NAME }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --query "properties.publicNetworkAccess" \ | |
| -o tsv) | |
| echo "ORIGINAL_KEYVAULT_PUBLIC_ACCESS=$ORIGINAL_KEYVAULT_PUBLIC_ACCESS" >> $GITHUB_ENV | |
| if [ "$ORIGINAL_KEYVAULT_PUBLIC_ACCESS" != "Enabled" ]; then | |
| az keyvault update \ | |
| --name "${{ env.KEYVAULT_NAME }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --public-network-access Enabled \ | |
| --output none | |
| echo "✓ Key Vault public access enabled" | |
| fi | |
| # Enable public access for SQL Server | |
| echo "Enabling public access for SQL Server: ${{ env.SQL_SERVER_NAME }}" | |
| ORIGINAL_SQL_PUBLIC_ACCESS=$(az sql server show \ | |
| --name "${{ env.SQL_SERVER_NAME }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --query "publicNetworkAccess" \ | |
| -o tsv) | |
| echo "ORIGINAL_SQL_PUBLIC_ACCESS=$ORIGINAL_SQL_PUBLIC_ACCESS" >> $GITHUB_ENV | |
| if [ "$ORIGINAL_SQL_PUBLIC_ACCESS" != "Enabled" ]; then | |
| az sql server update \ | |
| --name "${{ env.SQL_SERVER_NAME }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --enable-public-network true \ | |
| --output none | |
| echo "✓ SQL Server public access enabled" | |
| fi | |
| # Add temporary firewall rule allowing all IPs | |
| EXISTING_ALLOW_ALL_RULE=$(az sql server firewall-rule list \ | |
| --server "${{ env.SQL_SERVER_NAME }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --query "[?name=='temp-allow-all-ip'] | [0].name" \ | |
| -o tsv 2>/dev/null || echo "") | |
| if [ -z "$EXISTING_ALLOW_ALL_RULE" ]; then | |
| az sql server firewall-rule create \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --server "${{ env.SQL_SERVER_NAME }}" \ | |
| --name "temp-allow-all-ip" \ | |
| --start-ip-address 0.0.0.0 \ | |
| --end-ip-address 255.255.255.255 \ | |
| --output none || echo "⚠ Warning: Failed to create allow-all firewall rule" | |
| echo "CREATED_SQL_FIREWALL_RULE=true" >> $GITHUB_ENV | |
| echo "✓ Temporary allow-all firewall rule created" | |
| else | |
| echo "CREATED_SQL_FIREWALL_RULE=false" >> $GITHUB_ENV | |
| fi | |
| echo "Waiting for network access changes to propagate..." | |
| sleep 30 | |
| echo "=== Public network access enabled successfully ===" | |
| - name: Import Sample Data (Post-Deployment Scripts) | |
| run: | | |
| set -e | |
| az account set --subscription "${{ secrets.AZURE_SUBSCRIPTION_ID }}" | |
| echo "Running post-deployment script..." | |
| bash ./infra/scripts/add_cosmosdb_access.sh \ | |
| "${{ env.RG_NAME }}" \ | |
| "${{ env.COSMOS_DB_ACCOUNT_NAME }}" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" | |
| bash ./infra/scripts/copy_kb_files.sh \ | |
| "${{ env.STORAGE_ACCOUNT }}" \ | |
| "${{ env.STORAGE_CONTAINER }}" \ | |
| "" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" | |
| bash ./infra/scripts/run_create_index_scripts.sh \ | |
| "${{ env.KEYVAULT_NAME }}" \ | |
| "" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" \ | |
| "${{ env.RG_NAME }}" \ | |
| "${{ env.SQL_SERVER_NAME }}" \ | |
| "${{ env.SEARCH_SERVICE_NAME }}" \ | |
| "${{ env.AI_FOUNDRY_RESOURCE_ID}}" | |
| user_roles_json='[ | |
| {"clientId":"${{ env.CLIENT_ID }}","displayName":"${{ env.CLIENT_NAME }}","role":"db_datareader"}, | |
| {"clientId":"${{ env.CLIENT_ID }}","displayName":"${{ env.CLIENT_NAME }}","role":"db_owner"} | |
| ]' | |
| bash ./infra/scripts/add_user_scripts/create_sql_user_and_role.sh \ | |
| "${{ env.SQL_SERVER_NAME }}.database.windows.net" \ | |
| "${{ env.SQL_DATABASE }}" \ | |
| "$user_roles_json" \ | |
| "${{ secrets.AZURE_CLIENT_ID }}" | |
| echo "=== Post-Deployment Script Completed Successfully ===" | |
| - name: Restore Network Access (WAF Only) | |
| if: always() && env.DEPLOYMENT_TYPE == 'WAF' | |
| run: | | |
| set -e | |
| echo "=== Restoring original network access settings ===" | |
| # Restore Storage Account access | |
| if [ -n "${{ env.ORIGINAL_STORAGE_PUBLIC_ACCESS }}" ] && [ "${{ env.ORIGINAL_STORAGE_PUBLIC_ACCESS }}" != "Enabled" ]; then | |
| echo "Restoring Storage Account public access to: ${{ env.ORIGINAL_STORAGE_PUBLIC_ACCESS }}" | |
| RESTORE_VALUE="${{ env.ORIGINAL_STORAGE_PUBLIC_ACCESS }}" | |
| az storage account update \ | |
| --name "${{ env.STORAGE_ACCOUNT }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --public-network-access "$RESTORE_VALUE" \ | |
| --output none || echo "✗ Failed to restore Storage Account access" | |
| echo "✓ Storage Account access restored" | |
| fi | |
| # Restore Storage Account network default action | |
| if [ -n "${{ env.ORIGINAL_STORAGE_DEFAULT_ACTION }}" ] && [ "${{ env.ORIGINAL_STORAGE_DEFAULT_ACTION }}" != "Allow" ]; then | |
| echo "Restoring Storage Account network default action to: ${{ env.ORIGINAL_STORAGE_DEFAULT_ACTION }}" | |
| az storage account update \ | |
| --name "${{ env.STORAGE_ACCOUNT }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --default-action "${{ env.ORIGINAL_STORAGE_DEFAULT_ACTION }}" \ | |
| --output none || echo "✗ Failed to restore Storage Account network default action" | |
| echo "✓ Storage Account network default action restored" | |
| fi | |
| # Restore AI Foundry access | |
| if [ -n "${{ env.ORIGINAL_FOUNDRY_PUBLIC_ACCESS }}" ] && [ "${{ env.ORIGINAL_FOUNDRY_PUBLIC_ACCESS }}" != "Enabled" ]; then | |
| echo "Restoring AI Foundry public access to: ${{ env.ORIGINAL_FOUNDRY_PUBLIC_ACCESS }}" | |
| az resource update \ | |
| --ids "${{ env.AIF_ACCOUNT_RESOURCE_ID }}" \ | |
| --api-version 2024-10-01 \ | |
| --set properties.publicNetworkAccess="${{ env.ORIGINAL_FOUNDRY_PUBLIC_ACCESS }}" \ | |
| --set properties.apiProperties.qnaAzureSearchEndpointKey="" \ | |
| --set properties.networkAcls.bypass="AzureServices" \ | |
| --output none 2>/dev/null || echo "⚠ Warning: Failed to restore AI Foundry access automatically" | |
| echo "✓ AI Foundry access restored" | |
| fi | |
| # Restore Key Vault access | |
| if [ -n "${{ env.ORIGINAL_KEYVAULT_PUBLIC_ACCESS }}" ] && [ "${{ env.ORIGINAL_KEYVAULT_PUBLIC_ACCESS }}" != "Enabled" ]; then | |
| echo "Restoring Key Vault public access to: ${{ env.ORIGINAL_KEYVAULT_PUBLIC_ACCESS }}" | |
| RESTORE_VALUE="${{ env.ORIGINAL_KEYVAULT_PUBLIC_ACCESS }}" | |
| az keyvault update \ | |
| --name "${{ env.KEYVAULT_NAME }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --public-network-access "$RESTORE_VALUE" \ | |
| --output none || echo "✗ Failed to restore Key Vault access" | |
| echo "✓ Key Vault access restored" | |
| fi | |
| # Restore SQL Server public access | |
| if [ -n "${{ env.ORIGINAL_SQL_PUBLIC_ACCESS }}" ] && [ "${{ env.ORIGINAL_SQL_PUBLIC_ACCESS }}" != "Enabled" ]; then | |
| echo "Restoring SQL Server public access to: ${{ env.ORIGINAL_SQL_PUBLIC_ACCESS }}" | |
| az sql server update \ | |
| --name "${{ env.SQL_SERVER_NAME }}" \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --enable-public-network false \ | |
| --output none || echo "✗ Failed to restore SQL Server access" | |
| echo "✓ SQL Server access restored" | |
| fi | |
| # Remove temporary firewall rule if we created it | |
| if [ "${{ env.CREATED_SQL_FIREWALL_RULE }}" == "true" ]; then | |
| echo "Removing temporary allow-all firewall rule..." | |
| az sql server firewall-rule delete \ | |
| --resource-group "${{ env.RG_NAME }}" \ | |
| --server "${{ env.SQL_SERVER_NAME }}" \ | |
| --name "temp-allow-all-ip" \ | |
| --output none || echo "⚠ Warning: Failed to remove temporary firewall rule" | |
| echo "✓ Temporary firewall rule removed" | |
| fi | |
| echo "=== Network access restoration completed ===" | |
| - name: Set Deployment Status | |
| id: deployment_status | |
| if: always() | |
| run: | | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "SUCCESS=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "SUCCESS=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Logout | |
| if: always() | |
| run: | | |
| az logout | |
| azd auth logout | |
| e2e-test: | |
| needs: deploy | |
| if: needs.deploy.outputs.DEPLOYMENT_SUCCESS == 'true' | |
| uses: ./.github/workflows/test_automation.yml | |
| with: | |
| CA_WEB_URL: ${{ needs.deploy.outputs.WEBAPP_URL }} | |
| secrets: inherit | |
| cleanup: | |
| if: always() && needs.deploy.outputs.RESOURCE_GROUP_NAME != '' | |
| needs: [deploy, e2e-test] | |
| runs-on: ubuntu-latest | |
| env: | |
| RESOURCE_GROUP_NAME: ${{ needs.deploy.outputs.RESOURCE_GROUP_NAME }} | |
| AZURE_LOCATION: ${{ needs.deploy.outputs.AZURE_LOCATION }} | |
| ENV_NAME: ${{ needs.deploy.outputs.ENV_NAME }} | |
| DEPLOYMENT_TYPE: ${{ needs.deploy.outputs.DEPLOYMENT_TYPE }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Azure CLI | |
| run: | | |
| curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash | |
| az --version # Verify installation | |
| - name: Setup Azure Developer CLI | |
| run: | | |
| curl -fsSL https://aka.ms/install-azd.sh | sudo bash | |
| azd version | |
| - name: Login to Azure | |
| run: | | |
| echo "Logging into Azure..." | |
| az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }} | |
| azd auth login --client-id ${{ secrets.AZURE_CLIENT_ID }} --client-secret ${{ secrets.AZURE_CLIENT_SECRET }} --tenant-id ${{ secrets.AZURE_TENANT_ID }} | |
| echo "Setting default subscription..." | |
| az account set --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| azd config set defaults.subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Select Environment | |
| run: | | |
| set -e | |
| # Try to select the environment if it exists, otherwise create a minimal environment for cleanup | |
| azd env list | |
| if azd env list | grep -q "${{ env.ENV_NAME }}"; then | |
| echo "Environment ${{ env.ENV_NAME }} found, selecting it..." | |
| azd env select ${{ env.ENV_NAME }} | |
| else | |
| echo "Environment ${{ env.ENV_NAME }} not found, creating minimal environment for cleanup..." | |
| azd env new ${{ env.ENV_NAME }} --no-prompt | |
| azd env set AZURE_RESOURCE_GROUP "${{ env.RESOURCE_GROUP_NAME }}" | |
| azd env set AZURE_SUBSCRIPTION_ID "${{ secrets.AZURE_SUBSCRIPTION_ID }}" | |
| azd env set AZURE_ENV_AI_SERVICE_LOCATION="${{ env.AZURE_LOCATION }}" | |
| fi | |
| - name: Delete deployment using azd | |
| run: | | |
| set -e | |
| echo "Deleting deployment..." | |
| azd down --purge --force --no-prompt | |
| echo "Deployment deleted successfully." | |
| - name: Notify on Failure | |
| if: failure() || needs.deploy.result == 'failure' || needs.e2e-test.result == 'failure' | |
| run: | | |
| RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| # Construct the email body | |
| EMAIL_BODY=$(cat <<EOF | |
| { | |
| "body": "<p>Dear Team,</p><p>We would like to inform you that the Build-your-own-copilot-Solution-Accelerator(Client Advisior) - ${{ env.DEPLOYMENT_TYPE }} Automation process has encountered an issue and has failed to complete successfully.</p><p><strong>Build URL:</strong> ${RUN_URL}<br> ${OUTPUT}</p><p>Please investigate the matter at your earliest convenience.</p><p>Best regards,<br>Your Automation Team</p>" | |
| } | |
| EOF | |
| ) | |
| # Send the notification | |
| curl -X POST "${{ secrets.LOGIC_APP_URL }}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$EMAIL_BODY" || echo "Failed to send notification" | |
| - name: Logout | |
| if: always() | |
| run: | | |
| echo "Logging out of Azure..." | |
| az logout | |
| azd auth logout |