diff --git a/infra/app/adminweb.bicep b/infra/app/adminweb.bicep index 56397ed6f..3d494a39d 100644 --- a/infra/app/adminweb.bicep +++ b/infra/app/adminweb.bicep @@ -28,6 +28,7 @@ param speechKeyName string = '' param authType string param dockerFullImageName string = '' param useDocker bool = dockerFullImageName != '' +param databaseType string = 'CosmosDB' // 'CosmosDB' or 'PostgreSQL' var azureFormRecognizerInfoUpdated = useKeyVault ? azureFormRecognizerInfo @@ -68,6 +69,7 @@ module adminweb '../core/host/appservice.bicep' = { scmDoBuildDuringDeployment: useDocker ? false : true applicationInsightsName: applicationInsightsName appServicePlanId: appServicePlanId + managedIdentity: databaseType == 'PostgreSQL' appSettings: union(appSettings, { AZURE_AUTH_TYPE: authType USE_KEY_VAULT: useKeyVault ? useKeyVault : '' diff --git a/infra/app/web.bicep b/infra/app/web.bicep index 90b50086c..fd89d972b 100644 --- a/infra/app/web.bicep +++ b/infra/app/web.bicep @@ -168,6 +168,7 @@ module web '../core/host/appservice.bicep' = { dockerFullImageName: dockerFullImageName scmDoBuildDuringDeployment: useDocker ? false : true healthCheckPath: healthCheckPath + managedIdentity: databaseType == 'PostgreSQL' } } @@ -223,7 +224,7 @@ resource cosmosRoleDefinition 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefi name: '${json(appSettings.AZURE_COSMOSDB_INFO).accountName}/00000000-0000-0000-0000-000000000002' } -module cosmosUserRole '../core/database/cosmos-sql-role-assign.bicep' = { +module cosmosUserRole '../core/database/cosmos-sql-role-assign.bicep' = if(databaseType == 'CosmosDB') { name: 'cosmos-sql-user-role-${web.name}' params: { accountName: json(appSettings.AZURE_COSMOSDB_INFO).accountName diff --git a/infra/core/database/deploy_create_table_script.bicep b/infra/core/database/deploy_create_table_script.bicep index b1fc012df..4b2718af2 100644 --- a/infra/core/database/deploy_create_table_script.bicep +++ b/infra/core/database/deploy_create_table_script.bicep @@ -5,6 +5,9 @@ param baseUrl string param keyVaultName string param identity string param postgresSqlServerName string +param webAppPrincipalName string +param adminAppPrincipalName string +param managedIdentityName string resource create_index 'Microsoft.Resources/deploymentScripts@2020-10-01' = { kind:'AzureCLI' @@ -19,7 +22,7 @@ resource create_index 'Microsoft.Resources/deploymentScripts@2020-10-01' = { properties: { azCliVersion: '2.52.0' primaryScriptUri: '${baseUrl}scripts/run_create_table_script.sh' - arguments: '${baseUrl} ${keyVaultName} ${resourceGroup().name} ${postgresSqlServerName}' // Specify any arguments for the script + arguments: '${baseUrl} ${keyVaultName} ${resourceGroup().name} ${postgresSqlServerName} ${webAppPrincipalName} ${adminAppPrincipalName} ${managedIdentityName}' // Specify any arguments for the script timeout: 'PT1H' // Specify the desired timeout duration retentionInterval: 'PT1H' // Specify the desired retention interval cleanupPreference:'OnSuccess' diff --git a/infra/core/database/postgresdb.bicep b/infra/core/database/postgresdb.bicep index 32a2af714..557732cd8 100644 --- a/infra/core/database/postgresdb.bicep +++ b/infra/core/database/postgresdb.bicep @@ -65,7 +65,7 @@ resource delayScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { kind: 'AzurePowerShell' properties: { azPowerShellVersion: '3.0' - scriptContent: 'start-sleep -Seconds 180' + scriptContent: 'start-sleep -Seconds 300' cleanupPreference: 'Always' retentionInterval: 'PT1H' } diff --git a/infra/main.bicep b/infra/main.bicep index f164aeb4b..2d061e9d9 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -344,7 +344,7 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { } // ========== Managed Identity ========== // -module managedIdentityModule './core/security/managed-identity.bicep' = if (databaseType == 'postgres') { +module managedIdentityModule './core/security/managed-identity.bicep' = if (databaseType == 'PostgreSQL') { name: 'deploy_managed_identity' params: { solutionName: resourceToken @@ -353,7 +353,7 @@ module managedIdentityModule './core/security/managed-identity.bicep' = if (data scope: rg } -module cosmosDBModule './core/database/cosmosdb.bicep' = if (databaseType == 'cosmos') { +module cosmosDBModule './core/database/cosmosdb.bicep' = if (databaseType == 'CosmosDB') { name: 'deploy_cosmos_db' params: { name: azureCosmosDBAccountName @@ -830,6 +830,7 @@ module adminweb './app/adminweb.bicep' = if (hostingModel == 'code') { useKeyVault: useKeyVault keyVaultName: useKeyVault || authType == 'rbac' ? keyvault.outputs.name : '' authType: authType + databaseType: databaseType appSettings: { AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? computerVision.outputs.endpoint : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion @@ -903,6 +904,7 @@ module adminweb_docker './app/adminweb.bicep' = if (hostingModel == 'container') useKeyVault: useKeyVault keyVaultName: useKeyVault || authType == 'rbac' ? keyvault.outputs.name : '' authType: authType + databaseType: databaseType appSettings: { AZURE_COMPUTER_VISION_ENDPOINT: useAdvancedImageProcessing ? computerVision.outputs.endpoint : '' AZURE_COMPUTER_VISION_VECTORIZE_IMAGE_API_VERSION: computerVisionVectorizeImageApiVersion @@ -1247,7 +1249,7 @@ module machineLearning 'app/machinelearning.bicep' = if (orchestrationStrategy = } } -module createIndex './core/database/deploy_create_table_script.bicep' = if (databaseType == 'postgres') { +module createIndex './core/database/deploy_create_table_script.bicep' = if (databaseType == 'PostgreSQL') { name: 'deploy_create_table_script' params: { solutionLocation: location @@ -1255,9 +1257,14 @@ module createIndex './core/database/deploy_create_table_script.bicep' = if (data baseUrl: baseUrl keyVaultName: keyvault.outputs.name postgresSqlServerName: postgresDBModule.outputs.postgresDbOutput.postgresSQLName + webAppPrincipalName: hostingModel == 'code' ? web.outputs.FRONTEND_API_NAME : web_docker.outputs.FRONTEND_API_NAME + adminAppPrincipalName: hostingModel == 'code' ? adminweb.outputs.WEBSITE_ADMIN_NAME : adminweb_docker.outputs.WEBSITE_ADMIN_NAME + managedIdentityName: managedIdentityModule.outputs.managedIdentityOutput.name } scope: rg - dependsOn: [keyvault, postgresDBModule, storekeys] + dependsOn: hostingModel == 'code' ? [keyvault, postgresDBModule, storekeys, web, adminweb] : [ + [keyvault, postgresDBModule, storekeys, web_docker, adminweb_docker] + ] } output APPLICATIONINSIGHTS_CONNECTION_STRING string = monitoring.outputs.applicationInsightsConnectionString diff --git a/infra/main.json b/infra/main.json index cb7269c61..328f4b9a1 100644 --- a/infra/main.json +++ b/infra/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "14534949706227721920" + "templateHash": "15176273744623029817" } }, "parameters": { @@ -690,7 +690,7 @@ "tags": "[variables('tags')]" }, { - "condition": "[equals(parameters('databaseType'), 'postgres')]", + "condition": "[equals(parameters('databaseType'), 'PostgreSQL')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "deploy_managed_identity", @@ -783,7 +783,7 @@ ] }, { - "condition": "[equals(parameters('databaseType'), 'cosmos')]", + "condition": "[equals(parameters('databaseType'), 'CosmosDB')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "deploy_cosmos_db", @@ -977,7 +977,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "7878676541226628436" + "templateHash": "17455459966134467610" } }, "parameters": { @@ -1091,7 +1091,7 @@ "kind": "AzurePowerShell", "properties": { "azPowerShellVersion": "3.0", - "scriptContent": "start-sleep -Seconds 180", + "scriptContent": "start-sleep -Seconds 300", "cleanupPreference": "Always", "retentionInterval": "PT1H" }, @@ -2671,7 +2671,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "12192862160861363431" + "templateHash": "13375017292788108601" } }, "parameters": { @@ -2852,6 +2852,9 @@ "scmDoBuildDuringDeployment": "[if(parameters('useDocker'), createObject('value', false()), createObject('value', true()))]", "healthCheckPath": { "value": "[parameters('healthCheckPath')]" + }, + "managedIdentity": { + "value": "[equals(parameters('databaseType'), 'PostgreSQL')]" } }, "template": { @@ -3487,6 +3490,7 @@ ] }, { + "condition": "[equals(parameters('databaseType'), 'CosmosDB')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('cosmos-sql-user-role-{0}', format('{0}-app-module', parameters('name')))]", @@ -3667,7 +3671,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "12192862160861363431" + "templateHash": "13375017292788108601" } }, "parameters": { @@ -3848,6 +3852,9 @@ "scmDoBuildDuringDeployment": "[if(parameters('useDocker'), createObject('value', false()), createObject('value', true()))]", "healthCheckPath": { "value": "[parameters('healthCheckPath')]" + }, + "managedIdentity": { + "value": "[equals(parameters('databaseType'), 'PostgreSQL')]" } }, "template": { @@ -4483,6 +4490,7 @@ ] }, { + "condition": "[equals(parameters('databaseType'), 'CosmosDB')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('cosmos-sql-user-role-{0}', format('{0}-app-module', parameters('name')))]", @@ -4647,6 +4655,9 @@ "authType": { "value": "[parameters('authType')]" }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, "appSettings": { "value": { "AZURE_COMPUTER_VISION_ENDPOINT": "[if(parameters('useAdvancedImageProcessing'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'computerVision'), '2022-09-01').outputs.endpoint.value, '')]", @@ -4700,7 +4711,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "12567732396765618168" + "templateHash": "1041527018081544410" } }, "parameters": { @@ -4815,6 +4826,10 @@ "useDocker": { "type": "bool", "defaultValue": "[not(equals(parameters('dockerFullImageName'), ''))]" + }, + "databaseType": { + "type": "string", + "defaultValue": "CosmosDB" } }, "resources": [ @@ -4860,6 +4875,9 @@ "appServicePlanId": { "value": "[parameters('appServicePlanId')]" }, + "managedIdentity": { + "value": "[equals(parameters('databaseType'), 'PostgreSQL')]" + }, "appSettings": { "value": "[union(parameters('appSettings'), createObject('AZURE_AUTH_TYPE', parameters('authType'), 'USE_KEY_VAULT', if(parameters('useKeyVault'), parameters('useKeyVault'), ''), 'AZURE_OPENAI_API_KEY', if(parameters('useKeyVault'), parameters('openAIKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('azureOpenAIName')), '2023-05-01').key1), 'AZURE_SEARCH_KEY', if(parameters('useKeyVault'), parameters('searchKeyName'), listAdminKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Search/searchServices', parameters('azureAISearchName')), '2021-04-01-preview').primaryKey), 'AZURE_BLOB_STORAGE_INFO', if(parameters('useKeyVault'), parameters('azureBlobStorageInfo'), replace(parameters('azureBlobStorageInfo'), '$STORAGE_ACCOUNT_KEY', listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)), 'AZURE_FORM_RECOGNIZER_INFO', if(parameters('useKeyVault'), parameters('azureFormRecognizerInfo'), replace(parameters('azureFormRecognizerInfo'), '$FORM_RECOGNIZER_KEY', listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('formRecognizerName')), '2023-05-01').key1)), 'AZURE_CONTENT_SAFETY_KEY', if(parameters('useKeyVault'), parameters('contentSafetyKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('contentSafetyName')), '2023-05-01').key1), 'AZURE_SPEECH_SERVICE_KEY', if(parameters('useKeyVault'), parameters('speechKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('speechServiceName')), '2023-05-01').key1), 'AZURE_COMPUTER_VISION_KEY', if(or(parameters('useKeyVault'), equals(parameters('computerVisionName'), '')), parameters('computerVisionKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('computerVisionName')), '2023-05-01').key1)))]" } @@ -5595,6 +5613,9 @@ "authType": { "value": "[parameters('authType')]" }, + "databaseType": { + "value": "[parameters('databaseType')]" + }, "appSettings": { "value": { "AZURE_COMPUTER_VISION_ENDPOINT": "[if(parameters('useAdvancedImageProcessing'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'computerVision'), '2022-09-01').outputs.endpoint.value, '')]", @@ -5648,7 +5669,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "12567732396765618168" + "templateHash": "1041527018081544410" } }, "parameters": { @@ -5763,6 +5784,10 @@ "useDocker": { "type": "bool", "defaultValue": "[not(equals(parameters('dockerFullImageName'), ''))]" + }, + "databaseType": { + "type": "string", + "defaultValue": "CosmosDB" } }, "resources": [ @@ -5808,6 +5833,9 @@ "appServicePlanId": { "value": "[parameters('appServicePlanId')]" }, + "managedIdentity": { + "value": "[equals(parameters('databaseType'), 'PostgreSQL')]" + }, "appSettings": { "value": "[union(parameters('appSettings'), createObject('AZURE_AUTH_TYPE', parameters('authType'), 'USE_KEY_VAULT', if(parameters('useKeyVault'), parameters('useKeyVault'), ''), 'AZURE_OPENAI_API_KEY', if(parameters('useKeyVault'), parameters('openAIKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('azureOpenAIName')), '2023-05-01').key1), 'AZURE_SEARCH_KEY', if(parameters('useKeyVault'), parameters('searchKeyName'), listAdminKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Search/searchServices', parameters('azureAISearchName')), '2021-04-01-preview').primaryKey), 'AZURE_BLOB_STORAGE_INFO', if(parameters('useKeyVault'), parameters('azureBlobStorageInfo'), replace(parameters('azureBlobStorageInfo'), '$STORAGE_ACCOUNT_KEY', listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)), 'AZURE_FORM_RECOGNIZER_INFO', if(parameters('useKeyVault'), parameters('azureFormRecognizerInfo'), replace(parameters('azureFormRecognizerInfo'), '$FORM_RECOGNIZER_KEY', listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('formRecognizerName')), '2023-05-01').key1)), 'AZURE_CONTENT_SAFETY_KEY', if(parameters('useKeyVault'), parameters('contentSafetyKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('contentSafetyName')), '2023-05-01').key1), 'AZURE_SPEECH_SERVICE_KEY', if(parameters('useKeyVault'), parameters('speechKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('speechServiceName')), '2023-05-01').key1), 'AZURE_COMPUTER_VISION_KEY', if(or(parameters('useKeyVault'), equals(parameters('computerVisionName'), '')), parameters('computerVisionKeyName'), listKeys(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.CognitiveServices/accounts', parameters('computerVisionName')), '2023-05-01').key1)))]" } @@ -11974,7 +12002,7 @@ ] }, { - "condition": "[equals(parameters('databaseType'), 'postgres')]", + "condition": "[equals(parameters('databaseType'), 'PostgreSQL')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "deploy_create_table_script", @@ -11999,6 +12027,11 @@ }, "postgresSqlServerName": { "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'deploy_postgres_sql'), '2022-09-01').outputs.postgresDbOutput.value.postgresSQLName]" + }, + "webAppPrincipalName": "[if(equals(parameters('hostingModel'), 'code'), createObject('value', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', parameters('websiteName')), '2022-09-01').outputs.FRONTEND_API_NAME.value), createObject('value', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', format('{0}-docker', parameters('websiteName'))), '2022-09-01').outputs.FRONTEND_API_NAME.value))]", + "adminAppPrincipalName": "[if(equals(parameters('hostingModel'), 'code'), createObject('value', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', parameters('adminWebsiteName')), '2022-09-01').outputs.WEBSITE_ADMIN_NAME.value), createObject('value', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', format('{0}-docker', parameters('adminWebsiteName'))), '2022-09-01').outputs.WEBSITE_ADMIN_NAME.value))]", + "managedIdentityName": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'deploy_managed_identity'), '2022-09-01').outputs.managedIdentityOutput.value.name]" } }, "template": { @@ -12008,7 +12041,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "754015545513025215" + "templateHash": "5666855677780801837" } }, "parameters": { @@ -12029,6 +12062,15 @@ }, "postgresSqlServerName": { "type": "string" + }, + "webAppPrincipalName": { + "type": "string" + }, + "adminAppPrincipalName": { + "type": "string" + }, + "managedIdentityName": { + "type": "string" } }, "resources": [ @@ -12047,7 +12089,7 @@ "properties": { "azCliVersion": "2.52.0", "primaryScriptUri": "[format('{0}scripts/run_create_table_script.sh', parameters('baseUrl'))]", - "arguments": "[format('{0} {1} {2} {3}', parameters('baseUrl'), parameters('keyVaultName'), resourceGroup().name, parameters('postgresSqlServerName'))]", + "arguments": "[format('{0} {1} {2} {3} {4} {5} {6}', parameters('baseUrl'), parameters('keyVaultName'), resourceGroup().name, parameters('postgresSqlServerName'), parameters('webAppPrincipalName'), parameters('adminAppPrincipalName'), parameters('managedIdentityName'))]", "timeout": "PT1H", "retentionInterval": "PT1H", "cleanupPreference": "OnSuccess" @@ -12057,11 +12099,15 @@ } }, "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', parameters('adminWebsiteName'))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', format('{0}-docker', parameters('adminWebsiteName')))]", "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'keyvault')]", "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'deploy_managed_identity')]", "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'deploy_postgres_sql')]", "[subscriptionResourceId('Microsoft.Resources/resourceGroups', variables('rgName'))]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'storekeys')]" + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', 'storekeys')]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', parameters('websiteName'))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, variables('rgName')), 'Microsoft.Resources/deployments', format('{0}-docker', parameters('websiteName')))]" ] } ], diff --git a/scripts/data_scripts/create_postgres_tables.py b/scripts/data_scripts/create_postgres_tables.py index 92df9fa93..8ae2f7c6e 100644 --- a/scripts/data_scripts/create_postgres_tables.py +++ b/scripts/data_scripts/create_postgres_tables.py @@ -2,8 +2,12 @@ from azure.keyvault.secrets import SecretClient from azure.identity import DefaultAzureCredential import psycopg2 +from psycopg2 import sql key_vault_name = "kv_to-be-replaced" +principal_name = "webAppPrincipalName" +admin_principal_name = "adminAppPrincipalName" +user = "managedIdentityName" def get_secrets_from_kv(kv_name, secret_name): credential = DefaultAzureCredential() @@ -13,10 +17,48 @@ def get_secrets_from_kv(kv_name, secret_name): return secret_client.get_secret(secret_name).value +def grant_permissions(cursor, dbname, schema_name, principal_name): + """ + Grants database and schema-level permissions to a specified principal. + + Parameters: + - cursor: psycopg2 cursor object for database operations. + - dbname: Name of the database to grant CONNECT permission. + - schema_name: Name of the schema to grant table-level permissions. + - principal_name: Name of the principal (role or user) to grant permissions. + """ + + add_principal_user_query = sql.SQL("SELECT * FROM pgaadauth_create_principal({principal}, false, false)") + cursor.execute( + add_principal_user_query.format( + principal=sql.Literal(principal_name), + ) + ) + + # Grant CONNECT on database + grant_connect_query = sql.SQL("GRANT CONNECT ON DATABASE {database} TO {principal}") + cursor.execute( + grant_connect_query.format( + database=sql.Identifier(dbname), + principal=sql.Identifier(principal_name), + ) + ) + print(f"Granted CONNECT on database '{dbname}' to '{principal_name}'") + + # Grant SELECT, INSERT, UPDATE, DELETE on schema tables + grant_permissions_query = sql.SQL( + "GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA {schema} TO {principal}" + ) + cursor.execute( + grant_permissions_query.format( + schema=sql.Identifier(schema_name), + principal=sql.Identifier(principal_name), + ) + ) + postgres_details = json.loads(get_secrets_from_kv(key_vault_name, "AZURE-POSTGRESQL-INFO")) host = postgres_details.get("host", "") -user = postgres_details.get("user", "") -dbname = postgres_details.get("dbname", "") +dbname = postgres_details.get("database", "") password = postgres_details.get("password", "") # Acquire the access token @@ -24,12 +66,17 @@ def get_secrets_from_kv(kv_name, secret_name): access_token = cred.get_token("https://ossrdbms-aad.database.windows.net/.default") # Combine the token with the connection string to establish the connection. -conn_string = "host={0} user={1} dbname={2} password={3}".format( - host, user, dbname, password +conn_string = "host={0} user={1} dbname={2} password={3} sslmode=require".format( + host, user, dbname, access_token.token ) conn = psycopg2.connect(conn_string) cursor = conn.cursor() +grant_permissions(cursor, dbname, "public", principal_name) +conn.commit() +# grant_permissions(cursor, dbname, "public", admin_principal_name) +# conn.commit() + # Drop and recreate the conversations table cursor.execute("DROP TABLE IF EXISTS conversations") conn.commit() diff --git a/scripts/run_create_table_script.sh b/scripts/run_create_table_script.sh index 1d3bd2063..31bc4cf61 100644 --- a/scripts/run_create_table_script.sh +++ b/scripts/run_create_table_script.sh @@ -8,6 +8,9 @@ requirementFile="requirements.txt" requirementFileUrl=${baseUrl}"scripts/data_scripts/requirements.txt" resourceGroup="$3" serverName="$4" +webAppPrincipalName="$5" +adminAppPrincipalName="$6" +managedIdentityName="$7" echo "Script Started" @@ -27,9 +30,10 @@ echo "Download completed" #Replace key vault name sed -i "s/kv_to-be-replaced/${keyvaultName}/g" "create_postgres_tables.py" +sed -i "s/webAppPrincipalName/${webAppPrincipalName}/g" "create_postgres_tables.py" +sed -i "s/adminAppPrincipalName/${adminAppPrincipalName}/g" "create_postgres_tables.py" +sed -i "s/managedIdentityName/${managedIdentityName}/g" "create_postgres_tables.py" pip install -r requirements.txt -pip show azure-identity - python create_postgres_tables.py