Skip to content

Commit 9debd16

Browse files
Merge pull request #313 from microsoft/psl-pk-sqlsfi-mod
fix: Resolve SFI issue on Storage Account by using Azure Container Apps instead of Deployment Scripts
2 parents 6d17e79 + 8ba2e00 commit 9debd16

17 files changed

+363
-510
lines changed

.github/workflows/deploy-KMGeneric.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
az deployment group create \
113113
--resource-group ${{ env.RESOURCE_GROUP_NAME }} \
114114
--template-file infra/main.bicep \
115-
--parameters environmentName=${{env.SOLUTION_PREFIX}} contentUnderstandingLocation="westus" secondaryLocation="${{ env.AZURE_LOCATION }}" imageTag=${{ steps.determine_tag.outputs.tagname }}
115+
--parameters environmentName=${{env.SOLUTION_PREFIX}} contentUnderstandingLocation="swedencentral" secondaryLocation="${{ env.AZURE_LOCATION }}" imageTag=${{ steps.determine_tag.outputs.tagname }}
116116
117117

118118
- name: Extract AI Services and Key Vault Names

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ User story
1111

1212
This solution accelerator enables customers with large amounts of conversational data to improve decision-making by leveraging intelligence to uncover insights, relationships, and patterns from customer interactions. It empowers users to gain valuable knowledge and drive targeted business impact.
1313

14-
It leverages Azure AI Foundry, AI Content Understanding, Azure OpenAI, and Azure AI Search to transform large volumes of conversational data into actionable insights through topic modeling, key phrase extraction, speech-to-text transcription, and interactive chat experiences.
14+
It leverages Azure AI Foundry, Azure AI Content Understanding, Azure OpenAI Service, and Azure AI Search to transform large volumes of conversational data into actionable insights through topic modeling, key phrase extraction, speech-to-text transcription, and interactive chat experiences.
1515

1616

1717
### Technical key features
@@ -51,7 +51,7 @@ To deploy this solution accelerator, ensure you have access to an [Azure subscri
5151
Check the [Azure Products by Region](https://azure.microsoft.com/en-us/explore/global-infrastructure/products-by-region/?products=all&regions=all) page and select a **region** where the following services are available:
5252

5353
- Azure AI Foundry
54-
- Azure OpenAI Services
54+
- Azure OpenAI Service
5555
- Azure AI Search
5656
- Azure AI Content Understanding
5757
- Embedding Deployment Capacity
@@ -68,9 +68,9 @@ When you start the deployment, most parameters will have **default values**, but
6868
| **Setting** | **Description** | **Default value** |
6969
|------------|----------------|------------|
7070
| **Azure Region** | The region where resources will be created. | eastus |
71-
| **Environment Name** | A **3-20 character alphanumeric value** used to prefix resources. | kmtemplate |
72-
| **Content Understanding Location** | Select from a drop-down list of values. | westus |
73-
| **Secondary Location** | A **less busy** region for **Azure SQL and CosmosDB**, useful in case of availability constraints. | eastus2 |
71+
| **Environment Name** | A **3-20 character alphanumeric value** used to generate a unique ID to prefix the resources. | kmtemplate |
72+
| **Azure AI Content Understanding Location** | Select from a drop-down list of values. | swedencentral |
73+
| **Secondary Location** | A **less busy** region for **Azure SQL and Azure Cosmos DB**, useful in case of availability constraints. | eastus2 |
7474
| **Deployment Type** | Select from a drop-down list. | GlobalStandard |
7575
| **GPT Model** | Choose from **gpt-4, gpt-4o, gpt-4o-mini** | gpt-4o-mini |
7676
| **GPT Model Deployment Capacity** | Configure capacity for **GPT models**. | 30k |

docs/CustomizingAzdParameters.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ By default this template will use the environment name as the prefix to prevent
55

66
> To override any of the parameters, run `azd env set <key> <value>` before running `azd up`. On the first azd command, it will prompt you for the environment name. Be sure to choose 3-20 charaters alphanumeric unique name.
77
8-
Change the Content Understanding Location (allowed values: West US, Sweden Central, Australia East)
8+
Change the Content Understanding Location (allowed values: Sweden Central, Australia East)
99

1010
```shell
11-
azd env set AZURE_ENV_CU_LOCATION 'westus'
11+
azd env set AZURE_ENV_CU_LOCATION 'swedencentral'
1212
```
1313

1414
Change the Secondary Location (example: eastus2, westus2, etc.)
19.1 KB
Loading

infra/create-sql-user-and-role.bicep

Lines changed: 0 additions & 76 deletions
This file was deleted.

infra/deploy_ai_foundry.bicep

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ param keyVaultName string
55
param cuLocation string
66
param deploymentType string
77
param gptModelName string
8-
param gptModelVersion string
8+
param azureOpenAIApiVersion string
99
param gptDeploymentCapacity int
1010
param embeddingModel string
1111
param embeddingDeploymentCapacity int
@@ -358,6 +358,34 @@ resource storageroleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-
358358
}
359359
}
360360

361+
resource cognitiveServicesUserRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
362+
scope: aiServices_CU
363+
name: 'a97b65f3-24c7-4388-baec-2e87135dc908'
364+
}
365+
366+
resource cognitiveServicesUserAccessProj 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
367+
name: guid(resourceGroup().id, managedIdentityObjectId, cognitiveServicesUserRoleDefinition.id)
368+
properties: {
369+
principalId: managedIdentityObjectId
370+
roleDefinitionId: cognitiveServicesUserRoleDefinition.id
371+
principalType: 'ServicePrincipal'
372+
}
373+
}
374+
375+
resource aiDeveloperRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
376+
scope: aiServices_CU
377+
name: '64702f94-c441-49e6-a78b-ef80e0188fee'
378+
}
379+
380+
resource aiDeveloperAccessProj 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
381+
name: guid(resourceGroup().id, managedIdentityObjectId, aiDeveloperRoleDefinition.id)
382+
properties: {
383+
principalId: managedIdentityObjectId
384+
roleDefinitionId: aiDeveloperRoleDefinition.id
385+
principalType: 'ServicePrincipal'
386+
}
387+
}
388+
361389
resource aiHub 'Microsoft.MachineLearningServices/workspaces@2023-08-01-preview' = {
362390
name: aiHubName
363391
location: location
@@ -531,7 +559,7 @@ resource azureOpenAIApiVersionEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-0
531559
parent: keyVault
532560
name: 'AZURE-OPENAI-PREVIEW-API-VERSION'
533561
properties: {
534-
value: gptModelVersion //'2024-02-15-preview'
562+
value: azureOpenAIApiVersion //'2024-02-15-preview'
535563
}
536564
}
537565

@@ -671,4 +699,5 @@ output aiSearchService string = aiSearch.name
671699
output aiProjectName string = aiHubProject.name
672700

673701
output applicationInsightsId string = applicationInsights.id
702+
output logAnalyticsWorkspaceResourceName string = logAnalytics.name
674703
output storageAccountName string = storageNameCleaned
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
@description('Solution Name')
2+
param solutionName string
3+
@description('Specifies the location for resources.')
4+
param solutionLocation string
5+
param baseUrl string
6+
param managedIdentityObjectId string
7+
param managedIdentityClientId string
8+
param storageAccountName string
9+
param containerName string
10+
param containerAppName string = '${ solutionName }containerapp'
11+
param environmentName string = '${ solutionName }containerappenv'
12+
param imageName string = 'python:3.11-alpine'
13+
param setupCopyKbFiles string = '${baseUrl}infra/scripts/copy_kb_files.sh'
14+
param setupCreateIndexScriptsUrl string = '${baseUrl}infra/scripts/run_create_index_scripts.sh'
15+
param createSqlUserAndRoleScriptsUrl string = '${baseUrl}infra/scripts/add_user_scripts/create-sql-user-and-role.ps1'
16+
param keyVaultName string
17+
param sqlServerName string
18+
param sqlDbName string
19+
param sqlUsers array = [
20+
]
21+
param logAnalyticsWorkspaceResourceName string
22+
23+
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2020-10-01' existing = {
24+
name: logAnalyticsWorkspaceResourceName
25+
scope: resourceGroup()
26+
}
27+
28+
resource containerAppEnv 'Microsoft.App/managedEnvironments@2022-03-01' = {
29+
name: environmentName
30+
location: solutionLocation
31+
properties: {
32+
zoneRedundant: false
33+
appLogsConfiguration: {
34+
destination: 'log-analytics'
35+
logAnalyticsConfiguration: {
36+
customerId: logAnalytics.properties.customerId
37+
sharedKey: logAnalytics.listKeys().primarySharedKey
38+
}
39+
}
40+
}
41+
}
42+
43+
resource containerApp 'Microsoft.App/containerApps@2022-03-01' = {
44+
name: containerAppName
45+
location: solutionLocation
46+
identity: {
47+
type: 'UserAssigned'
48+
userAssignedIdentities: {
49+
'${managedIdentityObjectId}': {}
50+
}
51+
}
52+
properties: {
53+
managedEnvironmentId: containerAppEnv.id
54+
configuration: {
55+
ingress: {
56+
external: true
57+
targetPort: 80
58+
}
59+
60+
}
61+
template: {
62+
containers: [
63+
{
64+
name: containerAppName
65+
image: imageName
66+
resources: {
67+
cpu: 1
68+
memory: '2.0Gi'
69+
}
70+
command: [
71+
'/bin/sh', '-c', 'mkdir -p /scripts && apk add --no-cache curl bash jq py3-pip gcc musl-dev libffi-dev openssl-dev python3-dev && pip install --upgrade azure-cli && apk add --no-cache --virtual .build-deps build-base unixodbc-dev && curl -s -o msodbcsql18_18.4.1.1-1_amd64.apk https://download.microsoft.com/download/7/6/d/76de322a-d860-4894-9945-f0cc5d6a45f8/msodbcsql18_18.4.1.1-1_amd64.apk && curl -s -o mssql-tools18_18.4.1.1-1_amd64.apk https://download.microsoft.com/download/7/6/d/76de322a-d860-4894-9945-f0cc5d6a45f8/mssql-tools18_18.4.1.1-1_amd64.apk && apk add --allow-untrusted msodbcsql18_18.4.1.1-1_amd64.apk && apk add --allow-untrusted mssql-tools18_18.4.1.1-1_amd64.apk && curl -s -o /scripts/copy_kb_files.sh ${setupCopyKbFiles} && chmod +x /scripts/copy_kb_files.sh && sh -x /scripts/copy_kb_files.sh ${storageAccountName} ${containerName} ${baseUrl} ${managedIdentityClientId} && curl -s -o /scripts/run_create_index_scripts.sh ${setupCreateIndexScriptsUrl} && chmod +x /scripts/run_create_index_scripts.sh && sh -x /scripts/run_create_index_scripts.sh ${baseUrl} ${keyVaultName} ${managedIdentityClientId} && apk add --no-cache ca-certificates less ncurses-terminfo-base krb5-libs libgcc libintl libssl3 libstdc++ tzdata userspace-rcu zlib icu-libs curl && apk -X https://dl-cdn.alpinelinux.org/alpine/edge/main add --no-cache lttng-ust openssh-client && curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-musl-x64.tar.gz -o /tmp/powershell.tar.gz && mkdir -p /opt/microsoft/powershell/7 && tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && chmod +x /opt/microsoft/powershell/7/pwsh && ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && curl -s -o /scripts/create-sql-user-and-role.ps1 ${createSqlUserAndRoleScriptsUrl} && chmod +x /scripts/create-sql-user-and-role.ps1 && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[0].principalId} -DisplayName ${sqlUsers[0].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[0].databaseRoles[0]} && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[0].principalId} -DisplayName ${sqlUsers[0].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[0].databaseRoles[1]} && pwsh -File /scripts/create-sql-user-and-role.ps1 -SqlServerName ${sqlServerName} -SqlDatabaseName ${sqlDbName} -ClientId ${sqlUsers[1].principalId} -DisplayName ${sqlUsers[1].principalName} -ManagedIdentityClientId ${managedIdentityClientId} -DatabaseRole ${sqlUsers[1].databaseRoles[0]} && echo "Container app setup completed successfully."'
72+
]
73+
env: [
74+
{
75+
name: 'STORAGE_ACCOUNT_NAME'
76+
value: storageAccountName
77+
}
78+
{
79+
name: 'CONTAINER_NAME'
80+
value: containerName
81+
}
82+
{
83+
name:'APPSETTING_WEBSITE_SITE_NAME'
84+
value:'DUMMY'
85+
}
86+
]
87+
}
88+
]
89+
}
90+
}
91+
}

infra/deploy_sql_db.bicep

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,30 @@
44
param solutionName string
55
param solutionLocation string
66
param keyVaultName string
7-
param managedIdentityId string
87
param managedIdentityObjectId string
98
param managedIdentityName string
109

11-
// @description('The name of the SQL logical server.')
12-
// param serverName string = '${ solutionName }-sql-server'
13-
14-
// @description('The name of the SQL Database.')
15-
// param sqlDBName string = '${ solutionName }-sql-db'
16-
17-
// @description('Location for all resources.')
18-
// param location string = solutionLocation
19-
20-
// @description('The administrator username of the SQL logical server.')
21-
// param administratorLogin string = 'sqladmin'
22-
23-
// @description('The administrator password of the SQL logical server.')
24-
// @secure()
25-
// param administratorLoginPassword string = 'TestPassword_1234'
26-
2710
var serverName = '${ solutionName }-sql-server'
2811
var sqlDBName = '${ solutionName }-sql-db'
2912
var location = solutionLocation
3013
var administratorLogin = 'sqladmin'
3114
var administratorLoginPassword = 'TestPassword_1234'
3215

33-
param users array = [
34-
]
35-
3616
resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
3717
name: serverName
3818
location: location
3919
kind:'v12.0'
4020
properties: {
41-
administratorLogin: administratorLogin
42-
administratorLoginPassword: administratorLoginPassword
4321
publicNetworkAccess: 'Enabled'
4422
version: '12.0'
4523
restrictOutboundNetworkAccess: 'Disabled'
24+
administrators: {
25+
login: managedIdentityName
26+
sid: managedIdentityObjectId
27+
tenantId: subscription().tenantId
28+
administratorType: 'ActiveDirectory'
29+
azureADOnlyAuthentication: true
30+
}
4631
}
4732
}
4833

@@ -84,31 +69,6 @@ resource sqlDB 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
8469
}
8570
}
8671

87-
resource SQLServerName_ActiveDirectory 'Microsoft.Sql/servers/administrators@2023-08-01-preview' = {
88-
parent: sqlServer
89-
name: 'ActiveDirectory'
90-
properties: {
91-
login: managedIdentityName
92-
sid: managedIdentityObjectId
93-
tenantId: subscription().tenantId
94-
administratorType: 'ActiveDirectory'
95-
}
96-
}
97-
98-
module sqluser 'create-sql-user-and-role.bicep' = [for user in users: {
99-
name: 'sqluser-${guid(location, user.principalId, user.principalName, sqlDBName, sqlServer.name)}'
100-
params: {
101-
managedIdentityId: managedIdentityId
102-
principalId: user.principalId
103-
principalName: user.principalName
104-
sqlDatabaseName: sqlDBName
105-
location: location
106-
sqlServerName: sqlServer.name
107-
databaseRoles: user.databaseRoles
108-
}
109-
dependsOn: [ sqlDB, SQLServerName_ActiveDirectory ]
110-
}]
111-
11272
resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
11373
name: keyVaultName
11474
}
@@ -148,10 +108,3 @@ resource sqldbDatabasePwd 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview'
148108
output sqlServerName string = '${serverName}.database.windows.net'
149109
output sqlDbName string = sqlDBName
150110
output sqlDbUser string = administratorLogin
151-
152-
// output sqlDbOutput object = {
153-
// sqlServerName: '${serverName}.database.windows.net'
154-
// sqlDbName: sqlDBName
155-
// sqlDbUser: administratorLogin
156-
// sqlDbPwd: administratorLoginPassword
157-
// }

0 commit comments

Comments
 (0)