diff --git a/.azdo/pipelines/azure-dev.yml b/.azdo/pipelines/azure-dev.yml
new file mode 100644
index 000000000..b571fd91c
--- /dev/null
+++ b/.azdo/pipelines/azure-dev.yml
@@ -0,0 +1,87 @@
+# Run when commits are pushed to mainline branch (main or master)
+# Set this to the mainline branch you are using
+trigger:
+ - main
+ - master
+ - dev
+
+# Azure Pipelines workflow to deploy to Azure using azd
+# To configure required secrets and service connection for connecting to Azure, simply run `azd pipeline config --provider azdo`
+# Task "Install azd" needs to install setup-azd extension for azdo - https://marketplace.visualstudio.com/items?itemName=ms-azuretools.azd
+# See below for alternative task to install azd if you can't install above task in your organization
+
+pool:
+ vmImage: ubuntu-latest
+
+steps:
+ - task: setup-azd@0
+ displayName: Install azd
+
+ # If you can't install above task in your organization, you can comment it and uncomment below task to install azd
+ # - task: Bash@3
+ # displayName: Install azd
+ # inputs:
+ # targetType: 'inline'
+ # script: |
+ # curl -fsSL https://aka.ms/install-azd.sh | bash
+
+ # azd delegate auth to az to use service connection with AzureCLI@2
+ - pwsh: |
+ azd config set auth.useAzCliAuth "true"
+ displayName: Configure AZD to Use AZ CLI Authentication.
+
+ - task: AzureCLI@2
+ displayName: Provision Infrastructure
+ inputs:
+ azureSubscription: azconnection
+ scriptType: bash
+ scriptLocation: inlineScript
+ inlineScript: |
+ azd provision --no-prompt
+ env:
+
+ AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
+ AZURE_ENV_NAME: $(AZURE_ENV_NAME)
+ AZURE_LOCATION: $(AZURE_LOCATION)
+ # Project specific environment variables
+ # AZURE_RESOURCE_GROUP: $(AZURE_RESOURCE_GROUP)
+ # AZURE_AIHUB_NAME: $(AZURE_AIHUB_NAME)
+ # AZURE_AIPROJECT_NAME: $(AZURE_AIPROJECT_NAME)
+ # AZURE_AISERVICES_NAME: $(AZURE_AISERVICES_NAME)
+ # AZURE_SEARCH_SERVICE_NAME: $(AZURE_SEARCH_SERVICE_NAME)
+ # AZURE_APPLICATION_INSIGHTS_NAME: $(AZURE_APPLICATION_INSIGHTS_NAME)
+ # AZURE_CONTAINER_REGISTRY_NAME: $(AZURE_CONTAINER_REGISTRY_NAME)
+ # AZURE_KEYVAULT_NAME: $(AZURE_KEYVAULT_NAME)
+ # AZURE_STORAGE_ACCOUNT_NAME: $(AZURE_STORAGE_ACCOUNT_NAME)
+ # AZURE_LOG_ANALYTICS_WORKSPACE_NAME: $(AZURE_LOG_ANALYTICS_WORKSPACE_NAME)
+ # USE_CONTAINER_REGISTRY: $(USE_CONTAINER_REGISTRY)
+ # USE_APPLICATION_INSIGHTS: $(USE_APPLICATION_INSIGHTS)
+ # USE_SEARCH_SERVICE: $(USE_SEARCH_SERVICE)
+ # AZURE_AI_CHAT_DEPLOYMENT_NAME: $(AZURE_AI_CHAT_DEPLOYMENT_NAME)
+ # AZURE_AI_CHAT_DEPLOYMENT_SKU: $(AZURE_AI_CHAT_DEPLOYMENT_SKU)
+ # AZURE_AI_CHAT_DEPLOYMENT_CAPACITY: $(AZURE_AI_CHAT_DEPLOYMENT_CAPACITY)
+ # AZURE_AI_CHAT_MODEL_FORMAT: $(AZURE_AI_CHAT_MODEL_FORMAT)
+ # AZURE_AI_CHAT_MODEL_NAME: $(AZURE_AI_CHAT_MODEL)
+ # AZURE_AI_CHAT_MODEL_VERSION: $(AZURE_AI_CHAT_MODEL_VERSION)
+ # AZURE_AI_EMBED_DEPLOYMENT_NAME: $(AZURE_AI_EMBED_DEPLOYMENT_NAME)
+ # AZURE_AI_EMBED_DEPLOYMENT_SKU: $(AZURE_AI_EMBED_DEPLOYMENT_SKU)
+ # AZURE_AI_EMBED_DEPLOYMENT_CAPACITY: $(AZURE_AI_EMBED_DEPLOYMENT_CAPACITY)
+ # AZURE_AI_EMBED_MODEL_FORMAT: $(AZURE_AI_EMBED_MODEL_FORMAT)
+ # AZURE_AI_EMBED_MODEL_NAME: $(AZURE_AI_EMBED_MODEL_NAME)
+ # AZURE_AI_EMBED_MODEL_VERSION: $(AZURE_AI_EMBED_MODEL_VERSION)
+ # AZURE_EXISTING_AIPROJECT_CONNECTION_STRING: $(AZURE_EXISTING_AIPROJECT_CONNECTION_STRING)
+ - task: AzureCLI@2
+ displayName: Deploy Application
+ inputs:
+ azureSubscription: azconnection
+ scriptType: bash
+ scriptLocation: inlineScript
+ inlineScript: |
+ azd deploy --no-prompt
+ env:
+ AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
+ AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
+ AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
+ AZURE_ENV_NAME: ${{ secrets.AZURE_ENV_NAME }}
+ AZURE_LOCATION: ${{ secrets.AZURE_LOCATION }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index a6ae6ab8d..457b35fba 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -28,8 +28,7 @@
"ms-python.python",
"ms-azuretools.vscode-azcli",
"ms-azuretools.vscode-bicep",
- "ms-azuretools.azure-dev",
- "ms-azuretools.vscode-azurefunctions"
+ "ms-azuretools.azure-dev"
]
}
},
diff --git a/.github/workflows/CAdeploy.yml b/.github/workflows/CAdeploy.yml
index 7865b05d4..d9d2e004e 100644
--- a/.github/workflows/CAdeploy.yml
+++ b/.github/workflows/CAdeploy.yml
@@ -115,7 +115,7 @@ jobs:
az deployment group create \
--resource-group ${{ env.RESOURCE_GROUP_NAME }} \
--template-file infra/main.bicep \
- --parameters AzureOpenAILocation=${{ env.AZURE_LOCATION }}
+ --parameters AzureOpenAILocation=${{ env.AZURE_LOCATION }} environmentName=${{ env.SOLUTION_PREFIX }} cosmosLocation=eastus2
- name: List KeyVaults and Store in Array
id: list_keyvaults
diff --git a/.gitignore b/.gitignore
index f223f792e..cec1e1d05 100644
--- a/.gitignore
+++ b/.gitignore
@@ -403,4 +403,4 @@ scriptenv
.azure
clientdata
-clienttranscripts
\ No newline at end of file
+clienttranscripts
diff --git a/README.md b/README.md
index 4f182dcf8..a5ac4e09d 100644
--- a/README.md
+++ b/README.md
@@ -60,8 +60,8 @@ Follow the quick deploy steps on the deployment guide to deploy this solution to
-| [](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fbuild-your-own-copilot-solution-accelerator%2Fdev%2Finfra%2Fmain.json) |
-|---|
+
diff --git a/docs/ManualAppRegistrationConfiguration.md b/docs/ManualAppRegistrationConfiguration.md
new file mode 100644
index 000000000..cc50eb349
--- /dev/null
+++ b/docs/ManualAppRegistrationConfiguration.md
@@ -0,0 +1,66 @@
+# Manual App Registration Configuration
+This guide provides detailed steps to manually register both front-end and backend applications in Azure if automated registration is not an option due to security in place in your tenant and subscription.
+
+## Prerequisites
+
+- Access to **Microsoft Entra ID**
+- Necessary permissions to create and manage **App Registrations** in your Azure tenant
+
+## Step 1: Register the Web Application
+### 1. Create App Registration
+- Go to **Azure Portal** > **Microsoft Entra ID** > **Manage** > **App registrations**
+- Click **+ New registration**
+- Name the app (e.g., `byoc-app`)
+- Under **Redirect URI**, choose **Web** and enter:
+
+ ```
+ https://azurecontainerapps.io/auth/login/aad/callback
+ ```
+
+ To find your Web App URL:
+ - Navigate to your newly deployed resource group in the Azure Portal.
+ - Locate the web app in resource group.
+ - Copy the Default domain url from the Overview .
+
+- Click **Register**
+ 
+
+
+
+### 2. Configure Certificates and Secrets
+
+- Go to **Certificates & secrets**
+- Click **+ New client secret**
+- Description: Provide a meaningful name to identify the secret
+- Expires: Select from the options or define a custom range
+- Start (Optional for custom range): Set the starting date of the secret's validity
+- End (Optional for custom range): Set the ending date of the secret's validity
+- Click **Add** and remember to copy and store the secret value securely as it will not be shown again
+
+
+### 3. Get Tenant ID
+- Go to **Tenant Properties** in [Azure Portal](https://portal.azure.com)
+- Copy the Tenant ID (will be used in next step)
+
+
+
+### 4. Set Up Authentication in Web Container App
+
+- Go to your Web Container App
+- Go to **Authentication**
+- Click **Add Identity Provider**
+- Choose **Microsoft**
+- Input:
+ - **Client ID**: The Application (client) ID from the app registration
+ - **Client Secret**: The secret value you generated in Certificates & Secrets from the app registration
+ - **Issuer URL**: `https://sts.windows.net//v2.0`
+ - **Allowed Token Audiences**: Usually the Application ID URI or Client ID
+- Click **Add**
+
+
+
+---
+
+## Conclusion
+
+You have now manually configured Azure App Registrations.
\ No newline at end of file
diff --git a/docs/images/AppAuthenticationIdentityProviderRestriction.png b/docs/images/AppAuthenticationIdentityProviderRestriction.png
new file mode 100644
index 000000000..2da9f4411
Binary files /dev/null and b/docs/images/AppAuthenticationIdentityProviderRestriction.png differ
diff --git a/docs/images/ManualRegisterAppWeb1.png b/docs/images/ManualRegisterAppWeb1.png
new file mode 100644
index 000000000..a6fe9e39c
Binary files /dev/null and b/docs/images/ManualRegisterAppWeb1.png differ
diff --git a/docs/images/ManualRegisterAppWeb3.png b/docs/images/ManualRegisterAppWeb3.png
new file mode 100644
index 000000000..8f83739c6
Binary files /dev/null and b/docs/images/ManualRegisterAppWeb3.png differ
diff --git a/docs/images/ManualRegisterAppWeb4.png b/docs/images/ManualRegisterAppWeb4.png
new file mode 100644
index 000000000..2ee3ee194
Binary files /dev/null and b/docs/images/ManualRegisterAppWeb4.png differ
diff --git a/docs/images/ManualRegisterAppWeb6.png b/docs/images/ManualRegisterAppWeb6.png
new file mode 100644
index 000000000..2fca2c873
Binary files /dev/null and b/docs/images/ManualRegisterAppWeb6.png differ
diff --git a/docs/images/readMe/architecture.png b/docs/images/readMe/architecture.png
index 3716611da..104b326f7 100644
Binary files a/docs/images/readMe/architecture.png and b/docs/images/readMe/architecture.png differ
diff --git a/infra/deploy_cosmos_db.bicep b/infra/deploy_cosmos_db.bicep
index d0b778862..6b26f820a 100644
--- a/infra/deploy_cosmos_db.bicep
+++ b/infra/deploy_cosmos_db.bicep
@@ -112,4 +112,3 @@ resource AZURE_COSMOSDB_ENABLE_FEEDBACK 'Microsoft.KeyVault/vaults/secrets@2021-
output cosmosAccountName string = cosmos.name
output cosmosDatabaseName string = databaseName
output cosmosContainerName string = collectionName
-
diff --git a/infra/deploy_sql_db.bicep b/infra/deploy_sql_db.bicep
index 27339fba6..34cb8688a 100644
--- a/infra/deploy_sql_db.bicep
+++ b/infra/deploy_sql_db.bicep
@@ -13,6 +13,7 @@ param sqlDBName string
param location string = solutionLocation
@description('The administrator username of the SQL logical server.')
+@secure()
param administratorLogin string = 'sqladmin'
@description('The administrator password of the SQL logical server.')
@@ -112,6 +113,6 @@ resource sqldbDatabasePwd 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview'
}
}
-output sqlServerName string = '${serverName}.database.windows.net'
+output sqlServerName string = serverName
output sqlDbName string = sqlDBName
-output sqlDbUser string = administratorLogin
+// output sqlDbUser string = administratorLogin
diff --git a/infra/main.bicep b/infra/main.bicep
index 54acda493..3e286e79f 100644
--- a/infra/main.bicep
+++ b/infra/main.bicep
@@ -226,9 +226,9 @@ module appserviceModule 'deploy_app_service.bicep' = {
AzureOpenAIEmbeddingkey:keyVault.getSecret('AZURE-OPENAI-KEY')
AzureOpenAIEmbeddingEndpoint:aifoundry.outputs.aiServicesTarget
USE_INTERNAL_STREAM:'True'
- SQLDB_SERVER:sqlDBModule.outputs.sqlServerName
+ SQLDB_SERVER:'${sqlDBModule.outputs.sqlServerName}.database.windows.net'
SQLDB_DATABASE:sqlDBModule.outputs.sqlDbName
- SQLDB_USERNAME:sqlDBModule.outputs.sqlDbUser
+ SQLDB_USERNAME:'sqladmin'
SQLDB_PASSWORD:keyVault.getSecret('SQLDB-PASSWORD')
AZURE_COSMOSDB_ACCOUNT: cosmosDBModule.outputs.cosmosAccountName
AZURE_COSMOSDB_CONVERSATIONS_CONTAINER: cosmosDBModule.outputs.cosmosContainerName
@@ -256,7 +256,7 @@ output STORAGE_CONTAINER_NAME string = storageAccountModule.outputs.storageConta
output KEY_VAULT_NAME string = keyvaultModule.outputs.keyvaultName
output COSMOSDB_ACCOUNT_NAME string = cosmosDBModule.outputs.cosmosAccountName
output RESOURCE_GROUP_NAME string = resourceGroup().name
-output SQLDB_SERVER string = replace(sqlDBModule.outputs.sqlServerName, '.database.windows.net','')
+output SQLDB_SERVER string = sqlDBModule.outputs.sqlServerName
output SQLDB_DATABASE string = sqlDBModule.outputs.sqlDbName
output MANAGEDINDENTITY_WEBAPP_NAME string = managedIdentityModule.outputs.managedIdentityWebAppOutput.name
output MANAGEDINDENTITY_WEBAPP_CLIENTID string = managedIdentityModule.outputs.managedIdentityWebAppOutput.clientId
diff --git a/infra/main.json b/infra/main.json
index 23da09d3b..0e4dc7597 100644
--- a/infra/main.json
+++ b/infra/main.json
@@ -5,7 +5,7 @@
"_generator": {
"name": "bicep",
"version": "0.34.44.8038",
- "templateHash": "6807899313442022071"
+ "templateHash": "1797657337218629559"
}
},
"parameters": {
@@ -39,8 +39,7 @@
"type": "string",
"defaultValue": "gpt-4o-mini",
"allowedValues": [
- "gpt-4o-mini",
- "gpt-4o"
+ "gpt-4o-mini"
],
"minLength": 1,
"metadata": {
@@ -91,8 +90,6 @@
"eastus2",
"francecentral",
"japaneast",
- "norwayeast",
- "southindia",
"swedencentral",
"uksouth",
"westus",
@@ -1933,7 +1930,7 @@
"_generator": {
"name": "bicep",
"version": "0.34.44.8038",
- "templateHash": "1848692139029312246"
+ "templateHash": "4179944107717925300"
}
},
"parameters": {
@@ -1969,7 +1966,7 @@
}
},
"administratorLogin": {
- "type": "string",
+ "type": "securestring",
"defaultValue": "sqladmin",
"metadata": {
"description": "The administrator username of the SQL logical server."
@@ -2086,15 +2083,11 @@
"outputs": {
"sqlServerName": {
"type": "string",
- "value": "[format('{0}.database.windows.net', parameters('serverName'))]"
+ "value": "[parameters('serverName')]"
},
"sqlDbName": {
"type": "string",
"value": "[parameters('sqlDBName')]"
- },
- "sqlDbUser": {
- "type": "string",
- "value": "[parameters('administratorLogin')]"
}
}
}
@@ -2233,13 +2226,13 @@
"value": "True"
},
"SQLDB_SERVER": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_sql_db'), '2022-09-01').outputs.sqlServerName.value]"
+ "value": "[format('{0}.database.windows.net', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_sql_db'), '2022-09-01').outputs.sqlServerName.value)]"
},
"SQLDB_DATABASE": {
"value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_sql_db'), '2022-09-01').outputs.sqlDbName.value]"
},
"SQLDB_USERNAME": {
- "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_sql_db'), '2022-09-01').outputs.sqlDbUser.value]"
+ "value": "sqladmin"
},
"SQLDB_PASSWORD": {
"reference": {
@@ -3085,7 +3078,7 @@
},
"SQLDB_SERVER": {
"type": "string",
- "value": "[replace(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_sql_db'), '2022-09-01').outputs.sqlServerName.value, '.database.windows.net', '')]"
+ "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_sql_db'), '2022-09-01').outputs.sqlServerName.value]"
},
"SQLDB_DATABASE": {
"type": "string",
diff --git a/infra/scripts/quota_check_params.sh b/infra/scripts/quota_check_params.sh
index a373ad1cb..62a2305c8 100644
--- a/infra/scripts/quota_check_params.sh
+++ b/infra/scripts/quota_check_params.sh
@@ -247,4 +247,4 @@ else
echo "➡️ To request a quota increase, visit: https://aka.ms/oai/stuquotarequest"
fi
-echo "✅ Script completed."
+echo "✅ Script completed."
\ No newline at end of file