Skip to content

Validate Deployment - Client Advisor #1028

Validate Deployment - Client Advisor

Validate Deployment - Client Advisor #1028

Workflow file for this run

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