From bd32fd682462a06704b1eb7ce138478d4441627d Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 12:57:18 +0100 Subject: [PATCH 01/11] chore: restructure bicep types --- .azure/bicepconfig.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .azure/bicepconfig.json diff --git a/.azure/bicepconfig.json b/.azure/bicepconfig.json new file mode 100644 index 000000000..c472c442f --- /dev/null +++ b/.azure/bicepconfig.json @@ -0,0 +1,17 @@ +{ + // See https://aka.ms/bicep/config for more information on Bicep configuration options + // Press CTRL+SPACE/CMD+SPACE at any location to see Intellisense suggestions + "analyzers": { + "core": { + "rules": { + "no-unused-params": { + "level": "warning" + } + } + } + }, + "experimentalFeaturesEnabled": { + "compileTimeImports": true, + "userDefinedFunctions": true + } +} \ No newline at end of file From 53af77fae6f2e9881995792d158d332f4a4525a9 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 13:42:49 +0100 Subject: [PATCH 02/11] chore: restructure bicep params --- .azure/infrastructure/main.bicep | 89 ++++--------------- .azure/infrastructure/production.bicepparam | 28 ++++-- .azure/infrastructure/soak.bicepparam | 28 ++++-- .azure/infrastructure/staging.bicepparam | 28 ++++-- .azure/infrastructure/test.bicepparam | 28 ++++-- .azure/modules/appConfiguration/create.bicep | 35 ++++---- .../modules/applicationInsights/create.bicep | 11 ++- .../modules/functionApp/slackNotifier.bicep | 17 ++-- .azure/modules/keyvault/create.bicep | 14 +-- .azure/modules/postgreSql/create.bicep | 14 +-- 10 files changed, 148 insertions(+), 144 deletions(-) diff --git a/.azure/infrastructure/main.bicep b/.azure/infrastructure/main.bicep index 4ad48b15a..cb1a7a642 100644 --- a/.azure/infrastructure/main.bicep +++ b/.azure/infrastructure/main.bicep @@ -19,67 +19,20 @@ param sourceKeyVaultResourceGroup string @minLength(3) param sourceKeyVaultName string -@allowed( - [ - 'premium' - 'standard' - ] -) -param keyVaultSKUName string - -@allowed([ - 'A' -]) -param keyVaultSKUFamily string - -@allowed([ - 'standard' -]) -param appConfigurationSKUName string - -@allowed([ - 'CapacityReservation' - 'Free' - 'LACluster' - 'PerGB2018' - 'PerNode' - 'Premium' - 'Standalone' - 'Standard' -]) -param appInsightsSKUName string - -@allowed([ - 'Standard_LRS' - 'Standard_GRS' - 'Standard_RAGRS' - 'Standard_ZRS' - 'Premium_LRS' - 'Premium_ZRS' -]) -param slackNotifierStorageAccountSKUName string - -@allowed([ - 'Y1' -]) -param slackNotifierApplicationServicePlanSKUName string - -@allowed([ - 'Dynamic' - -]) -param slackNotifierApplicationServicePlanSKUTier string - -@allowed([ - 'Standard_B1ms' -]) -param postgresServerSKUName string -@allowed([ - 'Burstable' - 'GeneralPurpose' - 'MemoryOptimized' -]) -param postgresServerSKUTier string +import {Sku as KeyVaultSku} from '../modules/keyvault/create.bicep' +param keyVaultSku KeyVaultSku + +import {Sku as AppConfigurationSku} from '../modules/appConfiguration/create.bicep' +param appConfigurationSku AppConfigurationSku + +import {Sku as AppInsightsSku} from '../modules/applicationInsights/create.bicep' +param appInsightsSku AppInsightsSku + +import {Sku as SlackNotifierSku} from '../modules/functionApp/slackNotifier.bicep' +param slackNotifierSku SlackNotifierSku + +import {Sku as PostgresSku} from '../modules/postgreSql/create.bicep' +param postgresSku PostgresSku var secrets = { dialogportenPgAdminPassword: dialogportenPgAdminPassword @@ -102,8 +55,7 @@ module keyVaultModule '../modules/keyvault/create.bicep' = { params: { namePrefix: namePrefix location: location - skuName: keyVaultSKUName - skuFamily: keyVaultSKUFamily + sku: keyVaultSku } } @@ -113,7 +65,7 @@ module appConfiguration '../modules/appConfiguration/create.bicep' = { params: { namePrefix: namePrefix location: location - skuName: appConfigurationSKUName + sku: appConfigurationSku } } @@ -123,7 +75,7 @@ module appInsights '../modules/applicationInsights/create.bicep' = { params: { namePrefix: namePrefix location: location - skuName: appInsightsSKUName + sku: appInsightsSku } } @@ -156,8 +108,7 @@ module postgresql '../modules/postgreSql/create.bicep' = { srcKeyVault: srcKeyVault srcSecretName: 'dialogportenPgAdminPassword${environment}' administratorLoginPassword: contains(keyVaultSourceKeys, 'dialogportenPgAdminPassword${environment}') ? srcKeyVaultResource.getSecret('dialogportenPgAdminPassword${environment}') : secrets.dialogportenPgAdminPassword - skuName: postgresServerSKUName - skuTier: postgresServerSKUTier + sku: postgresSku } } @@ -194,9 +145,7 @@ module slackNotifier '../modules/functionApp/slackNotifier.bicep' = { keyVaultName: keyVaultModule.outputs.name namePrefix: namePrefix applicationInsightsName: appInsights.outputs.appInsightsName - storageAccountSKUName: slackNotifierStorageAccountSKUName - applicationServicePlanSKUName: slackNotifierApplicationServicePlanSKUName - applicationServicePlanSKUTier: slackNotifierApplicationServicePlanSKUTier + sku: slackNotifierSku } } diff --git a/.azure/infrastructure/production.bicepparam b/.azure/infrastructure/production.bicepparam index 66f2a64b2..63a21d428 100644 --- a/.azure/infrastructure/production.bicepparam +++ b/.azure/infrastructure/production.bicepparam @@ -11,12 +11,22 @@ param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RE param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME') // SKUs -param keyVaultSKUName = 'standard' -param keyVaultSKUFamily = 'A' -param appConfigurationSKUName = 'standard' -param appInsightsSKUName = 'PerGB2018' -param slackNotifierStorageAccountSKUName = 'Standard_LRS' -param slackNotifierApplicationServicePlanSKUName = 'Y1' -param slackNotifierApplicationServicePlanSKUTier = 'Dynamic' -param postgresServerSKUName = 'Standard_B1ms' -param postgresServerSKUTier = 'Burstable' +param keyVaultSku = { + name: 'standard' + family: 'A' +} +param appConfigurationSku = { + name: 'standard' +} +param appInsightsSku = { + name: 'PerGB2018' +} +param slackNotifierSku = { + storageAccountName: 'Standard_LRS' + applicationServicePlanName: 'Y1' + applicationServicePlanTier: 'Dynamic' +} +param postgresSku = { + name: 'Standard_B1ms' + tier: 'Burstable' +} diff --git a/.azure/infrastructure/soak.bicepparam b/.azure/infrastructure/soak.bicepparam index effbfebd5..609096cf1 100644 --- a/.azure/infrastructure/soak.bicepparam +++ b/.azure/infrastructure/soak.bicepparam @@ -11,12 +11,22 @@ param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RE param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME') // SKUs -param keyVaultSKUName = 'standard' -param keyVaultSKUFamily = 'A' -param appConfigurationSKUName = 'standard' -param appInsightsSKUName = 'PerGB2018' -param slackNotifierStorageAccountSKUName = 'Standard_LRS' -param slackNotifierApplicationServicePlanSKUName = 'Y1' -param slackNotifierApplicationServicePlanSKUTier = 'Dynamic' -param postgresServerSKUName = 'Standard_B1ms' -param postgresServerSKUTier = 'Burstable' +param keyVaultSku = { + name: 'standard' + family: 'A' +} +param appConfigurationSku = { + name: 'standard' +} +param appInsightsSku = { + name: 'PerGB2018' +} +param slackNotifierSku = { + storageAccountName: 'Standard_LRS' + applicationServicePlanName: 'Y1' + applicationServicePlanTier: 'Dynamic' +} +param postgresSku = { + name: 'Standard_B1ms' + tier: 'Burstable' +} diff --git a/.azure/infrastructure/staging.bicepparam b/.azure/infrastructure/staging.bicepparam index 301897e84..07b54f198 100644 --- a/.azure/infrastructure/staging.bicepparam +++ b/.azure/infrastructure/staging.bicepparam @@ -11,12 +11,22 @@ param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RE param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME') // SKUs -param keyVaultSKUName = 'standard' -param keyVaultSKUFamily = 'A' -param appConfigurationSKUName = 'standard' -param appInsightsSKUName = 'PerGB2018' -param slackNotifierStorageAccountSKUName = 'Standard_LRS' -param slackNotifierApplicationServicePlanSKUName = 'Y1' -param slackNotifierApplicationServicePlanSKUTier = 'Dynamic' -param postgresServerSKUName = 'Standard_B1ms' -param postgresServerSKUTier = 'Burstable' +param keyVaultSku = { + name: 'standard' + family: 'A' +} +param appConfigurationSku = { + name: 'standard' +} +param appInsightsSku = { + name: 'PerGB2018' +} +param slackNotifierSku = { + storageAccountName: 'Standard_LRS' + applicationServicePlanName: 'Y1' + applicationServicePlanTier: 'Dynamic' +} +param postgresSku = { + name: 'Standard_B1ms' + tier: 'Burstable' +} diff --git a/.azure/infrastructure/test.bicepparam b/.azure/infrastructure/test.bicepparam index 618cd5046..19b5e658c 100644 --- a/.azure/infrastructure/test.bicepparam +++ b/.azure/infrastructure/test.bicepparam @@ -11,12 +11,22 @@ param sourceKeyVaultResourceGroup = readEnvironmentVariable('SOURCE_KEY_VAULT_RE param sourceKeyVaultName = readEnvironmentVariable('SOURCE_KEY_VAULT_NAME') // SKUs -param keyVaultSKUName = 'standard' -param keyVaultSKUFamily = 'A' -param appConfigurationSKUName = 'standard' -param appInsightsSKUName = 'PerGB2018' -param slackNotifierStorageAccountSKUName = 'Standard_LRS' -param slackNotifierApplicationServicePlanSKUName = 'Y1' -param slackNotifierApplicationServicePlanSKUTier = 'Dynamic' -param postgresServerSKUName = 'Standard_B1ms' -param postgresServerSKUTier = 'Burstable' +param keyVaultSku = { + name: 'standard' + family: 'A' +} +param appConfigurationSku = { + name: 'standard' +} +param appInsightsSku = { + name: 'PerGB2018' +} +param slackNotifierSku = { + storageAccountName: 'Standard_LRS' + applicationServicePlanName: 'Y1' + applicationServicePlanTier: 'Dynamic' +} +param postgresSku = { + name: 'Standard_B1ms' + tier: 'Burstable' +} diff --git a/.azure/modules/appConfiguration/create.bicep b/.azure/modules/appConfiguration/create.bicep index 3e82fb0ad..2eb62992b 100644 --- a/.azure/modules/appConfiguration/create.bicep +++ b/.azure/modules/appConfiguration/create.bicep @@ -1,23 +1,26 @@ param namePrefix string param location string -param skuName string + +@export() +type Sku = { + name: 'standard' +} +param sku Sku resource appConfig 'Microsoft.AppConfiguration/configurationStores@2023-03-01' = { - name: '${namePrefix}-appConfiguration' - location: location - sku: { - name: skuName - } - properties: { - // TODO: Remove - enablePurgeProtection: false - } - resource configStoreKeyValue 'keyValues' = { - name: 'Sentinel' - properties: { - value: '1' - } - } + name: '${namePrefix}-appConfiguration' + location: location + sku: sku + properties: { + // TODO: Remove + enablePurgeProtection: false + } + resource configStoreKeyValue 'keyValues' = { + name: 'Sentinel' + properties: { + value: '1' + } + } } output endpoint string = appConfig.properties.endpoint diff --git a/.azure/modules/applicationInsights/create.bicep b/.azure/modules/applicationInsights/create.bicep index a53081493..8b3350328 100644 --- a/.azure/modules/applicationInsights/create.bicep +++ b/.azure/modules/applicationInsights/create.bicep @@ -1,15 +1,18 @@ param namePrefix string param location string -param skuName string + +@export() +type Sku = { + name: 'PerGB2018' | 'CapacityReservation' | 'Free' | 'LACluster' | 'PerGB2018' | 'PerNode' | 'Premium' | 'Standalone' | 'Standard' +} +param sku Sku resource appInsightsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { name: '${namePrefix}-insightsWorkspace' location: location properties: { retentionInDays: 30 - sku: { - name: skuName - } + sku: sku workspaceCapping: { dailyQuotaGb: -1 } diff --git a/.azure/modules/functionApp/slackNotifier.bicep b/.azure/modules/functionApp/slackNotifier.bicep index 1ab9b8132..3519a95ee 100644 --- a/.azure/modules/functionApp/slackNotifier.bicep +++ b/.azure/modules/functionApp/slackNotifier.bicep @@ -2,9 +2,14 @@ param location string param applicationInsightsName string param namePrefix string param keyVaultName string -param storageAccountSKUName string -param applicationServicePlanSKUName string -param applicationServicePlanSKUTier string + +@export() +type Sku = { + storageAccountName: 'Standard_LRS' | 'Standard_GRS' | 'Standard_RAGRS' | 'Standard_ZRS' | 'Premium_LRS' | 'Premium_ZRS' + applicationServicePlanName: 'F1' | 'D1' | 'B1' | 'B2' | 'B3' | 'S1' | 'S2' | 'S3' | 'P1' | 'P2' | 'P3' | 'P1V2' | 'P2V2' | 'P3V2' | 'I1' | 'I2' | 'I3' | 'Y1' | 'Y2' | 'Y3' | 'Y1v2' | 'Y2v2' | 'Y3v2' | 'Y1v2Isolated' | 'Y2v2Isolated' | 'Y3v2Isolated' + applicationServicePlanTier: 'Free' | 'Shared' | 'Basic' | 'Dynamic' | 'Standard' | 'Premium' | 'Isolated' +} +param sku Sku // Storage account names only supports lower case and numbers // todo: add name of function as param and turn this into a reusable module @@ -14,7 +19,7 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = { name: storageAccountName location: location sku: { - name: storageAccountSKUName + name: sku.storageAccountName } kind: 'Storage' properties: { @@ -27,8 +32,8 @@ resource applicationServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = { name: '${namePrefix}-slacknotifier-asp' location: location sku: { - name: applicationServicePlanSKUName - tier: applicationServicePlanSKUTier + name: sku.applicationServicePlanName + tier: sku.applicationServicePlanTier } properties: {} } diff --git a/.azure/modules/keyvault/create.bicep b/.azure/modules/keyvault/create.bicep index 96701d3ca..b69896bd0 100644 --- a/.azure/modules/keyvault/create.bicep +++ b/.azure/modules/keyvault/create.bicep @@ -1,7 +1,12 @@ param namePrefix string param location string -param skuName string -param skuFamily string + +@export() +type Sku = { + name: 'premium' | 'standard' + family: 'A' +} +param sku Sku var keyVaultName = take('${namePrefix}-kv-${uniqueString(resourceGroup().id)}', 24) @@ -12,10 +17,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = { // TODO: Remove, https://github.com/digdir/dialogporten/issues/229 enablePurgeProtection: null // Null is the same as false and false is invalid for some reason enabledForTemplateDeployment: false - sku: { - name: skuName - family: skuFamily - } + sku: sku tenantId: subscription().tenantId accessPolicies: [] } diff --git a/.azure/modules/postgreSql/create.bicep b/.azure/modules/postgreSql/create.bicep index d7481f22c..37e2301e3 100644 --- a/.azure/modules/postgreSql/create.bicep +++ b/.azure/modules/postgreSql/create.bicep @@ -2,8 +2,13 @@ param namePrefix string param location string param keyVaultName string param srcSecretName string -param skuName string -param skuTier string + +@export() +type Sku = { + name: 'Standard_B1ms' + tier: 'Burstable' | 'GeneralPurpose' | 'MemoryOptimized' +} +param sku Sku @secure() param srcKeyVault object @@ -50,10 +55,7 @@ resource postgres 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' = { } replicationRole: 'Primary' } - sku: { - name: skuName - tier: skuTier - } + sku: sku resource database 'databases' = { name: databaseName properties: { From e9d87beec8c7c29a5acf8d4b56d1bf0270e07f48 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 13:50:25 +0100 Subject: [PATCH 03/11] chore: restructure bicep params --- .azure/bicepconfig.json | 19 +- .azure/infrastructure/main.json | 1881 +++++++++++++++++++++++++++++++ 2 files changed, 1898 insertions(+), 2 deletions(-) create mode 100644 .azure/infrastructure/main.json diff --git a/.azure/bicepconfig.json b/.azure/bicepconfig.json index c472c442f..dd1d4865e 100644 --- a/.azure/bicepconfig.json +++ b/.azure/bicepconfig.json @@ -5,13 +5,28 @@ "core": { "rules": { "no-unused-params": { - "level": "warning" + "level": "error" + }, + "no-unused-vars": { + "level": "error" + }, + "no-hardcoded-env-urls": { + "level": "error" + }, + "secure-secrets-in-params": { + "level": "error" + }, + "no-unnecessary-dependson": { + "level": "error" + }, + "outputs-should-not-contain-secrets": { + "level": "error" } } } }, "experimentalFeaturesEnabled": { "compileTimeImports": true, - "userDefinedFunctions": true + "userDefinedFunctions": false } } \ No newline at end of file diff --git a/.azure/infrastructure/main.json b/.azure/infrastructure/main.json new file mode 100644 index 000000000..f73bb18ed --- /dev/null +++ b/.azure/infrastructure/main.json @@ -0,0 +1,1881 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "18102634065330484612" + } + }, + "definitions": { + "AppConfigurationSku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "standard" + ] + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "../modules/appConfiguration/create.bicep" + } + } + }, + "AppInsightsSku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "CapacityReservation", + "Free", + "LACluster", + "PerGB2018", + "PerNode", + "Premium", + "Standalone", + "Standard" + ] + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "../modules/applicationInsights/create.bicep" + } + } + }, + "KeyVaultSku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "premium", + "standard" + ] + }, + "family": { + "type": "string", + "allowedValues": [ + "A" + ] + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "../modules/keyvault/create.bicep" + } + } + }, + "PostgresSku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "Standard_B1ms" + ] + }, + "tier": { + "type": "string", + "allowedValues": [ + "Burstable", + "GeneralPurpose", + "MemoryOptimized" + ] + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "../modules/postgreSql/create.bicep" + } + } + }, + "SlackNotifierSku": { + "type": "object", + "properties": { + "storageAccountName": { + "type": "string", + "allowedValues": [ + "Premium_LRS", + "Premium_ZRS", + "Standard_GRS", + "Standard_LRS", + "Standard_RAGRS", + "Standard_ZRS" + ] + }, + "applicationServicePlanName": { + "type": "string", + "allowedValues": [ + "B1", + "B2", + "B3", + "D1", + "F1", + "I1", + "I2", + "I3", + "P1", + "P1V2", + "P2", + "P2V2", + "P3", + "P3V2", + "S1", + "S2", + "S3", + "Y1", + "Y1v2", + "Y1v2Isolated", + "Y2", + "Y2v2", + "Y2v2Isolated", + "Y3", + "Y3v2", + "Y3v2Isolated" + ] + }, + "applicationServicePlanTier": { + "type": "string", + "allowedValues": [ + "Basic", + "Dynamic", + "Free", + "Isolated", + "Premium", + "Shared", + "Standard" + ] + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "../modules/functionApp/slackNotifier.bicep" + } + } + } + }, + "parameters": { + "environment": { + "type": "string", + "minLength": 3 + }, + "location": { + "type": "string", + "minLength": 3 + }, + "keyVaultSourceKeys": { + "type": "array" + }, + "dialogportenPgAdminPassword": { + "type": "securestring", + "minLength": 3 + }, + "sourceKeyVaultSubscriptionId": { + "type": "securestring", + "minLength": 3 + }, + "sourceKeyVaultResourceGroup": { + "type": "securestring", + "minLength": 3 + }, + "sourceKeyVaultName": { + "type": "securestring", + "minLength": 3 + }, + "keyVaultSku": { + "$ref": "#/definitions/KeyVaultSku" + }, + "appConfigurationSku": { + "$ref": "#/definitions/AppConfigurationSku" + }, + "appInsightsSku": { + "$ref": "#/definitions/AppInsightsSku" + }, + "slackNotifierSku": { + "$ref": "#/definitions/SlackNotifierSku" + }, + "postgresSku": { + "$ref": "#/definitions/PostgresSku" + } + }, + "variables": { + "secrets": { + "dialogportenPgAdminPassword": "[parameters('dialogportenPgAdminPassword')]", + "sourceKeyVaultSubscriptionId": "[parameters('sourceKeyVaultSubscriptionId')]", + "sourceKeyVaultResourceGroup": "[parameters('sourceKeyVaultResourceGroup')]", + "sourceKeyVaultName": "[parameters('sourceKeyVaultName')]" + }, + "namePrefix": "[format('dp-be-{0}', parameters('environment'))]", + "srcKeyVault": { + "name": "[variables('secrets').sourceKeyVaultName]", + "subscriptionId": "[variables('secrets').sourceKeyVaultSubscriptionId]", + "resourceGroupName": "[variables('secrets').sourceKeyVaultResourceGroup]" + } + }, + "resources": { + "resourceGroup": { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2023-07-01", + "name": "[format('{0}-rg', variables('namePrefix'))]", + "location": "[parameters('location')]" + }, + "srcKeyVaultResource": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-07-01", + "subscriptionId": "[variables('secrets').sourceKeyVaultSubscriptionId]", + "resourceGroup": "[variables('secrets').sourceKeyVaultResourceGroup]", + "name": "[variables('secrets').sourceKeyVaultName]" + }, + "keyVaultModule": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "keyVault", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namePrefix": { + "value": "[variables('namePrefix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "sku": { + "value": "[parameters('keyVaultSku')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "2760954716125288010" + } + }, + "definitions": { + "Sku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "premium", + "standard" + ] + }, + "family": { + "type": "string", + "allowedValues": [ + "A" + ] + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "namePrefix": { + "type": "string" + }, + "location": { + "type": "string" + }, + "sku": { + "$ref": "#/definitions/Sku" + } + }, + "variables": { + "keyVaultName": "[take(format('{0}-kv-{1}', parameters('namePrefix'), uniqueString(resourceGroup().id)), 24)]" + }, + "resources": { + "keyVault": { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-07-01", + "name": "[variables('keyVaultName')]", + "location": "[parameters('location')]", + "properties": { + "enablePurgeProtection": null, + "enabledForTemplateDeployment": false, + "sku": "[parameters('sku')]", + "tenantId": "[subscription().tenantId]", + "accessPolicies": [] + } + } + }, + "outputs": { + "name": { + "type": "string", + "value": "[variables('keyVaultName')]" + } + } + } + }, + "dependsOn": [ + "resourceGroup" + ] + }, + "appConfiguration": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "appConfiguration", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namePrefix": { + "value": "[variables('namePrefix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "sku": { + "value": "[parameters('appConfigurationSku')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "988952339729943041" + } + }, + "definitions": { + "Sku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "standard" + ] + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "namePrefix": { + "type": "string" + }, + "location": { + "type": "string" + }, + "sku": { + "$ref": "#/definitions/Sku" + } + }, + "resources": { + "appConfig::configStoreKeyValue": { + "type": "Microsoft.AppConfiguration/configurationStores/keyValues", + "apiVersion": "2023-03-01", + "name": "[format('{0}/{1}', format('{0}-appConfiguration', parameters('namePrefix')), 'Sentinel')]", + "properties": { + "value": "1" + }, + "dependsOn": [ + "appConfig" + ] + }, + "appConfig": { + "type": "Microsoft.AppConfiguration/configurationStores", + "apiVersion": "2023-03-01", + "name": "[format('{0}-appConfiguration', parameters('namePrefix'))]", + "location": "[parameters('location')]", + "sku": "[parameters('sku')]", + "properties": { + "enablePurgeProtection": false + } + } + }, + "outputs": { + "endpoint": { + "type": "string", + "value": "[reference('appConfig').endpoint]" + }, + "name": { + "type": "string", + "value": "[format('{0}-appConfiguration', parameters('namePrefix'))]" + } + } + } + }, + "dependsOn": [ + "resourceGroup" + ] + }, + "appInsights": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "appInsights", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namePrefix": { + "value": "[variables('namePrefix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "sku": { + "value": "[parameters('appInsightsSku')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10082346743241499787" + } + }, + "definitions": { + "Sku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "CapacityReservation", + "Free", + "LACluster", + "PerGB2018", + "PerNode", + "Premium", + "Standalone", + "Standard" + ] + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "namePrefix": { + "type": "string" + }, + "location": { + "type": "string" + }, + "sku": { + "$ref": "#/definitions/Sku" + } + }, + "resources": { + "appInsightsWorkspace": { + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2022-10-01", + "name": "[format('{0}-insightsWorkspace', parameters('namePrefix'))]", + "location": "[parameters('location')]", + "properties": { + "retentionInDays": 30, + "sku": "[parameters('sku')]", + "workspaceCapping": { + "dailyQuotaGb": -1 + } + } + }, + "appInsights": { + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[format('{0}-applicationInsights', parameters('namePrefix'))]", + "location": "[parameters('location')]", + "kind": "web", + "properties": { + "Application_Type": "web", + "WorkspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('{0}-insightsWorkspace', parameters('namePrefix')))]", + "Flow_Type": "Bluefield", + "Request_Source": "rest" + }, + "dependsOn": [ + "appInsightsWorkspace" + ] + } + }, + "outputs": { + "connectionString": { + "type": "string", + "value": "[reference('appInsights').ConnectionString]" + }, + "appInsightsWorkspaceName": { + "type": "string", + "value": "[format('{0}-insightsWorkspace', parameters('namePrefix'))]" + }, + "appInsightsName": { + "type": "string", + "value": "[format('{0}-applicationInsights', parameters('namePrefix'))]" + } + } + } + }, + "dependsOn": [ + "resourceGroup" + ] + }, + "postgresql": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "postgresql", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namePrefix": { + "value": "[variables('namePrefix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "keyVaultName": { + "value": "[reference('keyVaultModule').outputs.name.value]" + }, + "srcKeyVault": { + "value": "[variables('srcKeyVault')]" + }, + "srcSecretName": { + "value": "[format('dialogportenPgAdminPassword{0}', parameters('environment'))]" + }, + "administratorLoginPassword": "[if(contains(parameters('keyVaultSourceKeys'), format('dialogportenPgAdminPassword{0}', parameters('environment'))), createObject('reference', createObject('keyVault', createObject('id', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', variables('secrets').sourceKeyVaultSubscriptionId, variables('secrets').sourceKeyVaultResourceGroup), 'Microsoft.KeyVault/vaults', variables('secrets').sourceKeyVaultName)), 'secretName', format('dialogportenPgAdminPassword{0}', parameters('environment')))), createObject('value', variables('secrets').dialogportenPgAdminPassword))]", + "sku": { + "value": "[parameters('postgresSku')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "52111473636837092" + } + }, + "definitions": { + "Sku": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "Standard_B1ms" + ] + }, + "tier": { + "type": "string", + "allowedValues": [ + "Burstable", + "GeneralPurpose", + "MemoryOptimized" + ] + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "namePrefix": { + "type": "string" + }, + "location": { + "type": "string" + }, + "keyVaultName": { + "type": "string" + }, + "srcSecretName": { + "type": "string" + }, + "sku": { + "$ref": "#/definitions/Sku" + }, + "srcKeyVault": { + "type": "secureObject" + }, + "administratorLoginPassword": { + "type": "securestring" + } + }, + "variables": { + "administratorLogin": "dialogportenPgAdmin", + "databaseName": "dialogporten" + }, + "resources": { + "postgres::database": { + "type": "Microsoft.DBforPostgreSQL/flexibleServers/databases", + "apiVersion": "2022-12-01", + "name": "[format('{0}/{1}', format('{0}-postgres', parameters('namePrefix')), variables('databaseName'))]", + "properties": { + "charset": "UTF8", + "collation": "en_US.utf8" + }, + "dependsOn": [ + "postgres" + ] + }, + "postgres::allowAzureAccess": { + "type": "Microsoft.DBforPostgreSQL/flexibleServers/firewallRules", + "apiVersion": "2022-12-01", + "name": "[format('{0}/{1}', format('{0}-postgres', parameters('namePrefix')), 'AllowAccessFromAzure')]", + "properties": { + "startIpAddress": "0.0.0.0", + "endIpAddress": "0.0.0.0" + }, + "dependsOn": [ + "postgres" + ] + }, + "postgres": { + "type": "Microsoft.DBforPostgreSQL/flexibleServers", + "apiVersion": "2022-12-01", + "name": "[format('{0}-postgres', parameters('namePrefix'))]", + "location": "[parameters('location')]", + "properties": { + "version": "15", + "administratorLogin": "[variables('administratorLogin')]", + "administratorLoginPassword": "[parameters('administratorLoginPassword')]", + "storage": { + "storageSizeGB": 32 + }, + "dataEncryption": { + "type": "SystemManaged" + }, + "replicationRole": "Primary" + }, + "sku": "[parameters('sku')]" + }, + "saveAdmPassword": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('Save_{0}', parameters('srcSecretName'))]", + "subscriptionId": "[parameters('srcKeyVault').subscriptionId]", + "resourceGroup": "[parameters('srcKeyVault').resourceGroupName]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "destKeyVaultName": { + "value": "[parameters('srcKeyVault').name]" + }, + "secretName": { + "value": "[parameters('srcSecretName')]" + }, + "secretValue": { + "value": "[parameters('administratorLoginPassword')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4960712788860156215" + } + }, + "parameters": { + "destKeyVaultName": { + "type": "string" + }, + "secretName": { + "type": "string" + }, + "secretValue": { + "type": "securestring" + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", + "properties": { + "value": "[parameters('secretValue')]" + } + } + ], + "outputs": { + "secretUri": { + "type": "string", + "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" + } + } + } + } + }, + "adoConnectionString": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "adoConnectionString", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "destKeyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "secretName": { + "value": "dialogportenAdoConnectionString" + }, + "secretValue": { + "value": "[format('Server={0};Database={1};Port=5432;User Id={2};Password={3};Ssl Mode=Require;Trust Server Certificate=true;', reference('postgres').fullyQualifiedDomainName, variables('databaseName'), variables('administratorLogin'), parameters('administratorLoginPassword'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4960712788860156215" + } + }, + "parameters": { + "destKeyVaultName": { + "type": "string" + }, + "secretName": { + "type": "string" + }, + "secretValue": { + "type": "securestring" + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", + "properties": { + "value": "[parameters('secretValue')]" + } + } + ], + "outputs": { + "secretUri": { + "type": "string", + "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" + } + } + } + }, + "dependsOn": [ + "postgres" + ] + }, + "psqlConnectionString": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "psqlConnectionString", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "destKeyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "secretName": { + "value": "dialogportenPsqlConnectionString" + }, + "secretValue": { + "value": "[format('psql ''host={0} port=5432 dbname={1} user={2} password={3} sslmode=require''', reference('postgres').fullyQualifiedDomainName, variables('databaseName'), variables('administratorLogin'), parameters('administratorLoginPassword'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4960712788860156215" + } + }, + "parameters": { + "destKeyVaultName": { + "type": "string" + }, + "secretName": { + "type": "string" + }, + "secretValue": { + "type": "securestring" + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", + "properties": { + "value": "[parameters('secretValue')]" + } + } + ], + "outputs": { + "secretUri": { + "type": "string", + "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" + } + } + } + }, + "dependsOn": [ + "postgres" + ] + } + }, + "outputs": { + "adoConnectionStringSecretUri": { + "type": "string", + "value": "[reference('adoConnectionString').outputs.secretUri.value]" + }, + "psqlConnectionStringSecretUri": { + "type": "string", + "value": "[reference('psqlConnectionString').outputs.secretUri.value]" + } + } + } + }, + "dependsOn": [ + "keyVaultModule", + "resourceGroup", + "srcKeyVaultResource" + ] + }, + "copyEnvironmentSecrets": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "copyEnvironmentSecrets", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "srcKeyVaultKeys": { + "value": "[parameters('keyVaultSourceKeys')]" + }, + "srcKeyVaultName": { + "value": "[variables('secrets').sourceKeyVaultName]" + }, + "srcKeyVaultRGNName": { + "value": "[variables('secrets').sourceKeyVaultResourceGroup]" + }, + "srcKeyVaultSubId": { + "value": "[variables('secrets').sourceKeyVaultSubscriptionId]" + }, + "destKeyVaultName": { + "value": "[reference('keyVaultModule').outputs.name.value]" + }, + "secretPrefix": { + "value": "[format('dialogporten--{0}--', parameters('environment'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "44147448919080552" + } + }, + "parameters": { + "srcKeyVaultKeys": { + "type": "array" + }, + "srcKeyVaultName": { + "type": "string" + }, + "srcKeyVaultRGNName": { + "type": "string", + "defaultValue": "[resourceGroup().name]" + }, + "srcKeyVaultSubId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]" + }, + "destKeyVaultName": { + "type": "string" + }, + "destKeyVaultRGName": { + "type": "string", + "defaultValue": "[resourceGroup().name]" + }, + "destKeyVaultSubId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]" + }, + "secretPrefix": { + "type": "string" + }, + "removeSecretPrefix": { + "type": "bool", + "defaultValue": true + } + }, + "variables": { + "copy": [ + { + "name": "environmentKeys", + "count": "[length(parameters('srcKeyVaultKeys'))]", + "input": { + "isEnvironmentKey": "[startsWith(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'))]", + "value": "[if(parameters('removeSecretPrefix'), replace(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'), ''), parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')])]", + "fullName": "[parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')]]" + } + } + ] + }, + "resources": [ + { + "copy": { + "name": "secrets", + "count": "[length(variables('environmentKeys'))]" + }, + "condition": "[variables('environmentKeys')[copyIndex()].isEnvironmentKey]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[variables('environmentKeys')[copyIndex()].value]", + "subscriptionId": "[parameters('destKeyVaultSubId')]", + "resourceGroup": "[parameters('destKeyVaultRGName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "destKeyVaultName": { + "value": "[parameters('destKeyVaultName')]" + }, + "secretName": { + "value": "[variables('environmentKeys')[copyIndex()].value]" + }, + "secretValue": { + "reference": { + "keyVault": { + "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('srcKeyVaultSubId'), parameters('srcKeyVaultRGNName')), 'Microsoft.KeyVault/vaults', parameters('srcKeyVaultName'))]" + }, + "secretName": "[variables('environmentKeys')[copyIndex()].fullName]" + } + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4960712788860156215" + } + }, + "parameters": { + "destKeyVaultName": { + "type": "string" + }, + "secretName": { + "type": "string" + }, + "secretValue": { + "type": "securestring" + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", + "properties": { + "value": "[parameters('secretValue')]" + } + } + ], + "outputs": { + "secretUri": { + "type": "string", + "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" + } + } + } + } + } + ] + } + }, + "dependsOn": [ + "keyVaultModule", + "resourceGroup" + ] + }, + "copyCrossEnvironmentSecrets": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "copyCrossEnvironmentSecrets", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "srcKeyVaultKeys": { + "value": "[parameters('keyVaultSourceKeys')]" + }, + "srcKeyVaultName": { + "value": "[variables('secrets').sourceKeyVaultName]" + }, + "srcKeyVaultRGNName": { + "value": "[variables('secrets').sourceKeyVaultResourceGroup]" + }, + "srcKeyVaultSubId": { + "value": "[variables('secrets').sourceKeyVaultSubscriptionId]" + }, + "destKeyVaultName": { + "value": "[reference('keyVaultModule').outputs.name.value]" + }, + "secretPrefix": { + "value": "dialogporten--any--" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "44147448919080552" + } + }, + "parameters": { + "srcKeyVaultKeys": { + "type": "array" + }, + "srcKeyVaultName": { + "type": "string" + }, + "srcKeyVaultRGNName": { + "type": "string", + "defaultValue": "[resourceGroup().name]" + }, + "srcKeyVaultSubId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]" + }, + "destKeyVaultName": { + "type": "string" + }, + "destKeyVaultRGName": { + "type": "string", + "defaultValue": "[resourceGroup().name]" + }, + "destKeyVaultSubId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]" + }, + "secretPrefix": { + "type": "string" + }, + "removeSecretPrefix": { + "type": "bool", + "defaultValue": true + } + }, + "variables": { + "copy": [ + { + "name": "environmentKeys", + "count": "[length(parameters('srcKeyVaultKeys'))]", + "input": { + "isEnvironmentKey": "[startsWith(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'))]", + "value": "[if(parameters('removeSecretPrefix'), replace(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'), ''), parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')])]", + "fullName": "[parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')]]" + } + } + ] + }, + "resources": [ + { + "copy": { + "name": "secrets", + "count": "[length(variables('environmentKeys'))]" + }, + "condition": "[variables('environmentKeys')[copyIndex()].isEnvironmentKey]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[variables('environmentKeys')[copyIndex()].value]", + "subscriptionId": "[parameters('destKeyVaultSubId')]", + "resourceGroup": "[parameters('destKeyVaultRGName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "destKeyVaultName": { + "value": "[parameters('destKeyVaultName')]" + }, + "secretName": { + "value": "[variables('environmentKeys')[copyIndex()].value]" + }, + "secretValue": { + "reference": { + "keyVault": { + "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('srcKeyVaultSubId'), parameters('srcKeyVaultRGNName')), 'Microsoft.KeyVault/vaults', parameters('srcKeyVaultName'))]" + }, + "secretName": "[variables('environmentKeys')[copyIndex()].fullName]" + } + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "4960712788860156215" + } + }, + "parameters": { + "destKeyVaultName": { + "type": "string" + }, + "secretName": { + "type": "string" + }, + "secretValue": { + "type": "securestring" + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", + "properties": { + "value": "[parameters('secretValue')]" + } + } + ], + "outputs": { + "secretUri": { + "type": "string", + "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" + } + } + } + } + } + ] + } + }, + "dependsOn": [ + "keyVaultModule", + "resourceGroup" + ] + }, + "slackNotifier": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "slackNotifier", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "keyVaultName": { + "value": "[reference('keyVaultModule').outputs.name.value]" + }, + "namePrefix": { + "value": "[variables('namePrefix')]" + }, + "applicationInsightsName": { + "value": "[reference('appInsights').outputs.appInsightsName.value]" + }, + "sku": { + "value": "[parameters('slackNotifierSku')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "14801988153889955025" + } + }, + "definitions": { + "Sku": { + "type": "object", + "properties": { + "storageAccountName": { + "type": "string", + "allowedValues": [ + "Premium_LRS", + "Premium_ZRS", + "Standard_GRS", + "Standard_LRS", + "Standard_RAGRS", + "Standard_ZRS" + ] + }, + "applicationServicePlanName": { + "type": "string", + "allowedValues": [ + "B1", + "B2", + "B3", + "D1", + "F1", + "I1", + "I2", + "I3", + "P1", + "P1V2", + "P2", + "P2V2", + "P3", + "P3V2", + "S1", + "S2", + "S3", + "Y1", + "Y1v2", + "Y1v2Isolated", + "Y2", + "Y2v2", + "Y2v2Isolated", + "Y3", + "Y3v2", + "Y3v2Isolated" + ] + }, + "applicationServicePlanTier": { + "type": "string", + "allowedValues": [ + "Basic", + "Dynamic", + "Free", + "Isolated", + "Premium", + "Shared", + "Standard" + ] + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "location": { + "type": "string" + }, + "applicationInsightsName": { + "type": "string" + }, + "namePrefix": { + "type": "string" + }, + "keyVaultName": { + "type": "string" + }, + "sku": { + "$ref": "#/definitions/Sku" + } + }, + "variables": { + "storageAccountName": "[format('{0}{1}sa', replace(parameters('namePrefix'), '-', ''), substring('slacknotifier', 0, 10))]", + "functionAppName": "[format('{0}-slacknotifier-fa', parameters('namePrefix'))]" + }, + "resources": { + "storageAccount": { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-01-01", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('sku').storageAccountName]" + }, + "kind": "Storage", + "properties": { + "supportsHttpsTrafficOnly": true, + "defaultToOAuthAuthentication": true + } + }, + "applicationServicePlan": { + "type": "Microsoft.Web/serverfarms", + "apiVersion": "2023-01-01", + "name": "[format('{0}-slacknotifier-asp', parameters('namePrefix'))]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('sku').applicationServicePlanName]", + "tier": "[parameters('sku').applicationServicePlanTier]" + }, + "properties": {} + }, + "applicationInsights": { + "existing": true, + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[parameters('applicationInsightsName')]" + }, + "functionApp": { + "type": "Microsoft.Web/sites", + "apiVersion": "2023-01-01", + "name": "[variables('functionAppName')]", + "location": "[parameters('location')]", + "kind": "functionapp", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', format('{0}-slacknotifier-asp', parameters('namePrefix')))]", + "publicNetworkAccess": "Enabled", + "siteConfig": {}, + "httpsOnly": true + }, + "dependsOn": [ + "applicationServicePlan" + ] + }, + "notifyDevTeam": { + "type": "Microsoft.Insights/actionGroups", + "apiVersion": "2023-01-01", + "name": "[format('{0}-notify-devteam-ag', parameters('namePrefix'))]", + "location": "Global", + "properties": { + "enabled": true, + "groupShortName": "DevNotify", + "azureFunctionReceivers": [ + { + "name": "[reference('functionApp').defaultHostName]", + "functionName": "ForwardAlertToSlack", + "functionAppResourceId": "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]", + "httpTriggerUrl": "[format('https://{0}/api/forwardalerttoslack?code={1}', reference('functionApp').defaultHostName, listkeys(format('{0}/host/default', resourceId('Microsoft.Web/sites', variables('functionAppName'))), '2023-01-01').functionKeys.default)]", + "useCommonAlertSchema": true + } + ] + }, + "dependsOn": [ + "functionApp" + ] + }, + "exceptionOccuredAlertRule": { + "type": "Microsoft.Insights/scheduledQueryRules", + "apiVersion": "2023-03-15-preview", + "name": "[format('{0}-exception-occured-sqr', parameters('namePrefix'))]", + "location": "[parameters('location')]", + "properties": { + "enabled": true, + "severity": 1, + "evaluationFrequency": "PT5M", + "windowSize": "PT5M", + "scopes": [ + "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]" + ], + "autoMitigate": false, + "targetResourceTypes": [ + "microsoft.insights/components" + ], + "criteria": { + "allOf": [ + { + "query": "exceptions | summarize count = count() by environment = tostring(customDimensions.AspNetCoreEnvironment), problemId", + "operator": "GreaterThan", + "threshold": 0, + "timeAggregation": "Count", + "failingPeriods": { + "numberOfEvaluationPeriods": 1, + "minFailingPeriodsToAlert": 1 + } + } + ] + }, + "actions": { + "actionGroups": [ + "[resourceId('Microsoft.Insights/actionGroups', format('{0}-notify-devteam-ag', parameters('namePrefix')))]" + ] + } + }, + "dependsOn": [ + "applicationInsights", + "notifyDevTeam" + ] + }, + "updateAppSettings": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-appsettings', variables('functionAppName'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "webAppName": { + "value": "[variables('functionAppName')]" + }, + "currentAppSettings": { + "value": "[list(resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings'), '2023-01-01').properties]" + }, + "appSettings": { + "value": { + "AzureWebJobsStorage": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2023-01-01').keys[0].value)]", + "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2023-01-01').keys[0].value)]", + "WEBSITE_CONTENTSHARE": "[toLower(variables('functionAppName'))]", + "FUNCTIONS_EXTENSION_VERSION": "~4", + "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference('applicationInsights').InstrumentationKey]", + "Slack__WebhookUrl": "[format('@Microsoft.KeyVault(VaultName={0};SecretName=Slack--Webhook--Url)', parameters('keyVaultName'))]", + "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" + } + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10763973054038990940" + } + }, + "parameters": { + "webAppName": { + "type": "string" + }, + "appSettings": { + "type": "object" + }, + "currentAppSettings": { + "type": "object" + } + }, + "resources": [ + { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}', parameters('webAppName'), 'appsettings')]", + "properties": "[union(parameters('currentAppSettings'), parameters('appSettings'))]" + } + ] + } + }, + "dependsOn": [ + "applicationInsights", + "storageAccount" + ] + } + }, + "outputs": { + "functionAppPrincipalId": { + "type": "string", + "value": "[reference('functionApp', '2023-01-01', 'full').identity.principalId]" + } + } + } + }, + "dependsOn": [ + "appInsights", + "keyVaultModule", + "resourceGroup" + ] + }, + "containerAppEnv": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "containerAppEnv", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namePrefix": { + "value": "[variables('namePrefix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "appInsightWorkspaceName": { + "value": "[reference('appInsights').outputs.appInsightsWorkspaceName.value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10299501857515385890" + } + }, + "parameters": { + "location": { + "type": "string" + }, + "namePrefix": { + "type": "string" + }, + "appInsightWorkspaceName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.App/managedEnvironments", + "apiVersion": "2023-05-01", + "name": "[format('{0}-cae', parameters('namePrefix'))]", + "location": "[parameters('location')]", + "properties": { + "appLogsConfiguration": { + "destination": "log-analytics", + "logAnalyticsConfiguration": { + "customerId": "[reference(resourceId('Microsoft.OperationalInsights/workspaces', parameters('appInsightWorkspaceName')), '2022-10-01').customerId]", + "sharedKey": "[listKeys(resourceId('Microsoft.OperationalInsights/workspaces', parameters('appInsightWorkspaceName')), '2022-10-01').primarySharedKey]" + } + } + } + } + ], + "outputs": { + "containerAppEnvId": { + "type": "string", + "value": "[resourceId('Microsoft.App/managedEnvironments', format('{0}-cae', parameters('namePrefix')))]" + } + } + } + }, + "dependsOn": [ + "appInsights", + "resourceGroup" + ] + }, + "appInsightsReaderAccessPolicy": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "appInsightsReaderAccessPolicy", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "appInsightsName": { + "value": "[reference('appInsights').outputs.appInsightsName.value]" + }, + "principalIds": { + "value": [ + "[reference('slackNotifier').outputs.functionAppPrincipalId.value]" + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "17437758389307278342" + } + }, + "parameters": { + "appInsightsName": { + "type": "string" + }, + "principalIds": { + "type": "array" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignments", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Insights/components/{0}', parameters('appInsightsName'))]", + "name": "[guid(subscription().id, parameters('principalIds')[copyIndex()], subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7'))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "ServicePrincipal" + } + } + ] + } + }, + "dependsOn": [ + "appInsights", + "resourceGroup", + "slackNotifier" + ] + }, + "appConfigConfigurations": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "AppConfig_Add_DialogDbConnectionString", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "configStoreName": { + "value": "[reference('appConfiguration').outputs.name.value]" + }, + "key": { + "value": "Infrastructure:DialogDbConnectionString" + }, + "value": { + "value": "[reference('postgresql').outputs.adoConnectionStringSecretUri.value]" + }, + "keyValueType": { + "value": "keyVaultReference" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "12264379860409378346" + } + }, + "parameters": { + "configStoreName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the App Configuration store." + } + }, + "key": { + "type": "string", + "metadata": { + "description": "Specifies the names of the key-value resources. The name is a combination of key and label with $ as delimiter. The label is optional." + } + }, + "value": { + "type": "string", + "metadata": { + "description": "Specifies the values of the key-value resources" + } + }, + "contentType": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Specifies the content type of the key-value resources. For feature flag set keyValueType=featureFlag. For Key Value reference set keyValueType=featureFlag. Otherwise, it's optional." + } + }, + "keyValueType": { + "type": "string", + "defaultValue": "custom", + "allowedValues": [ + "keyVaultReference", + "featureFlag", + "custom" + ], + "metadata": { + "description": "Specifies the type of the key-value resources" + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Adds tags for the key-value resources" + } + } + }, + "variables": { + "parsedContentType": "[if(equals(parameters('keyValueType'), 'keyVaultReference'), 'application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8', if(equals(parameters('keyValueType'), 'featureFlag'), 'application/vnd.microsoft.appconfig.ff+json;charset=utf-8', parameters('contentType')))]", + "parsedValue": "[if(equals(parameters('keyValueType'), 'keyVaultReference'), format('{{\"uri\":\"{0}\"}}', parameters('value')), parameters('value'))]" + }, + "resources": [ + { + "type": "Microsoft.AppConfiguration/configurationStores/keyValues", + "apiVersion": "2023-03-01", + "name": "[format('{0}/{1}', parameters('configStoreName'), parameters('key'))]", + "properties": { + "value": "[variables('parsedValue')]", + "contentType": "[variables('parsedContentType')]", + "tags": "[parameters('tags')]" + } + } + ] + } + }, + "dependsOn": [ + "appConfiguration", + "postgresql", + "resourceGroup" + ] + }, + "keyVaultReaderAccessPolicy": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "keyVaultReaderAccessPolicyFunctions", + "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyvaultName": { + "value": "[reference('keyVaultModule').outputs.name.value]" + }, + "principalIds": { + "value": [ + "[reference('slackNotifier').outputs.functionAppPrincipalId.value]" + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "8309515987304945736" + } + }, + "parameters": { + "keyvaultName": { + "type": "string" + }, + "principalIds": { + "type": "array" + } + }, + "variables": { + "copy": [ + { + "name": "readerAccessPoliciesArray", + "count": "[length(parameters('principalIds'))]", + "input": { + "objectId": "[parameters('principalIds')[copyIndex('readerAccessPoliciesArray')]]", + "tenantId": "[subscription().tenantId]", + "permissions": { + "certificates": [ + "get", + "list" + ], + "keys": [ + "get", + "list" + ], + "secrets": [ + "get", + "list" + ] + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyvaultName'), 'add')]", + "properties": { + "accessPolicies": "[variables('readerAccessPoliciesArray')]" + } + } + ] + } + }, + "dependsOn": [ + "keyVaultModule", + "resourceGroup", + "slackNotifier" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "value": "[format('{0}-rg', variables('namePrefix'))]" + }, + "containerAppEnvId": { + "type": "string", + "value": "[reference('containerAppEnv').outputs.containerAppEnvId.value]" + }, + "environmentKeyVaultName": { + "type": "string", + "value": "[reference('keyVaultModule').outputs.name.value]" + } + } +} \ No newline at end of file From fa0769f7961692648fa7711b081055064cae0644 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 14:53:48 +0100 Subject: [PATCH 04/11] feat: add redis --- .azure/infrastructure/main.bicep | 46 +++++++++++++++++---- .azure/infrastructure/production.bicepparam | 2 + .azure/infrastructure/soak.bicepparam | 2 + .azure/infrastructure/staging.bicepparam | 2 + .azure/infrastructure/test.bicepparam | 2 + .azure/modules/postgreSql/create.bicep | 6 +-- .azure/modules/redis/main.bicep | 45 ++++++++++++++++++++ 7 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 .azure/modules/redis/main.bicep diff --git a/.azure/infrastructure/main.bicep b/.azure/infrastructure/main.bicep index cb1a7a642..a210db706 100644 --- a/.azure/infrastructure/main.bicep +++ b/.azure/infrastructure/main.bicep @@ -34,6 +34,11 @@ param slackNotifierSku SlackNotifierSku import {Sku as PostgresSku} from '../modules/postgreSql/create.bicep' param postgresSku PostgresSku +import {Sku as RedisSku} from '../modules/redis/main.bicep' +param redisSku RedisSku +@minLength(1) +param redisVersion string + var secrets = { dialogportenPgAdminPassword: dialogportenPgAdminPassword sourceKeyVaultSubscriptionId: sourceKeyVaultSubscriptionId @@ -49,7 +54,7 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { location: location } -module keyVaultModule '../modules/keyvault/create.bicep' = { +module environmentKeyVault '../modules/keyvault/create.bicep' = { scope: resourceGroup name: 'keyVault' params: { @@ -104,7 +109,7 @@ module postgresql '../modules/postgreSql/create.bicep' = { params: { namePrefix: namePrefix location: location - keyVaultName: keyVaultModule.outputs.name + environmentKeyVaultName: environmentKeyVault.outputs.name srcKeyVault: srcKeyVault srcSecretName: 'dialogportenPgAdminPassword${environment}' administratorLoginPassword: contains(keyVaultSourceKeys, 'dialogportenPgAdminPassword${environment}') ? srcKeyVaultResource.getSecret('dialogportenPgAdminPassword${environment}') : secrets.dialogportenPgAdminPassword @@ -112,6 +117,20 @@ module postgresql '../modules/postgreSql/create.bicep' = { } } +module redis '../modules/redis/main.bicep' = { + scope: resourceGroup + name: 'redis' + params: { + namePrefix: namePrefix + location: location + environmentKeyVaultName: environmentKeyVault.outputs.name + sku: redisSku + version: redisVersion + } +} + + + module copyEnvironmentSecrets '../modules/keyvault/copySecrets.bicep' = { scope: resourceGroup name: 'copyEnvironmentSecrets' @@ -120,7 +139,7 @@ module copyEnvironmentSecrets '../modules/keyvault/copySecrets.bicep' = { srcKeyVaultName: secrets.sourceKeyVaultName srcKeyVaultRGNName: secrets.sourceKeyVaultResourceGroup srcKeyVaultSubId: secrets.sourceKeyVaultSubscriptionId - destKeyVaultName: keyVaultModule.outputs.name + destKeyVaultName: environmentKeyVault.outputs.name secretPrefix: 'dialogporten--${environment}--' } } @@ -132,7 +151,7 @@ module copyCrossEnvironmentSecrets '../modules/keyvault/copySecrets.bicep' = { srcKeyVaultName: secrets.sourceKeyVaultName srcKeyVaultRGNName: secrets.sourceKeyVaultResourceGroup srcKeyVaultSubId: secrets.sourceKeyVaultSubscriptionId - destKeyVaultName: keyVaultModule.outputs.name + destKeyVaultName: environmentKeyVault.outputs.name secretPrefix: 'dialogporten--any--' } } @@ -142,7 +161,7 @@ module slackNotifier '../modules/functionApp/slackNotifier.bicep' = { scope: resourceGroup params: { location: location - keyVaultName: keyVaultModule.outputs.name + keyVaultName: environmentKeyVault.outputs.name namePrefix: namePrefix applicationInsightsName: appInsights.outputs.appInsightsName sku: slackNotifierSku @@ -168,7 +187,7 @@ module appInsightsReaderAccessPolicy '../modules/applicationInsights/addReaderRo } } -module appConfigConfigurations '../modules/appConfiguration/upsertKeyValue.bicep' = { +module postgresConnectionStringAppConfig '../modules/appConfiguration/upsertKeyValue.bicep' = { scope: resourceGroup name: 'AppConfig_Add_DialogDbConnectionString' params: { @@ -179,15 +198,26 @@ module appConfigConfigurations '../modules/appConfiguration/upsertKeyValue.bicep } } +module redisConnectionStringAppConfig '../modules/appConfiguration/upsertKeyValue.bicep' = { + scope: resourceGroup + name: 'AppConfig_Add_DialogRedisConnectionString' + params: { + configStoreName: appConfiguration.outputs.name + key: 'Infrastructure:DialogRedisConnectionString' + value: redis.outputs.connectionStringSecretUri + keyValueType: 'keyVaultReference' + } +} + module keyVaultReaderAccessPolicy '../modules/keyvault/addReaderRoles.bicep' = { scope: resourceGroup name: 'keyVaultReaderAccessPolicyFunctions' params: { - keyvaultName: keyVaultModule.outputs.name + keyvaultName: environmentKeyVault.outputs.name principalIds: [ slackNotifier.outputs.functionAppPrincipalId ] } } output resourceGroupName string = resourceGroup.name output containerAppEnvId string = containerAppEnv.outputs.containerAppEnvId -output environmentKeyVaultName string = keyVaultModule.outputs.name +output environmentKeyVaultName string = environmentKeyVault.outputs.name diff --git a/.azure/infrastructure/production.bicepparam b/.azure/infrastructure/production.bicepparam index 63a21d428..c72c688bb 100644 --- a/.azure/infrastructure/production.bicepparam +++ b/.azure/infrastructure/production.bicepparam @@ -4,6 +4,8 @@ param environment = 'production' param location = 'norwayeast' param keyVaultSourceKeys = json(readEnvironmentVariable('KEY_VAULT_SOURCE_KEYS')) +param redisVersion = '6.0' + // secrets param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD') param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID') diff --git a/.azure/infrastructure/soak.bicepparam b/.azure/infrastructure/soak.bicepparam index 609096cf1..f2430332e 100644 --- a/.azure/infrastructure/soak.bicepparam +++ b/.azure/infrastructure/soak.bicepparam @@ -4,6 +4,8 @@ param environment = 'soak' param location = 'norwayeast' param keyVaultSourceKeys = json(readEnvironmentVariable('KEY_VAULT_SOURCE_KEYS')) +param redisVersion = '6.0' + // secrets param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD') param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID') diff --git a/.azure/infrastructure/staging.bicepparam b/.azure/infrastructure/staging.bicepparam index 07b54f198..1d729f11e 100644 --- a/.azure/infrastructure/staging.bicepparam +++ b/.azure/infrastructure/staging.bicepparam @@ -4,6 +4,8 @@ param environment = 'staging' param location = 'norwayeast' param keyVaultSourceKeys = json(readEnvironmentVariable('KEY_VAULT_SOURCE_KEYS')) +param redisVersion = '6.0' + // secrets param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD') param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID') diff --git a/.azure/infrastructure/test.bicepparam b/.azure/infrastructure/test.bicepparam index 19b5e658c..85519dc4f 100644 --- a/.azure/infrastructure/test.bicepparam +++ b/.azure/infrastructure/test.bicepparam @@ -4,6 +4,8 @@ param environment = 'test' param location = 'norwayeast' param keyVaultSourceKeys = json(readEnvironmentVariable('KEY_VAULT_SOURCE_KEYS')) +param redisVersion = '6.0' + // secrets param dialogportenPgAdminPassword = readEnvironmentVariable('PG_ADMIN_PASSWORD') param sourceKeyVaultSubscriptionId = readEnvironmentVariable('SOURCE_KEY_VAULT_SUBSCRIPTION_ID') diff --git a/.azure/modules/postgreSql/create.bicep b/.azure/modules/postgreSql/create.bicep index 37e2301e3..cdd4de08e 100644 --- a/.azure/modules/postgreSql/create.bicep +++ b/.azure/modules/postgreSql/create.bicep @@ -1,6 +1,6 @@ param namePrefix string param location string -param keyVaultName string +param environmentKeyVaultName string param srcSecretName string @export() @@ -81,7 +81,7 @@ resource postgres 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' = { module adoConnectionString '../keyvault/upsertSecret.bicep' = { name: 'adoConnectionString' params: { - destKeyVaultName: keyVaultName + destKeyVaultName: environmentKeyVaultName secretName: 'dialogportenAdoConnectionString' secretValue: 'Server=${postgres.properties.fullyQualifiedDomainName};Database=${databaseName};Port=5432;User Id=${administratorLogin};Password=${administratorLoginPassword};Ssl Mode=Require;Trust Server Certificate=true;' } @@ -90,7 +90,7 @@ module adoConnectionString '../keyvault/upsertSecret.bicep' = { module psqlConnectionString '../keyvault/upsertSecret.bicep' = { name: 'psqlConnectionString' params: { - destKeyVaultName: keyVaultName + destKeyVaultName: environmentKeyVaultName secretName: 'dialogportenPsqlConnectionString' secretValue: 'psql \'host=${postgres.properties.fullyQualifiedDomainName} port=5432 dbname=${databaseName} user=${administratorLogin} password=${administratorLoginPassword} sslmode=require\'' } diff --git a/.azure/modules/redis/main.bicep b/.azure/modules/redis/main.bicep new file mode 100644 index 000000000..24a9f9eaa --- /dev/null +++ b/.azure/modules/redis/main.bicep @@ -0,0 +1,45 @@ +param namePrefix string +param location string +@minLength(1) +param environmentKeyVaultName string +@minLength(1) +param version string + +@export() +type Sku = { + name: 'Basic' | 'Standard' | 'Premium' + family: 'C' | 'P' + @minValue(1) + capacity: int +} + +param sku Sku + +// https://learn.microsoft.com/en-us/azure/templates/microsoft.cache/redis?pivots=deployment-language-bicep +resource redis 'Microsoft.Cache/Redis@2023-08-01' = { + name: '${namePrefix}-redis' + location: location + identity: { + type: 'SystemAssigned' + } + properties: { + sku: sku + enableNonSslPort: false + redisConfiguration: { + 'maxmemory-policy': 'allkeys-lru' + } + redisVersion: version + } +} + +module redisConnectionString '../keyvault/upsertSecret.bicep' = { + name: 'adoConnectionString' + params: { + destKeyVaultName: environmentKeyVaultName + secretName: 'dialogportenRedisConnectionString' + // disable public access? Use vnet here maybe? + secretValue: 'redis://${redis.properties.hostName}:${redis.properties.port},password=${redis.properties.accessKeys.primaryKey},ssl=True,abortConnect=False' + } +} + +output connectionStringSecretUri string = redisConnectionString.outputs.secretUri From f3dc0a46297f9e2f19bacc5664bd190a7c266179 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 15:13:29 +0100 Subject: [PATCH 05/11] cleanup --- .azure/infrastructure/main.json | 1881 ------------------------------- 1 file changed, 1881 deletions(-) delete mode 100644 .azure/infrastructure/main.json diff --git a/.azure/infrastructure/main.json b/.azure/infrastructure/main.json deleted file mode 100644 index f73bb18ed..000000000 --- a/.azure/infrastructure/main.json +++ /dev/null @@ -1,1881 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "18102634065330484612" - } - }, - "definitions": { - "AppConfigurationSku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "standard" - ] - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "../modules/appConfiguration/create.bicep" - } - } - }, - "AppInsightsSku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "CapacityReservation", - "Free", - "LACluster", - "PerGB2018", - "PerNode", - "Premium", - "Standalone", - "Standard" - ] - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "../modules/applicationInsights/create.bicep" - } - } - }, - "KeyVaultSku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "premium", - "standard" - ] - }, - "family": { - "type": "string", - "allowedValues": [ - "A" - ] - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "../modules/keyvault/create.bicep" - } - } - }, - "PostgresSku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "Standard_B1ms" - ] - }, - "tier": { - "type": "string", - "allowedValues": [ - "Burstable", - "GeneralPurpose", - "MemoryOptimized" - ] - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "../modules/postgreSql/create.bicep" - } - } - }, - "SlackNotifierSku": { - "type": "object", - "properties": { - "storageAccountName": { - "type": "string", - "allowedValues": [ - "Premium_LRS", - "Premium_ZRS", - "Standard_GRS", - "Standard_LRS", - "Standard_RAGRS", - "Standard_ZRS" - ] - }, - "applicationServicePlanName": { - "type": "string", - "allowedValues": [ - "B1", - "B2", - "B3", - "D1", - "F1", - "I1", - "I2", - "I3", - "P1", - "P1V2", - "P2", - "P2V2", - "P3", - "P3V2", - "S1", - "S2", - "S3", - "Y1", - "Y1v2", - "Y1v2Isolated", - "Y2", - "Y2v2", - "Y2v2Isolated", - "Y3", - "Y3v2", - "Y3v2Isolated" - ] - }, - "applicationServicePlanTier": { - "type": "string", - "allowedValues": [ - "Basic", - "Dynamic", - "Free", - "Isolated", - "Premium", - "Shared", - "Standard" - ] - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "../modules/functionApp/slackNotifier.bicep" - } - } - } - }, - "parameters": { - "environment": { - "type": "string", - "minLength": 3 - }, - "location": { - "type": "string", - "minLength": 3 - }, - "keyVaultSourceKeys": { - "type": "array" - }, - "dialogportenPgAdminPassword": { - "type": "securestring", - "minLength": 3 - }, - "sourceKeyVaultSubscriptionId": { - "type": "securestring", - "minLength": 3 - }, - "sourceKeyVaultResourceGroup": { - "type": "securestring", - "minLength": 3 - }, - "sourceKeyVaultName": { - "type": "securestring", - "minLength": 3 - }, - "keyVaultSku": { - "$ref": "#/definitions/KeyVaultSku" - }, - "appConfigurationSku": { - "$ref": "#/definitions/AppConfigurationSku" - }, - "appInsightsSku": { - "$ref": "#/definitions/AppInsightsSku" - }, - "slackNotifierSku": { - "$ref": "#/definitions/SlackNotifierSku" - }, - "postgresSku": { - "$ref": "#/definitions/PostgresSku" - } - }, - "variables": { - "secrets": { - "dialogportenPgAdminPassword": "[parameters('dialogportenPgAdminPassword')]", - "sourceKeyVaultSubscriptionId": "[parameters('sourceKeyVaultSubscriptionId')]", - "sourceKeyVaultResourceGroup": "[parameters('sourceKeyVaultResourceGroup')]", - "sourceKeyVaultName": "[parameters('sourceKeyVaultName')]" - }, - "namePrefix": "[format('dp-be-{0}', parameters('environment'))]", - "srcKeyVault": { - "name": "[variables('secrets').sourceKeyVaultName]", - "subscriptionId": "[variables('secrets').sourceKeyVaultSubscriptionId]", - "resourceGroupName": "[variables('secrets').sourceKeyVaultResourceGroup]" - } - }, - "resources": { - "resourceGroup": { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2023-07-01", - "name": "[format('{0}-rg', variables('namePrefix'))]", - "location": "[parameters('location')]" - }, - "srcKeyVaultResource": { - "existing": true, - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2023-07-01", - "subscriptionId": "[variables('secrets').sourceKeyVaultSubscriptionId]", - "resourceGroup": "[variables('secrets').sourceKeyVaultResourceGroup]", - "name": "[variables('secrets').sourceKeyVaultName]" - }, - "keyVaultModule": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "keyVault", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namePrefix": { - "value": "[variables('namePrefix')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "sku": { - "value": "[parameters('keyVaultSku')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "2760954716125288010" - } - }, - "definitions": { - "Sku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "premium", - "standard" - ] - }, - "family": { - "type": "string", - "allowedValues": [ - "A" - ] - } - }, - "metadata": { - "__bicep_export!": true - } - } - }, - "parameters": { - "namePrefix": { - "type": "string" - }, - "location": { - "type": "string" - }, - "sku": { - "$ref": "#/definitions/Sku" - } - }, - "variables": { - "keyVaultName": "[take(format('{0}-kv-{1}', parameters('namePrefix'), uniqueString(resourceGroup().id)), 24)]" - }, - "resources": { - "keyVault": { - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2023-07-01", - "name": "[variables('keyVaultName')]", - "location": "[parameters('location')]", - "properties": { - "enablePurgeProtection": null, - "enabledForTemplateDeployment": false, - "sku": "[parameters('sku')]", - "tenantId": "[subscription().tenantId]", - "accessPolicies": [] - } - } - }, - "outputs": { - "name": { - "type": "string", - "value": "[variables('keyVaultName')]" - } - } - } - }, - "dependsOn": [ - "resourceGroup" - ] - }, - "appConfiguration": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "appConfiguration", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namePrefix": { - "value": "[variables('namePrefix')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "sku": { - "value": "[parameters('appConfigurationSku')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "988952339729943041" - } - }, - "definitions": { - "Sku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "standard" - ] - } - }, - "metadata": { - "__bicep_export!": true - } - } - }, - "parameters": { - "namePrefix": { - "type": "string" - }, - "location": { - "type": "string" - }, - "sku": { - "$ref": "#/definitions/Sku" - } - }, - "resources": { - "appConfig::configStoreKeyValue": { - "type": "Microsoft.AppConfiguration/configurationStores/keyValues", - "apiVersion": "2023-03-01", - "name": "[format('{0}/{1}', format('{0}-appConfiguration', parameters('namePrefix')), 'Sentinel')]", - "properties": { - "value": "1" - }, - "dependsOn": [ - "appConfig" - ] - }, - "appConfig": { - "type": "Microsoft.AppConfiguration/configurationStores", - "apiVersion": "2023-03-01", - "name": "[format('{0}-appConfiguration', parameters('namePrefix'))]", - "location": "[parameters('location')]", - "sku": "[parameters('sku')]", - "properties": { - "enablePurgeProtection": false - } - } - }, - "outputs": { - "endpoint": { - "type": "string", - "value": "[reference('appConfig').endpoint]" - }, - "name": { - "type": "string", - "value": "[format('{0}-appConfiguration', parameters('namePrefix'))]" - } - } - } - }, - "dependsOn": [ - "resourceGroup" - ] - }, - "appInsights": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "appInsights", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namePrefix": { - "value": "[variables('namePrefix')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "sku": { - "value": "[parameters('appInsightsSku')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10082346743241499787" - } - }, - "definitions": { - "Sku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "CapacityReservation", - "Free", - "LACluster", - "PerGB2018", - "PerNode", - "Premium", - "Standalone", - "Standard" - ] - } - }, - "metadata": { - "__bicep_export!": true - } - } - }, - "parameters": { - "namePrefix": { - "type": "string" - }, - "location": { - "type": "string" - }, - "sku": { - "$ref": "#/definitions/Sku" - } - }, - "resources": { - "appInsightsWorkspace": { - "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2022-10-01", - "name": "[format('{0}-insightsWorkspace', parameters('namePrefix'))]", - "location": "[parameters('location')]", - "properties": { - "retentionInDays": 30, - "sku": "[parameters('sku')]", - "workspaceCapping": { - "dailyQuotaGb": -1 - } - } - }, - "appInsights": { - "type": "Microsoft.Insights/components", - "apiVersion": "2020-02-02", - "name": "[format('{0}-applicationInsights', parameters('namePrefix'))]", - "location": "[parameters('location')]", - "kind": "web", - "properties": { - "Application_Type": "web", - "WorkspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('{0}-insightsWorkspace', parameters('namePrefix')))]", - "Flow_Type": "Bluefield", - "Request_Source": "rest" - }, - "dependsOn": [ - "appInsightsWorkspace" - ] - } - }, - "outputs": { - "connectionString": { - "type": "string", - "value": "[reference('appInsights').ConnectionString]" - }, - "appInsightsWorkspaceName": { - "type": "string", - "value": "[format('{0}-insightsWorkspace', parameters('namePrefix'))]" - }, - "appInsightsName": { - "type": "string", - "value": "[format('{0}-applicationInsights', parameters('namePrefix'))]" - } - } - } - }, - "dependsOn": [ - "resourceGroup" - ] - }, - "postgresql": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "postgresql", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namePrefix": { - "value": "[variables('namePrefix')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "keyVaultName": { - "value": "[reference('keyVaultModule').outputs.name.value]" - }, - "srcKeyVault": { - "value": "[variables('srcKeyVault')]" - }, - "srcSecretName": { - "value": "[format('dialogportenPgAdminPassword{0}', parameters('environment'))]" - }, - "administratorLoginPassword": "[if(contains(parameters('keyVaultSourceKeys'), format('dialogportenPgAdminPassword{0}', parameters('environment'))), createObject('reference', createObject('keyVault', createObject('id', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', variables('secrets').sourceKeyVaultSubscriptionId, variables('secrets').sourceKeyVaultResourceGroup), 'Microsoft.KeyVault/vaults', variables('secrets').sourceKeyVaultName)), 'secretName', format('dialogportenPgAdminPassword{0}', parameters('environment')))), createObject('value', variables('secrets').dialogportenPgAdminPassword))]", - "sku": { - "value": "[parameters('postgresSku')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "52111473636837092" - } - }, - "definitions": { - "Sku": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "Standard_B1ms" - ] - }, - "tier": { - "type": "string", - "allowedValues": [ - "Burstable", - "GeneralPurpose", - "MemoryOptimized" - ] - } - }, - "metadata": { - "__bicep_export!": true - } - } - }, - "parameters": { - "namePrefix": { - "type": "string" - }, - "location": { - "type": "string" - }, - "keyVaultName": { - "type": "string" - }, - "srcSecretName": { - "type": "string" - }, - "sku": { - "$ref": "#/definitions/Sku" - }, - "srcKeyVault": { - "type": "secureObject" - }, - "administratorLoginPassword": { - "type": "securestring" - } - }, - "variables": { - "administratorLogin": "dialogportenPgAdmin", - "databaseName": "dialogporten" - }, - "resources": { - "postgres::database": { - "type": "Microsoft.DBforPostgreSQL/flexibleServers/databases", - "apiVersion": "2022-12-01", - "name": "[format('{0}/{1}', format('{0}-postgres', parameters('namePrefix')), variables('databaseName'))]", - "properties": { - "charset": "UTF8", - "collation": "en_US.utf8" - }, - "dependsOn": [ - "postgres" - ] - }, - "postgres::allowAzureAccess": { - "type": "Microsoft.DBforPostgreSQL/flexibleServers/firewallRules", - "apiVersion": "2022-12-01", - "name": "[format('{0}/{1}', format('{0}-postgres', parameters('namePrefix')), 'AllowAccessFromAzure')]", - "properties": { - "startIpAddress": "0.0.0.0", - "endIpAddress": "0.0.0.0" - }, - "dependsOn": [ - "postgres" - ] - }, - "postgres": { - "type": "Microsoft.DBforPostgreSQL/flexibleServers", - "apiVersion": "2022-12-01", - "name": "[format('{0}-postgres', parameters('namePrefix'))]", - "location": "[parameters('location')]", - "properties": { - "version": "15", - "administratorLogin": "[variables('administratorLogin')]", - "administratorLoginPassword": "[parameters('administratorLoginPassword')]", - "storage": { - "storageSizeGB": 32 - }, - "dataEncryption": { - "type": "SystemManaged" - }, - "replicationRole": "Primary" - }, - "sku": "[parameters('sku')]" - }, - "saveAdmPassword": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('Save_{0}', parameters('srcSecretName'))]", - "subscriptionId": "[parameters('srcKeyVault').subscriptionId]", - "resourceGroup": "[parameters('srcKeyVault').resourceGroupName]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "destKeyVaultName": { - "value": "[parameters('srcKeyVault').name]" - }, - "secretName": { - "value": "[parameters('srcSecretName')]" - }, - "secretValue": { - "value": "[parameters('administratorLoginPassword')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4960712788860156215" - } - }, - "parameters": { - "destKeyVaultName": { - "type": "string" - }, - "secretName": { - "type": "string" - }, - "secretValue": { - "type": "securestring" - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", - "properties": { - "value": "[parameters('secretValue')]" - } - } - ], - "outputs": { - "secretUri": { - "type": "string", - "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" - } - } - } - } - }, - "adoConnectionString": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "adoConnectionString", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "destKeyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "secretName": { - "value": "dialogportenAdoConnectionString" - }, - "secretValue": { - "value": "[format('Server={0};Database={1};Port=5432;User Id={2};Password={3};Ssl Mode=Require;Trust Server Certificate=true;', reference('postgres').fullyQualifiedDomainName, variables('databaseName'), variables('administratorLogin'), parameters('administratorLoginPassword'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4960712788860156215" - } - }, - "parameters": { - "destKeyVaultName": { - "type": "string" - }, - "secretName": { - "type": "string" - }, - "secretValue": { - "type": "securestring" - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", - "properties": { - "value": "[parameters('secretValue')]" - } - } - ], - "outputs": { - "secretUri": { - "type": "string", - "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" - } - } - } - }, - "dependsOn": [ - "postgres" - ] - }, - "psqlConnectionString": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "psqlConnectionString", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "destKeyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "secretName": { - "value": "dialogportenPsqlConnectionString" - }, - "secretValue": { - "value": "[format('psql ''host={0} port=5432 dbname={1} user={2} password={3} sslmode=require''', reference('postgres').fullyQualifiedDomainName, variables('databaseName'), variables('administratorLogin'), parameters('administratorLoginPassword'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4960712788860156215" - } - }, - "parameters": { - "destKeyVaultName": { - "type": "string" - }, - "secretName": { - "type": "string" - }, - "secretValue": { - "type": "securestring" - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", - "properties": { - "value": "[parameters('secretValue')]" - } - } - ], - "outputs": { - "secretUri": { - "type": "string", - "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" - } - } - } - }, - "dependsOn": [ - "postgres" - ] - } - }, - "outputs": { - "adoConnectionStringSecretUri": { - "type": "string", - "value": "[reference('adoConnectionString').outputs.secretUri.value]" - }, - "psqlConnectionStringSecretUri": { - "type": "string", - "value": "[reference('psqlConnectionString').outputs.secretUri.value]" - } - } - } - }, - "dependsOn": [ - "keyVaultModule", - "resourceGroup", - "srcKeyVaultResource" - ] - }, - "copyEnvironmentSecrets": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "copyEnvironmentSecrets", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "srcKeyVaultKeys": { - "value": "[parameters('keyVaultSourceKeys')]" - }, - "srcKeyVaultName": { - "value": "[variables('secrets').sourceKeyVaultName]" - }, - "srcKeyVaultRGNName": { - "value": "[variables('secrets').sourceKeyVaultResourceGroup]" - }, - "srcKeyVaultSubId": { - "value": "[variables('secrets').sourceKeyVaultSubscriptionId]" - }, - "destKeyVaultName": { - "value": "[reference('keyVaultModule').outputs.name.value]" - }, - "secretPrefix": { - "value": "[format('dialogporten--{0}--', parameters('environment'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "44147448919080552" - } - }, - "parameters": { - "srcKeyVaultKeys": { - "type": "array" - }, - "srcKeyVaultName": { - "type": "string" - }, - "srcKeyVaultRGNName": { - "type": "string", - "defaultValue": "[resourceGroup().name]" - }, - "srcKeyVaultSubId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]" - }, - "destKeyVaultName": { - "type": "string" - }, - "destKeyVaultRGName": { - "type": "string", - "defaultValue": "[resourceGroup().name]" - }, - "destKeyVaultSubId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]" - }, - "secretPrefix": { - "type": "string" - }, - "removeSecretPrefix": { - "type": "bool", - "defaultValue": true - } - }, - "variables": { - "copy": [ - { - "name": "environmentKeys", - "count": "[length(parameters('srcKeyVaultKeys'))]", - "input": { - "isEnvironmentKey": "[startsWith(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'))]", - "value": "[if(parameters('removeSecretPrefix'), replace(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'), ''), parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')])]", - "fullName": "[parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')]]" - } - } - ] - }, - "resources": [ - { - "copy": { - "name": "secrets", - "count": "[length(variables('environmentKeys'))]" - }, - "condition": "[variables('environmentKeys')[copyIndex()].isEnvironmentKey]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[variables('environmentKeys')[copyIndex()].value]", - "subscriptionId": "[parameters('destKeyVaultSubId')]", - "resourceGroup": "[parameters('destKeyVaultRGName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "destKeyVaultName": { - "value": "[parameters('destKeyVaultName')]" - }, - "secretName": { - "value": "[variables('environmentKeys')[copyIndex()].value]" - }, - "secretValue": { - "reference": { - "keyVault": { - "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('srcKeyVaultSubId'), parameters('srcKeyVaultRGNName')), 'Microsoft.KeyVault/vaults', parameters('srcKeyVaultName'))]" - }, - "secretName": "[variables('environmentKeys')[copyIndex()].fullName]" - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4960712788860156215" - } - }, - "parameters": { - "destKeyVaultName": { - "type": "string" - }, - "secretName": { - "type": "string" - }, - "secretValue": { - "type": "securestring" - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", - "properties": { - "value": "[parameters('secretValue')]" - } - } - ], - "outputs": { - "secretUri": { - "type": "string", - "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" - } - } - } - } - } - ] - } - }, - "dependsOn": [ - "keyVaultModule", - "resourceGroup" - ] - }, - "copyCrossEnvironmentSecrets": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "copyCrossEnvironmentSecrets", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "srcKeyVaultKeys": { - "value": "[parameters('keyVaultSourceKeys')]" - }, - "srcKeyVaultName": { - "value": "[variables('secrets').sourceKeyVaultName]" - }, - "srcKeyVaultRGNName": { - "value": "[variables('secrets').sourceKeyVaultResourceGroup]" - }, - "srcKeyVaultSubId": { - "value": "[variables('secrets').sourceKeyVaultSubscriptionId]" - }, - "destKeyVaultName": { - "value": "[reference('keyVaultModule').outputs.name.value]" - }, - "secretPrefix": { - "value": "dialogporten--any--" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "44147448919080552" - } - }, - "parameters": { - "srcKeyVaultKeys": { - "type": "array" - }, - "srcKeyVaultName": { - "type": "string" - }, - "srcKeyVaultRGNName": { - "type": "string", - "defaultValue": "[resourceGroup().name]" - }, - "srcKeyVaultSubId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]" - }, - "destKeyVaultName": { - "type": "string" - }, - "destKeyVaultRGName": { - "type": "string", - "defaultValue": "[resourceGroup().name]" - }, - "destKeyVaultSubId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]" - }, - "secretPrefix": { - "type": "string" - }, - "removeSecretPrefix": { - "type": "bool", - "defaultValue": true - } - }, - "variables": { - "copy": [ - { - "name": "environmentKeys", - "count": "[length(parameters('srcKeyVaultKeys'))]", - "input": { - "isEnvironmentKey": "[startsWith(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'))]", - "value": "[if(parameters('removeSecretPrefix'), replace(parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')], parameters('secretPrefix'), ''), parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')])]", - "fullName": "[parameters('srcKeyVaultKeys')[copyIndex('environmentKeys')]]" - } - } - ] - }, - "resources": [ - { - "copy": { - "name": "secrets", - "count": "[length(variables('environmentKeys'))]" - }, - "condition": "[variables('environmentKeys')[copyIndex()].isEnvironmentKey]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[variables('environmentKeys')[copyIndex()].value]", - "subscriptionId": "[parameters('destKeyVaultSubId')]", - "resourceGroup": "[parameters('destKeyVaultRGName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "destKeyVaultName": { - "value": "[parameters('destKeyVaultName')]" - }, - "secretName": { - "value": "[variables('environmentKeys')[copyIndex()].value]" - }, - "secretValue": { - "reference": { - "keyVault": { - "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('srcKeyVaultSubId'), parameters('srcKeyVaultRGNName')), 'Microsoft.KeyVault/vaults', parameters('srcKeyVaultName'))]" - }, - "secretName": "[variables('environmentKeys')[copyIndex()].fullName]" - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4960712788860156215" - } - }, - "parameters": { - "destKeyVaultName": { - "type": "string" - }, - "secretName": { - "type": "string" - }, - "secretValue": { - "type": "securestring" - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName'))]", - "properties": { - "value": "[parameters('secretValue')]" - } - } - ], - "outputs": { - "secretUri": { - "type": "string", - "value": "[reference(resourceId('Microsoft.KeyVault/vaults/secrets', split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[0], split(format('{0}/{1}', parameters('destKeyVaultName'), parameters('secretName')), '/')[1]), '2023-07-01').secretUri]" - } - } - } - } - } - ] - } - }, - "dependsOn": [ - "keyVaultModule", - "resourceGroup" - ] - }, - "slackNotifier": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "slackNotifier", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "keyVaultName": { - "value": "[reference('keyVaultModule').outputs.name.value]" - }, - "namePrefix": { - "value": "[variables('namePrefix')]" - }, - "applicationInsightsName": { - "value": "[reference('appInsights').outputs.appInsightsName.value]" - }, - "sku": { - "value": "[parameters('slackNotifierSku')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14801988153889955025" - } - }, - "definitions": { - "Sku": { - "type": "object", - "properties": { - "storageAccountName": { - "type": "string", - "allowedValues": [ - "Premium_LRS", - "Premium_ZRS", - "Standard_GRS", - "Standard_LRS", - "Standard_RAGRS", - "Standard_ZRS" - ] - }, - "applicationServicePlanName": { - "type": "string", - "allowedValues": [ - "B1", - "B2", - "B3", - "D1", - "F1", - "I1", - "I2", - "I3", - "P1", - "P1V2", - "P2", - "P2V2", - "P3", - "P3V2", - "S1", - "S2", - "S3", - "Y1", - "Y1v2", - "Y1v2Isolated", - "Y2", - "Y2v2", - "Y2v2Isolated", - "Y3", - "Y3v2", - "Y3v2Isolated" - ] - }, - "applicationServicePlanTier": { - "type": "string", - "allowedValues": [ - "Basic", - "Dynamic", - "Free", - "Isolated", - "Premium", - "Shared", - "Standard" - ] - } - }, - "metadata": { - "__bicep_export!": true - } - } - }, - "parameters": { - "location": { - "type": "string" - }, - "applicationInsightsName": { - "type": "string" - }, - "namePrefix": { - "type": "string" - }, - "keyVaultName": { - "type": "string" - }, - "sku": { - "$ref": "#/definitions/Sku" - } - }, - "variables": { - "storageAccountName": "[format('{0}{1}sa', replace(parameters('namePrefix'), '-', ''), substring('slacknotifier', 0, 10))]", - "functionAppName": "[format('{0}-slacknotifier-fa', parameters('namePrefix'))]" - }, - "resources": { - "storageAccount": { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-01-01", - "name": "[variables('storageAccountName')]", - "location": "[parameters('location')]", - "sku": { - "name": "[parameters('sku').storageAccountName]" - }, - "kind": "Storage", - "properties": { - "supportsHttpsTrafficOnly": true, - "defaultToOAuthAuthentication": true - } - }, - "applicationServicePlan": { - "type": "Microsoft.Web/serverfarms", - "apiVersion": "2023-01-01", - "name": "[format('{0}-slacknotifier-asp', parameters('namePrefix'))]", - "location": "[parameters('location')]", - "sku": { - "name": "[parameters('sku').applicationServicePlanName]", - "tier": "[parameters('sku').applicationServicePlanTier]" - }, - "properties": {} - }, - "applicationInsights": { - "existing": true, - "type": "Microsoft.Insights/components", - "apiVersion": "2020-02-02", - "name": "[parameters('applicationInsightsName')]" - }, - "functionApp": { - "type": "Microsoft.Web/sites", - "apiVersion": "2023-01-01", - "name": "[variables('functionAppName')]", - "location": "[parameters('location')]", - "kind": "functionapp", - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', format('{0}-slacknotifier-asp', parameters('namePrefix')))]", - "publicNetworkAccess": "Enabled", - "siteConfig": {}, - "httpsOnly": true - }, - "dependsOn": [ - "applicationServicePlan" - ] - }, - "notifyDevTeam": { - "type": "Microsoft.Insights/actionGroups", - "apiVersion": "2023-01-01", - "name": "[format('{0}-notify-devteam-ag', parameters('namePrefix'))]", - "location": "Global", - "properties": { - "enabled": true, - "groupShortName": "DevNotify", - "azureFunctionReceivers": [ - { - "name": "[reference('functionApp').defaultHostName]", - "functionName": "ForwardAlertToSlack", - "functionAppResourceId": "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]", - "httpTriggerUrl": "[format('https://{0}/api/forwardalerttoslack?code={1}', reference('functionApp').defaultHostName, listkeys(format('{0}/host/default', resourceId('Microsoft.Web/sites', variables('functionAppName'))), '2023-01-01').functionKeys.default)]", - "useCommonAlertSchema": true - } - ] - }, - "dependsOn": [ - "functionApp" - ] - }, - "exceptionOccuredAlertRule": { - "type": "Microsoft.Insights/scheduledQueryRules", - "apiVersion": "2023-03-15-preview", - "name": "[format('{0}-exception-occured-sqr', parameters('namePrefix'))]", - "location": "[parameters('location')]", - "properties": { - "enabled": true, - "severity": 1, - "evaluationFrequency": "PT5M", - "windowSize": "PT5M", - "scopes": [ - "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]" - ], - "autoMitigate": false, - "targetResourceTypes": [ - "microsoft.insights/components" - ], - "criteria": { - "allOf": [ - { - "query": "exceptions | summarize count = count() by environment = tostring(customDimensions.AspNetCoreEnvironment), problemId", - "operator": "GreaterThan", - "threshold": 0, - "timeAggregation": "Count", - "failingPeriods": { - "numberOfEvaluationPeriods": 1, - "minFailingPeriodsToAlert": 1 - } - } - ] - }, - "actions": { - "actionGroups": [ - "[resourceId('Microsoft.Insights/actionGroups', format('{0}-notify-devteam-ag', parameters('namePrefix')))]" - ] - } - }, - "dependsOn": [ - "applicationInsights", - "notifyDevTeam" - ] - }, - "updateAppSettings": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-appsettings', variables('functionAppName'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "webAppName": { - "value": "[variables('functionAppName')]" - }, - "currentAppSettings": { - "value": "[list(resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings'), '2023-01-01').properties]" - }, - "appSettings": { - "value": { - "AzureWebJobsStorage": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2023-01-01').keys[0].value)]", - "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2023-01-01').keys[0].value)]", - "WEBSITE_CONTENTSHARE": "[toLower(variables('functionAppName'))]", - "FUNCTIONS_EXTENSION_VERSION": "~4", - "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference('applicationInsights').InstrumentationKey]", - "Slack__WebhookUrl": "[format('@Microsoft.KeyVault(VaultName={0};SecretName=Slack--Webhook--Url)', parameters('keyVaultName'))]", - "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10763973054038990940" - } - }, - "parameters": { - "webAppName": { - "type": "string" - }, - "appSettings": { - "type": "object" - }, - "currentAppSettings": { - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.Web/sites/config", - "apiVersion": "2023-01-01", - "name": "[format('{0}/{1}', parameters('webAppName'), 'appsettings')]", - "properties": "[union(parameters('currentAppSettings'), parameters('appSettings'))]" - } - ] - } - }, - "dependsOn": [ - "applicationInsights", - "storageAccount" - ] - } - }, - "outputs": { - "functionAppPrincipalId": { - "type": "string", - "value": "[reference('functionApp', '2023-01-01', 'full').identity.principalId]" - } - } - } - }, - "dependsOn": [ - "appInsights", - "keyVaultModule", - "resourceGroup" - ] - }, - "containerAppEnv": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "containerAppEnv", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namePrefix": { - "value": "[variables('namePrefix')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "appInsightWorkspaceName": { - "value": "[reference('appInsights').outputs.appInsightsWorkspaceName.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10299501857515385890" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "namePrefix": { - "type": "string" - }, - "appInsightWorkspaceName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.App/managedEnvironments", - "apiVersion": "2023-05-01", - "name": "[format('{0}-cae', parameters('namePrefix'))]", - "location": "[parameters('location')]", - "properties": { - "appLogsConfiguration": { - "destination": "log-analytics", - "logAnalyticsConfiguration": { - "customerId": "[reference(resourceId('Microsoft.OperationalInsights/workspaces', parameters('appInsightWorkspaceName')), '2022-10-01').customerId]", - "sharedKey": "[listKeys(resourceId('Microsoft.OperationalInsights/workspaces', parameters('appInsightWorkspaceName')), '2022-10-01').primarySharedKey]" - } - } - } - } - ], - "outputs": { - "containerAppEnvId": { - "type": "string", - "value": "[resourceId('Microsoft.App/managedEnvironments', format('{0}-cae', parameters('namePrefix')))]" - } - } - } - }, - "dependsOn": [ - "appInsights", - "resourceGroup" - ] - }, - "appInsightsReaderAccessPolicy": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "appInsightsReaderAccessPolicy", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "appInsightsName": { - "value": "[reference('appInsights').outputs.appInsightsName.value]" - }, - "principalIds": { - "value": [ - "[reference('slackNotifier').outputs.functionAppPrincipalId.value]" - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "17437758389307278342" - } - }, - "parameters": { - "appInsightsName": { - "type": "string" - }, - "principalIds": { - "type": "array" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignments", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Insights/components/{0}', parameters('appInsightsName'))]", - "name": "[guid(subscription().id, parameters('principalIds')[copyIndex()], subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "ServicePrincipal" - } - } - ] - } - }, - "dependsOn": [ - "appInsights", - "resourceGroup", - "slackNotifier" - ] - }, - "appConfigConfigurations": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "AppConfig_Add_DialogDbConnectionString", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "configStoreName": { - "value": "[reference('appConfiguration').outputs.name.value]" - }, - "key": { - "value": "Infrastructure:DialogDbConnectionString" - }, - "value": { - "value": "[reference('postgresql').outputs.adoConnectionStringSecretUri.value]" - }, - "keyValueType": { - "value": "keyVaultReference" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "12264379860409378346" - } - }, - "parameters": { - "configStoreName": { - "type": "string", - "metadata": { - "description": "Specifies the name of the App Configuration store." - } - }, - "key": { - "type": "string", - "metadata": { - "description": "Specifies the names of the key-value resources. The name is a combination of key and label with $ as delimiter. The label is optional." - } - }, - "value": { - "type": "string", - "metadata": { - "description": "Specifies the values of the key-value resources" - } - }, - "contentType": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Specifies the content type of the key-value resources. For feature flag set keyValueType=featureFlag. For Key Value reference set keyValueType=featureFlag. Otherwise, it's optional." - } - }, - "keyValueType": { - "type": "string", - "defaultValue": "custom", - "allowedValues": [ - "keyVaultReference", - "featureFlag", - "custom" - ], - "metadata": { - "description": "Specifies the type of the key-value resources" - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Adds tags for the key-value resources" - } - } - }, - "variables": { - "parsedContentType": "[if(equals(parameters('keyValueType'), 'keyVaultReference'), 'application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8', if(equals(parameters('keyValueType'), 'featureFlag'), 'application/vnd.microsoft.appconfig.ff+json;charset=utf-8', parameters('contentType')))]", - "parsedValue": "[if(equals(parameters('keyValueType'), 'keyVaultReference'), format('{{\"uri\":\"{0}\"}}', parameters('value')), parameters('value'))]" - }, - "resources": [ - { - "type": "Microsoft.AppConfiguration/configurationStores/keyValues", - "apiVersion": "2023-03-01", - "name": "[format('{0}/{1}', parameters('configStoreName'), parameters('key'))]", - "properties": { - "value": "[variables('parsedValue')]", - "contentType": "[variables('parsedContentType')]", - "tags": "[parameters('tags')]" - } - } - ] - } - }, - "dependsOn": [ - "appConfiguration", - "postgresql", - "resourceGroup" - ] - }, - "keyVaultReaderAccessPolicy": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "keyVaultReaderAccessPolicyFunctions", - "resourceGroup": "[format('{0}-rg', variables('namePrefix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyvaultName": { - "value": "[reference('keyVaultModule').outputs.name.value]" - }, - "principalIds": { - "value": [ - "[reference('slackNotifier').outputs.functionAppPrincipalId.value]" - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "8309515987304945736" - } - }, - "parameters": { - "keyvaultName": { - "type": "string" - }, - "principalIds": { - "type": "array" - } - }, - "variables": { - "copy": [ - { - "name": "readerAccessPoliciesArray", - "count": "[length(parameters('principalIds'))]", - "input": { - "objectId": "[parameters('principalIds')[copyIndex('readerAccessPoliciesArray')]]", - "tenantId": "[subscription().tenantId]", - "permissions": { - "certificates": [ - "get", - "list" - ], - "keys": [ - "get", - "list" - ], - "secrets": [ - "get", - "list" - ] - } - } - } - ] - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/accessPolicies", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('keyvaultName'), 'add')]", - "properties": { - "accessPolicies": "[variables('readerAccessPoliciesArray')]" - } - } - ] - } - }, - "dependsOn": [ - "keyVaultModule", - "resourceGroup", - "slackNotifier" - ] - } - }, - "outputs": { - "resourceGroupName": { - "type": "string", - "value": "[format('{0}-rg', variables('namePrefix'))]" - }, - "containerAppEnvId": { - "type": "string", - "value": "[reference('containerAppEnv').outputs.containerAppEnvId.value]" - }, - "environmentKeyVaultName": { - "type": "string", - "value": "[reference('keyVaultModule').outputs.name.value]" - } - } -} \ No newline at end of file From 64b0321caeca9946b919922847cbb4185efde3b2 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 15:14:12 +0100 Subject: [PATCH 06/11] cleanup --- .azure/modules/appConfiguration/create.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/modules/appConfiguration/create.bicep b/.azure/modules/appConfiguration/create.bicep index 2eb62992b..459502c3b 100644 --- a/.azure/modules/appConfiguration/create.bicep +++ b/.azure/modules/appConfiguration/create.bicep @@ -3,7 +3,7 @@ param location string @export() type Sku = { - name: 'standard' + name: 'standard' } param sku Sku From b389dc52866acd520990f0e347080a87570b6440 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 15:22:37 +0100 Subject: [PATCH 07/11] feat(azure): add redis --- .azure/modules/redis/main.bicep | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.azure/modules/redis/main.bicep b/.azure/modules/redis/main.bicep index 24a9f9eaa..09eb69a36 100644 --- a/.azure/modules/redis/main.bicep +++ b/.azure/modules/redis/main.bicep @@ -12,7 +12,6 @@ type Sku = { @minValue(1) capacity: int } - param sku Sku // https://learn.microsoft.com/en-us/azure/templates/microsoft.cache/redis?pivots=deployment-language-bicep @@ -33,12 +32,12 @@ resource redis 'Microsoft.Cache/Redis@2023-08-01' = { } module redisConnectionString '../keyvault/upsertSecret.bicep' = { - name: 'adoConnectionString' + name: 'redisConnectionString' params: { - destKeyVaultName: environmentKeyVaultName - secretName: 'dialogportenRedisConnectionString' - // disable public access? Use vnet here maybe? - secretValue: 'redis://${redis.properties.hostName}:${redis.properties.port},password=${redis.properties.accessKeys.primaryKey},ssl=True,abortConnect=False' + destKeyVaultName: environmentKeyVaultName + secretName: 'dialogportenRedisConnectionString' + // disable public access? Use vnet here maybe? + secretValue: 'redis://${redis.properties.hostName}:${redis.properties.port},password=${redis.properties.accessKeys.primaryKey},ssl=True,abortConnect=False' } } From 2fd7b60983b85aaa96d4ec78ac5ca90a438ac371 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 15:58:51 +0100 Subject: [PATCH 08/11] cleanup --- .azure/infrastructure/production.bicepparam | 6 ++++++ .azure/infrastructure/soak.bicepparam | 6 ++++++ .azure/infrastructure/staging.bicepparam | 6 ++++++ .azure/infrastructure/test.bicepparam | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/.azure/infrastructure/production.bicepparam b/.azure/infrastructure/production.bicepparam index c72c688bb..320a69244 100644 --- a/.azure/infrastructure/production.bicepparam +++ b/.azure/infrastructure/production.bicepparam @@ -32,3 +32,9 @@ param postgresSku = { name: 'Standard_B1ms' tier: 'Burstable' } + +param redisSku = { + name: 'Basic' + family: 'C' + capacity: 1 +} diff --git a/.azure/infrastructure/soak.bicepparam b/.azure/infrastructure/soak.bicepparam index f2430332e..dd737f9c1 100644 --- a/.azure/infrastructure/soak.bicepparam +++ b/.azure/infrastructure/soak.bicepparam @@ -32,3 +32,9 @@ param postgresSku = { name: 'Standard_B1ms' tier: 'Burstable' } + +param redisSku = { + name: 'Basic' + family: 'C' + capacity: 1 +} diff --git a/.azure/infrastructure/staging.bicepparam b/.azure/infrastructure/staging.bicepparam index 1d729f11e..2f8855a55 100644 --- a/.azure/infrastructure/staging.bicepparam +++ b/.azure/infrastructure/staging.bicepparam @@ -32,3 +32,9 @@ param postgresSku = { name: 'Standard_B1ms' tier: 'Burstable' } + +param redisSku = { + name: 'Basic' + family: 'C' + capacity: 1 +} diff --git a/.azure/infrastructure/test.bicepparam b/.azure/infrastructure/test.bicepparam index 85519dc4f..fa52bb031 100644 --- a/.azure/infrastructure/test.bicepparam +++ b/.azure/infrastructure/test.bicepparam @@ -32,3 +32,9 @@ param postgresSku = { name: 'Standard_B1ms' tier: 'Burstable' } + +param redisSku = { + name: 'Basic' + family: 'C' + capacity: 1 +} From 4019054c20190c6d80cf3a4fcff1be529703dd73 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 5 Mar 2024 16:52:49 +0100 Subject: [PATCH 09/11] refactor to use managed identity --- .azure/applications/web-api-eu/main.bicep | 26 +++++++++++++++++++++++ .azure/infrastructure/main.bicep | 8 +++---- .azure/modules/redis/main.bicep | 11 +++++----- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/.azure/applications/web-api-eu/main.bicep b/.azure/applications/web-api-eu/main.bicep index aca633672..2a9a5caf8 100644 --- a/.azure/applications/web-api-eu/main.bicep +++ b/.azure/applications/web-api-eu/main.bicep @@ -14,6 +14,9 @@ param apimIp string param containerAppEnvironmentName string @minLength(3) @secure() +param redisName string +@minLength(3) +@secure() param appInsightConnectionString string @minLength(5) @secure() @@ -33,6 +36,10 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' name: containerAppEnvironmentName } +resource redis 'Microsoft.Cache/redis@2023-08-01' existing = { + name: redisName +} + var containerAppEnvVars = [ { name: 'ASPNETCORE_ENVIRONMENT' @@ -70,6 +77,25 @@ module containerApp '../../modules/containerApp/main.bicep' = { } } +resource redisCustomAccessPolicy 'Microsoft.Cache/redis/accessPolicies@2023-08-01' = { + parent: redis + name: containerAppName + properties: { + permissions: 'Contributor' + } +} + +resource redisCacheName_customAccessPolicyAssignment 'Microsoft.Cache/redis/accessPolicyAssignments@2023-08-01' = { + parent: redis + name: containerAppName + properties: { + accessPolicyName: containerAppName + objectId: containerApp.outputs.identityPrincipalId + objectIdAlias: '${containerAppName}-access-policy-redis' + } + dependsOn: [redisCustomAccessPolicy] +} + module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' = { name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { diff --git a/.azure/infrastructure/main.bicep b/.azure/infrastructure/main.bicep index a210db706..5b4472e0d 100644 --- a/.azure/infrastructure/main.bicep +++ b/.azure/infrastructure/main.bicep @@ -198,13 +198,13 @@ module postgresConnectionStringAppConfig '../modules/appConfiguration/upsertKeyV } } -module redisConnectionStringAppConfig '../modules/appConfiguration/upsertKeyValue.bicep' = { +module redisHostNameAppConfig '../modules/appConfiguration/upsertKeyValue.bicep' = { scope: resourceGroup - name: 'AppConfig_Add_DialogRedisConnectionString' + name: 'AppConfig_Add_RedisHostName' params: { configStoreName: appConfiguration.outputs.name - key: 'Infrastructure:DialogRedisConnectionString' - value: redis.outputs.connectionStringSecretUri + key: 'Infrastructure:RedisHostName' + value: redis.outputs.hostName keyValueType: 'keyVaultReference' } } diff --git a/.azure/modules/redis/main.bicep b/.azure/modules/redis/main.bicep index 09eb69a36..1979abf7d 100644 --- a/.azure/modules/redis/main.bicep +++ b/.azure/modules/redis/main.bicep @@ -25,20 +25,21 @@ resource redis 'Microsoft.Cache/Redis@2023-08-01' = { sku: sku enableNonSslPort: false redisConfiguration: { - 'maxmemory-policy': 'allkeys-lru' + 'aad-enabled': 'true' + 'maxmemory-policy': 'allkeys-lru' } redisVersion: version } } module redisConnectionString '../keyvault/upsertSecret.bicep' = { - name: 'redisConnectionString' + name: 'redisHostName' params: { destKeyVaultName: environmentKeyVaultName - secretName: 'dialogportenRedisConnectionString' + secretName: 'dialogportenRedisHostName' // disable public access? Use vnet here maybe? - secretValue: 'redis://${redis.properties.hostName}:${redis.properties.port},password=${redis.properties.accessKeys.primaryKey},ssl=True,abortConnect=False' + secretValue: redis.properties.hostName } } -output connectionStringSecretUri string = redisConnectionString.outputs.secretUri +output hostName string = redis.properties.hostName From 2795a57ff0f3e491687a044768020212a441a183 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 6 Mar 2024 09:29:41 +0100 Subject: [PATCH 10/11] feat: add redis --- .azure/applications/web-api-eu/main.bicep | 2 +- .../web-api-eu/staging.bicepparam | 1 + .../applications/web-api-eu/test.bicepparam | 1 + .../web-api-migration-job/staging.bicepparam | 1 + .azure/applications/web-api-so/main.bicep | 26 +++++++++++++++++++ .../web-api-so/staging.bicepparam | 1 + .../applications/web-api-so/test.bicepparam | 1 + .github/workflows/action-deploy-apps.yml | 3 +++ .github/workflows/ci-cd-main.yml | 1 + .github/workflows/ci-cd-staging.yml | 1 + 10 files changed, 37 insertions(+), 1 deletion(-) diff --git a/.azure/applications/web-api-eu/main.bicep b/.azure/applications/web-api-eu/main.bicep index 2a9a5caf8..6d2962964 100644 --- a/.azure/applications/web-api-eu/main.bicep +++ b/.azure/applications/web-api-eu/main.bicep @@ -85,7 +85,7 @@ resource redisCustomAccessPolicy 'Microsoft.Cache/redis/accessPolicies@2023-08-0 } } -resource redisCacheName_customAccessPolicyAssignment 'Microsoft.Cache/redis/accessPolicyAssignments@2023-08-01' = { +resource redisCustomAccessPolicyAssignment 'Microsoft.Cache/redis/accessPolicyAssignments@2023-08-01' = { parent: redis name: containerAppName properties: { diff --git a/.azure/applications/web-api-eu/staging.bicepparam b/.azure/applications/web-api-eu/staging.bicepparam index 447dcb2be..5b4a8010a 100644 --- a/.azure/applications/web-api-eu/staging.bicepparam +++ b/.azure/applications/web-api-eu/staging.bicepparam @@ -10,3 +10,4 @@ param environmentKeyVaultName = readEnvironmentVariable('ENVIRONMENT_KEY_VAULT_N param containerAppEnvironmentName = readEnvironmentVariable('CONTAINER_APP_ENVIRONMENT_NAME') param appInsightConnectionString = readEnvironmentVariable('APP_INSIGHTS_CONNECTION_STRING') param appConfigurationName = readEnvironmentVariable('APP_CONFIGURATION_NAME') +param redisName = readEnvironmentVariable('REDIS_NAME') diff --git a/.azure/applications/web-api-eu/test.bicepparam b/.azure/applications/web-api-eu/test.bicepparam index 9df5c026b..e40c26f7f 100644 --- a/.azure/applications/web-api-eu/test.bicepparam +++ b/.azure/applications/web-api-eu/test.bicepparam @@ -10,3 +10,4 @@ param environmentKeyVaultName = readEnvironmentVariable('ENVIRONMENT_KEY_VAULT_N param containerAppEnvironmentName = readEnvironmentVariable('CONTAINER_APP_ENVIRONMENT_NAME') param appInsightConnectionString = readEnvironmentVariable('APP_INSIGHTS_CONNECTION_STRING') param appConfigurationName = readEnvironmentVariable('APP_CONFIGURATION_NAME') +param redisName = readEnvironmentVariable('REDIS_NAME') diff --git a/.azure/applications/web-api-migration-job/staging.bicepparam b/.azure/applications/web-api-migration-job/staging.bicepparam index 581936cc5..6ae2b55fe 100644 --- a/.azure/applications/web-api-migration-job/staging.bicepparam +++ b/.azure/applications/web-api-migration-job/staging.bicepparam @@ -7,3 +7,4 @@ param containerAppEnvironmentName = readEnvironmentVariable('CONTAINER_APP_ENVIR //secrets param adoConnectionStringSecretUri = readEnvironmentVariable('ADO_CONNECTION_STRING_SECRET_URI') +param redisName = readEnvironmentVariable('REDIS_NAME') diff --git a/.azure/applications/web-api-so/main.bicep b/.azure/applications/web-api-so/main.bicep index e0d3a969c..0a6b9e399 100644 --- a/.azure/applications/web-api-so/main.bicep +++ b/.azure/applications/web-api-so/main.bicep @@ -14,6 +14,9 @@ param apimIp string param containerAppEnvironmentName string @minLength(3) @secure() +param redisName string +@minLength(3) +@secure() param appInsightConnectionString string @minLength(5) @secure() @@ -33,6 +36,10 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' name: containerAppEnvironmentName } +resource redis 'Microsoft.Cache/redis@2023-08-01' existing = { + name: redisName +} + var containerAppEnvVars = [ { name: 'ASPNETCORE_ENVIRONMENT' @@ -74,6 +81,25 @@ module containerApp '../../modules/containerApp/main.bicep' = { } } +resource redisCustomAccessPolicy 'Microsoft.Cache/redis/accessPolicies@2023-08-01' = { + parent: redis + name: containerAppName + properties: { + permissions: 'Contributor' + } +} + +resource redisCustomAccessPolicyAssignment 'Microsoft.Cache/redis/accessPolicyAssignments@2023-08-01' = { + parent: redis + name: containerAppName + properties: { + accessPolicyName: containerAppName + objectId: containerApp.outputs.identityPrincipalId + objectIdAlias: '${containerAppName}-access-policy-redis' + } + dependsOn: [redisCustomAccessPolicy] +} + module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' = { name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { diff --git a/.azure/applications/web-api-so/staging.bicepparam b/.azure/applications/web-api-so/staging.bicepparam index 447dcb2be..5b4a8010a 100644 --- a/.azure/applications/web-api-so/staging.bicepparam +++ b/.azure/applications/web-api-so/staging.bicepparam @@ -10,3 +10,4 @@ param environmentKeyVaultName = readEnvironmentVariable('ENVIRONMENT_KEY_VAULT_N param containerAppEnvironmentName = readEnvironmentVariable('CONTAINER_APP_ENVIRONMENT_NAME') param appInsightConnectionString = readEnvironmentVariable('APP_INSIGHTS_CONNECTION_STRING') param appConfigurationName = readEnvironmentVariable('APP_CONFIGURATION_NAME') +param redisName = readEnvironmentVariable('REDIS_NAME') diff --git a/.azure/applications/web-api-so/test.bicepparam b/.azure/applications/web-api-so/test.bicepparam index 9df5c026b..e40c26f7f 100644 --- a/.azure/applications/web-api-so/test.bicepparam +++ b/.azure/applications/web-api-so/test.bicepparam @@ -10,3 +10,4 @@ param environmentKeyVaultName = readEnvironmentVariable('ENVIRONMENT_KEY_VAULT_N param containerAppEnvironmentName = readEnvironmentVariable('CONTAINER_APP_ENVIRONMENT_NAME') param appInsightConnectionString = readEnvironmentVariable('APP_INSIGHTS_CONNECTION_STRING') param appConfigurationName = readEnvironmentVariable('APP_CONFIGURATION_NAME') +param redisName = readEnvironmentVariable('REDIS_NAME') diff --git a/.github/workflows/action-deploy-apps.yml b/.github/workflows/action-deploy-apps.yml index 0e2aedc70..2263ce31d 100644 --- a/.github/workflows/action-deploy-apps.yml +++ b/.github/workflows/action-deploy-apps.yml @@ -22,6 +22,8 @@ on: required: true AZURE_ADO_CONNECTION_STRING_SECRET_URI: required: true + AZURE_REDIS_NAME: + required: true inputs: region: @@ -147,6 +149,7 @@ jobs: APP_INSIGHTS_CONNECTION_STRING: ${{ secrets.AZURE_APP_INSIGHTS_CONNECTION_STRING }} APP_CONFIGURATION_NAME: ${{ secrets.AZURE_APP_CONFIGURATION_NAME }} ENVIRONMENT_KEY_VAULT_NAME: ${{ secrets.AZURE_ENVIRONMENT_KEY_VAULT_NAME }} + REDIS_NAME: ${{ secrets.AZURE_REDIS_NAME }} with: scope: resourcegroup template: ./.azure/applications/${{ matrix.name }}/main.bicep diff --git a/.github/workflows/ci-cd-main.yml b/.github/workflows/ci-cd-main.yml index 369290770..f9f4bebba 100644 --- a/.github/workflows/ci-cd-main.yml +++ b/.github/workflows/ci-cd-main.yml @@ -103,6 +103,7 @@ jobs: AZURE_CONTAINER_APP_ENVIRONMENT_NAME: ${{ secrets.AZURE_CONTAINER_APP_ENVIRONMENT_NAME }} AZURE_APP_INSIGHTS_CONNECTION_STRING: ${{ secrets.AZURE_APP_INSIGHTS_CONNECTION_STRING }} AZURE_APP_CONFIGURATION_NAME: ${{ secrets.AZURE_APP_CONFIGURATION_NAME }} + AZURE_REDIS_NAME: ${{ secrets.AZURE_REDIS_NAME }} with: environment: test region: norwayeast diff --git a/.github/workflows/ci-cd-staging.yml b/.github/workflows/ci-cd-staging.yml index 7c33213b3..82734ad46 100644 --- a/.github/workflows/ci-cd-staging.yml +++ b/.github/workflows/ci-cd-staging.yml @@ -64,6 +64,7 @@ jobs: AZURE_CONTAINER_APP_ENVIRONMENT_NAME: ${{ secrets.AZURE_CONTAINER_APP_ENVIRONMENT_NAME }} AZURE_APP_INSIGHTS_CONNECTION_STRING: ${{ secrets.AZURE_APP_INSIGHTS_CONNECTION_STRING }} AZURE_APP_CONFIGURATION_NAME: ${{ secrets.AZURE_APP_CONFIGURATION_NAME }} + AZURE_REDIS_NAME: ${{ secrets.AZURE_REDIS_NAME }} with: environment: staging region: norwayeast From 7ef3455cd9b7ed3f9dd41e32f944c4620eee32af Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 6 Mar 2024 09:50:25 +0100 Subject: [PATCH 11/11] cleanup --- .azure/infrastructure/main.bicep | 2 -- 1 file changed, 2 deletions(-) diff --git a/.azure/infrastructure/main.bicep b/.azure/infrastructure/main.bicep index 5b4472e0d..adcab5956 100644 --- a/.azure/infrastructure/main.bicep +++ b/.azure/infrastructure/main.bicep @@ -129,8 +129,6 @@ module redis '../modules/redis/main.bicep' = { } } - - module copyEnvironmentSecrets '../modules/keyvault/copySecrets.bicep' = { scope: resourceGroup name: 'copyEnvironmentSecrets'