From 1834045002578bef6c616fb8187f4ee62bc8458e Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 31 Jul 2024 00:00:27 +0200 Subject: [PATCH] chore(azure): add tags and param-descriptions on all resources (#942) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description - Adds tags on all resources with Environment. Might look into adding more tags like version etc eventually. - Adds @description for all params in modules ## Related Issue(s) - #{issue number} ## Verification - [ ] **Your** code builds clean without any errors or warnings - [ ] Manual testing done (required) - [ ] Relevant automated test added (if you find this hard, leave it and we'll help out) ## Documentation - [ ] Documentation is updated (either in `docs`-directory, Altinnpedia or a separate linked PR in [altinn-studio-docs.](https://github.com/Altinn/altinn-studio-docs), if applicable) --------- Co-authored-by: Ole Jørgen Skogstad --- .azure/applications/graphql/main.bicep | 14 +++++ .azure/applications/web-api-eu/main.bicep | 18 +++++- .../web-api-migration-job/main.bicep | 8 +++ .azure/applications/web-api-so/main.bicep | 18 +++++- .azure/functions/resourceName.bicep | 5 +- .azure/infrastructure/main.bicep | 32 ++++++++++- .azure/modules/appConfiguration/create.bicep | 9 +++ .../applicationInsights/addReaderRoles.bicep | 21 ++++--- .../modules/applicationInsights/create.bicep | 55 +++++++++++++------ .azure/modules/containerApp/main.bicep | 12 ++++ .azure/modules/containerAppEnv/main.bicep | 10 ++++ .azure/modules/containerAppJob/main.bicep | 11 ++++ .azure/modules/functionApp/appSettings.bicep | 13 +++-- .../modules/functionApp/slackNotifier.bicep | 16 ++++++ .azure/modules/keyvault/addReaderRoles.bicep | 3 + .azure/modules/keyvault/copySecrets.bicep | 35 +++++++++--- .azure/modules/keyvault/create.bicep | 9 +++ .azure/modules/keyvault/upsertSecret.bicep | 4 +- .azure/modules/postgreSql/create.bicep | 30 +++++++++- .azure/modules/privateDnsZone/main.bicep | 5 ++ .azure/modules/redis/main.bicep | 20 +++++++ .azure/modules/serviceBus/main.bicep | 15 +++++ .azure/modules/vnet/main.bicep | 9 +++ 23 files changed, 322 insertions(+), 50 deletions(-) diff --git a/.azure/applications/graphql/main.bicep b/.azure/applications/graphql/main.bicep index b3e51ced2..93ff1f267 100644 --- a/.azure/applications/graphql/main.bicep +++ b/.azure/applications/graphql/main.bicep @@ -1,23 +1,37 @@ targetScope = 'resourceGroup' +@description('The tag of the image to be used') @minLength(3) param imageTag string + +@description('The environment for the deployment') @minLength(3) param environment string + +@description('The location where the resources will be deployed') @minLength(3) param location string + +@description('The IP address of the API Management instance') @minLength(3) param apimIp string +@description('The name of the container app environment') @minLength(3) @secure() param containerAppEnvironmentName string + +@description('The connection string for Application Insights') @minLength(3) @secure() param appInsightConnectionString string + +@description('The name of the App Configuration store') @minLength(5) @secure() param appConfigurationName string + +@description('The name of the Key Vault for the environment') @minLength(3) @secure() param environmentKeyVaultName string diff --git a/.azure/applications/web-api-eu/main.bicep b/.azure/applications/web-api-eu/main.bicep index b7e00070c..ea202ae85 100644 --- a/.azure/applications/web-api-eu/main.bicep +++ b/.azure/applications/web-api-eu/main.bicep @@ -1,23 +1,37 @@ targetScope = 'resourceGroup' +@description('The tag of the image to be used') @minLength(3) param imageTag string + +@description('The environment for the deployment') @minLength(3) param environment string + +@description('The location where the resources will be deployed') @minLength(3) param location string + +@description('The IP address of the API Management instance') @minLength(3) param apimIp string +@description('The name of the container app environment') @minLength(3) @secure() param containerAppEnvironmentName string + +@description('The connection string for Application Insights') @minLength(3) @secure() param appInsightConnectionString string + +@description('The name of the App Configuration store') @minLength(5) @secure() param appConfigurationName string + +@description('The name of the Key Vault for the environment') @minLength(3) @secure() param environmentKeyVaultName string @@ -74,7 +88,7 @@ module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { keyvaultName: environmentKeyVaultResource.name - principalIds: [ containerApp.outputs.identityPrincipalId ] + principalIds: [containerApp.outputs.identityPrincipalId] } } @@ -82,7 +96,7 @@ module appConfigReaderAccessPolicy '../../modules/appConfiguration/addReaderRole name: 'appConfigReaderAccessPolicy-${containerAppName}' params: { appConfigurationName: appConfigurationName - principalIds: [ containerApp.outputs.identityPrincipalId ] + principalIds: [containerApp.outputs.identityPrincipalId] } } diff --git a/.azure/applications/web-api-migration-job/main.bicep b/.azure/applications/web-api-migration-job/main.bicep index 9bdbbfdea..2a10bf9c6 100644 --- a/.azure/applications/web-api-migration-job/main.bicep +++ b/.azure/applications/web-api-migration-job/main.bicep @@ -1,15 +1,23 @@ targetScope = 'resourceGroup' +@description('The tag of the image to be used') @minLength(3) param imageTag string + +@description('The environment for the deployment') @minLength(3) param environment string + +@description('The location where the resources will be deployed') @minLength(3) param location string +@description('The name of the container app environment') @minLength(3) @secure() param containerAppEnvironmentName string + +@description('The name of the Key Vault for the environment') @minLength(3) @secure() param environmentKeyVaultName string diff --git a/.azure/applications/web-api-so/main.bicep b/.azure/applications/web-api-so/main.bicep index 7378dc819..683780c7e 100644 --- a/.azure/applications/web-api-so/main.bicep +++ b/.azure/applications/web-api-so/main.bicep @@ -1,23 +1,37 @@ targetScope = 'resourceGroup' +@description('The tag of the image to be used') @minLength(3) param imageTag string + +@description('The environment for the deployment') @minLength(3) param environment string + +@description('The location where the resources will be deployed') @minLength(3) param location string + +@description('The IP address of the API Management instance') @minLength(3) param apimIp string +@description('The name of the container app environment') @minLength(3) @secure() param containerAppEnvironmentName string + +@description('The connection string for Application Insights') @minLength(3) @secure() param appInsightConnectionString string + +@description('The name of the App Configuration store') @minLength(5) @secure() param appConfigurationName string + +@description('The name of the Key Vault for the environment') @minLength(3) @secure() param environmentKeyVaultName string @@ -78,7 +92,7 @@ module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { keyvaultName: environmentKeyVaultResource.name - principalIds: [ containerApp.outputs.identityPrincipalId ] + principalIds: [containerApp.outputs.identityPrincipalId] } } @@ -86,7 +100,7 @@ module appConfigReaderAccessPolicy '../../modules/appConfiguration/addReaderRole name: 'appConfigReaderAccessPolicy-${containerAppName}' params: { appConfigurationName: appConfigurationName - principalIds: [ containerApp.outputs.identityPrincipalId ] + principalIds: [containerApp.outputs.identityPrincipalId] } } diff --git a/.azure/functions/resourceName.bicep b/.azure/functions/resourceName.bicep index b68d18849..59009019c 100644 --- a/.azure/functions/resourceName.bicep +++ b/.azure/functions/resourceName.bicep @@ -1,9 +1,8 @@ -// This function generates a unique string based on the subscription ID and resource group ID +@description('This function generates a unique string based on the subscription ID and resource group ID') @export() func uniqueStringBySubscriptionAndResourceGroup() string => uniqueString('${subscription().id}${resourceGroup().id}') -// This function generates a unique resource name by appending a unique string to the given name, ensuring the total length does not exceed the specified limit. -// It also ensures that the name is always postfixed with the full length of the unique string, which is 13 characters plus a dash. +@description('This function generates a unique resource name by appending a unique string to the given name, ensuring the total length does not exceed the specified limit. It also ensures that the name is always postfixed with the full length of the unique string, which is 13 characters plus a dash.') // Example: // uniqueResourceName(name: 'my-resource', limit: 50) => 'my-resource-1234567890123' // Example: diff --git a/.azure/infrastructure/main.bicep b/.azure/infrastructure/main.bicep index 7fb6ff2e0..d0808eca0 100644 --- a/.azure/infrastructure/main.bicep +++ b/.azure/infrastructure/main.bicep @@ -1,20 +1,32 @@ targetScope = 'subscription' + +@description('The environment for the deployment') @minLength(3) param environment string + +@description('The location where the resources will be deployed') @minLength(3) param location string +@description('Array of all keys in the source Key Vault') param keyVaultSourceKeys array +@description('Password for PostgreSQL admin') @secure() @minLength(3) param dialogportenPgAdminPassword string + +@description('Subscription ID for the source Key Vault') @secure() @minLength(3) param sourceKeyVaultSubscriptionId string + +@description('Resource group for the source Key Vault') @secure() @minLength(3) param sourceKeyVaultResourceGroup string + +@description('Name of the source Key Vault') @secure() @minLength(3) param sourceKeyVaultName string @@ -51,10 +63,15 @@ var secrets = { var namePrefix = 'dp-be-${environment}' +var tags = { + Environment: environment +} + // Create resource groups resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-03-01' = { name: '${namePrefix}-rg' location: location + tags: tags } module environmentKeyVault '../modules/keyvault/create.bicep' = { @@ -64,6 +81,7 @@ module environmentKeyVault '../modules/keyvault/create.bicep' = { namePrefix: namePrefix location: location sku: keyVaultSku + tags: tags } } @@ -74,6 +92,7 @@ module appConfiguration '../modules/appConfiguration/create.bicep' = { namePrefix: namePrefix location: location sku: appConfigurationSku + tags: tags } } @@ -84,6 +103,7 @@ module appInsights '../modules/applicationInsights/create.bicep' = { namePrefix: namePrefix location: location sku: appInsightsSku + tags: tags } } @@ -96,6 +116,7 @@ module serviceBus '../modules/serviceBus/main.bicep' = { sku: serviceBusSku subnetId: vnet.outputs.serviceBusSubnetId vnetId: vnet.outputs.virtualNetworkId + tags: tags } } @@ -105,6 +126,7 @@ module vnet '../modules/vnet/main.bicep' = { params: { namePrefix: namePrefix location: location + tags: tags } } @@ -135,13 +157,14 @@ module postgresql '../modules/postgreSql/create.bicep' = { location: location environmentKeyVaultName: environmentKeyVault.outputs.name srcKeyVault: srcKeyVault - srcSecretName: 'dialogportenPgAdminPassword${environment}' + srcKeyVaultAdministratorLoginPasswordKey: 'dialogportenPgAdminPassword${environment}' administratorLoginPassword: contains(keyVaultSourceKeys, 'dialogportenPgAdminPassword${environment}') ? srcKeyVaultResource.getSecret('dialogportenPgAdminPassword${environment}') : secrets.dialogportenPgAdminPassword sku: postgresSku subnetId: vnet.outputs.postgresqlSubnetId vnetId: vnet.outputs.virtualNetworkId + tags: tags } } @@ -156,6 +179,7 @@ module redis '../modules/redis/main.bicep' = { version: redisVersion subnetId: vnet.outputs.redisSubnetId vnetId: vnet.outputs.virtualNetworkId + tags: tags } } @@ -170,6 +194,7 @@ module copyCrossEnvironmentSecrets '../modules/keyvault/copySecrets.bicep' = { srcKeyVaultSubId: secrets.sourceKeyVaultSubscriptionId destKeyVaultName: environmentKeyVault.outputs.name secretPrefix: 'dialogporten--any--' + tags: tags } } @@ -184,6 +209,7 @@ module copyEnvironmentSecrets '../modules/keyvault/copySecrets.bicep' = { srcKeyVaultSubId: secrets.sourceKeyVaultSubscriptionId destKeyVaultName: environmentKeyVault.outputs.name secretPrefix: 'dialogporten--${environment}--' + tags: tags } } @@ -196,6 +222,7 @@ module slackNotifier '../modules/functionApp/slackNotifier.bicep' = { namePrefix: namePrefix applicationInsightsName: appInsights.outputs.appInsightsName sku: slackNotifierSku + tags: tags } } @@ -207,6 +234,7 @@ module containerAppEnv '../modules/containerAppEnv/main.bicep' = { location: location appInsightWorkspaceName: appInsights.outputs.appInsightsWorkspaceName subnetId: vnet.outputs.containerAppEnvironmentSubnetId + tags: tags } } @@ -227,6 +255,7 @@ module postgresConnectionStringAppConfig '../modules/appConfiguration/upsertKeyV key: 'Infrastructure:DialogDbConnectionString' value: postgresql.outputs.adoConnectionStringSecretUri keyValueType: 'keyVaultReference' + tags: tags } } @@ -238,6 +267,7 @@ module redisConnectionStringAppConfig '../modules/appConfiguration/upsertKeyValu key: 'Infrastructure:Redis:ConnectionString' value: redis.outputs.connectionStringSecretUri keyValueType: 'keyVaultReference' + tags: tags } } diff --git a/.azure/modules/appConfiguration/create.bicep b/.azure/modules/appConfiguration/create.bicep index 1402450b8..9c2d782c8 100644 --- a/.azure/modules/appConfiguration/create.bicep +++ b/.azure/modules/appConfiguration/create.bicep @@ -1,12 +1,20 @@ import { uniqueResourceName } from '../../functions/resourceName.bicep' +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The location where the resources will be deployed') param location string +@description('Tags to apply to resources') +param tags object + @export() type Sku = { name: 'standard' } + +@description('The SKU of the App Configuration') param sku Sku var appConfigNameMaxLength = 63 @@ -26,6 +34,7 @@ resource appConfig 'Microsoft.AppConfiguration/configurationStores@2023-03-01' = value: '1' } } + tags: tags } output endpoint string = appConfig.properties.endpoint diff --git a/.azure/modules/applicationInsights/addReaderRoles.bicep b/.azure/modules/applicationInsights/addReaderRoles.bicep index 865e3dbe6..6c40ca1d5 100644 --- a/.azure/modules/applicationInsights/addReaderRoles.bicep +++ b/.azure/modules/applicationInsights/addReaderRoles.bicep @@ -1,22 +1,27 @@ +@description('The name of the Application Insights resource') param appInsightsName string + +@description('Array of principal IDs to assign the Reader role to') param principalIds array resource appInsights 'Microsoft.Insights/components@2020-02-02' existing = { - name: appInsightsName + name: appInsightsName } @description('This is the built-in Reader role. See https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#reader') resource readerRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - scope: subscription() - name: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + scope: subscription() + name: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' } -resource roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { +resource roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for principalId in principalIds: { scope: appInsights name: guid(subscription().id, principalId, readerRole.id) properties: { - roleDefinitionId: readerRole.id - principalId: principalId - principalType: 'ServicePrincipal' + roleDefinitionId: readerRole.id + principalId: principalId + principalType: 'ServicePrincipal' } -}] + } +] diff --git a/.azure/modules/applicationInsights/create.bicep b/.azure/modules/applicationInsights/create.bicep index a92c4c0dc..dcac7fb1c 100644 --- a/.azure/modules/applicationInsights/create.bicep +++ b/.azure/modules/applicationInsights/create.bicep @@ -1,34 +1,53 @@ +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The location where the resources will be deployed') param location string +@description('Tags to apply to resources') +param tags object + @export() type Sku = { - name: 'PerGB2018' | 'CapacityReservation' | 'Free' | 'LACluster' | 'PerGB2018' | 'PerNode' | 'Premium' | 'Standalone' | 'Standard' + name: + | 'PerGB2018' + | 'CapacityReservation' + | 'Free' + | 'LACluster' + | 'PerGB2018' + | 'PerNode' + | 'Premium' + | 'Standalone' + | 'Standard' } + +@description('The SKU of the Application Insights') param sku Sku resource appInsightsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = { - name: '${namePrefix}-insightsWorkspace' - location: location - properties: { - retentionInDays: 30 - sku: sku - workspaceCapping: { - dailyQuotaGb: -1 - } + name: '${namePrefix}-insightsWorkspace' + location: location + properties: { + retentionInDays: 30 + sku: sku + workspaceCapping: { + dailyQuotaGb: -1 } + } + tags: tags } resource appInsights 'Microsoft.Insights/components@2020-02-02' = { - name: '${namePrefix}-applicationInsights' - location: location - kind: 'web' - properties: { - Application_Type: 'web' - WorkspaceResourceId: appInsightsWorkspace.id - Flow_Type: 'Bluefield' - Request_Source: 'rest' - } + name: '${namePrefix}-applicationInsights' + location: location + kind: 'web' + properties: { + Application_Type: 'web' + WorkspaceResourceId: appInsightsWorkspace.id + Flow_Type: 'Bluefield' + Request_Source: 'rest' + } + tags: tags } output connectionString string = appInsights.properties.ConnectionString diff --git a/.azure/modules/containerApp/main.bicep b/.azure/modules/containerApp/main.bicep index 6d9198dc2..74bb5891f 100644 --- a/.azure/modules/containerApp/main.bicep +++ b/.azure/modules/containerApp/main.bicep @@ -1,10 +1,22 @@ +@description('The location where the resources will be deployed') param location string + +@description('The environment variables for the container app') param envVariables array = [] + +@description('The port on which the container app will run') param port int = 8080 + +@description('The name of the container app') param name string + +@description('The image to be used for the container app') param image string + +@description('The IP address of the API Management instance') param apimIp string? +@description('The ID of the container app environment') param containerAppEnvId string var probes = [ diff --git a/.azure/modules/containerAppEnv/main.bicep b/.azure/modules/containerAppEnv/main.bicep index ad5667f9a..2d038de5b 100644 --- a/.azure/modules/containerAppEnv/main.bicep +++ b/.azure/modules/containerAppEnv/main.bicep @@ -1,7 +1,16 @@ +@description('The location where the resources will be deployed') param location string + +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The ID of the subnet to be used for the container app environment') param subnetId string +@description('Tags to apply to resources') +param tags object + +@description('The name of the Application Insights workspace') param appInsightWorkspaceName string resource appInsightsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = { @@ -24,6 +33,7 @@ resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-03-01' = { internal: false } } + tags: tags } output containerAppEnvId string = containerAppEnv.id diff --git a/.azure/modules/containerAppJob/main.bicep b/.azure/modules/containerAppJob/main.bicep index 66f56abcc..bc9dca801 100644 --- a/.azure/modules/containerAppJob/main.bicep +++ b/.azure/modules/containerAppJob/main.bicep @@ -1,8 +1,19 @@ +@description('The location where the resources will be deployed') param location string + +@description('The name of the job') param name string + +@description('The image to be used for the job') param image string + +@description('The ID of the container app environment') param containerAppEnvId string + +@description('The environment variables for the job') param environmentVariables { name: string, value: string?, secretRef: string? }[] = [] + +@description('The secrets to be used in the job') param secrets { name: string, keyVaultUrl: string, identity: 'System' }[] = [] resource job 'Microsoft.App/jobs@2024-03-01' = { diff --git a/.azure/modules/functionApp/appSettings.bicep b/.azure/modules/functionApp/appSettings.bicep index 98a3ee75f..eeca797f2 100644 --- a/.azure/modules/functionApp/appSettings.bicep +++ b/.azure/modules/functionApp/appSettings.bicep @@ -1,13 +1,18 @@ +@description('The name of the web application') param webAppName string + +@description('The new app settings to be applied') param appSettings object + +@description('The current app settings of the web application') param currentAppSettings object resource webApp 'Microsoft.Web/sites@2023-12-01' existing = { - name: webAppName + name: webAppName } resource siteconfig 'Microsoft.Web/sites/config@2023-12-01' = { - parent: webApp - name: 'appsettings' - properties: union(currentAppSettings, appSettings) + parent: webApp + name: 'appsettings' + properties: union(currentAppSettings, appSettings) } diff --git a/.azure/modules/functionApp/slackNotifier.bicep b/.azure/modules/functionApp/slackNotifier.bicep index 59358b72a..738c9459a 100644 --- a/.azure/modules/functionApp/slackNotifier.bicep +++ b/.azure/modules/functionApp/slackNotifier.bicep @@ -1,10 +1,20 @@ import { uniqueStringBySubscriptionAndResourceGroup, uniqueResourceName } from '../../functions/resourceName.bicep' +@description('The location where the resources will be deployed') param location string + +@description('The name of the Application Insights resource') param applicationInsightsName string + +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The name of the Key Vault') param keyVaultName string +@description('Tags to apply to resources') +param tags object + @export() type Sku = { storageAccountName: @@ -43,6 +53,7 @@ type Sku = { | 'Y3v2Isolated' applicationServicePlanTier: 'Free' | 'Shared' | 'Basic' | 'Dynamic' | 'Standard' | 'Premium' | 'Isolated' } +@description('The SKU of the Slack Notifier') param sku Sku // Storage account names only supports lower case and numbers @@ -66,6 +77,7 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = { defaultToOAuthAuthentication: true minimumTlsVersion: 'TLS1_2' } + tags: tags } resource applicationServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = { @@ -76,6 +88,7 @@ resource applicationServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = { tier: sku.applicationServicePlanTier } properties: {} + tags: tags } resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = { @@ -99,6 +112,7 @@ resource functionApp 'Microsoft.Web/sites@2023-12-01' = { } httpsOnly: true } + tags: tags } var appSettings = { @@ -138,6 +152,7 @@ resource notifyDevTeam 'Microsoft.Insights/actionGroups@2023-01-01' = { } ] } + tags: tags } resource exceptionOccuredAlertRule 'Microsoft.Insights/scheduledQueryRules@2023-03-15-preview' = { @@ -173,6 +188,7 @@ resource exceptionOccuredAlertRule 'Microsoft.Insights/scheduledQueryRules@2023- ] } } + tags: tags } output functionAppPrincipalId string = functionApp.identity.principalId diff --git a/.azure/modules/keyvault/addReaderRoles.bicep b/.azure/modules/keyvault/addReaderRoles.bicep index 171ebc79d..b3d04a04f 100644 --- a/.azure/modules/keyvault/addReaderRoles.bicep +++ b/.azure/modules/keyvault/addReaderRoles.bicep @@ -1,4 +1,7 @@ +@description('The name of the Key Vault') param keyvaultName string + +@description('Array of principal IDs to assign the Key Vault Secrets User role to') param principalIds array resource keyvault 'Microsoft.KeyVault/vaults@2023-07-01' existing = { diff --git a/.azure/modules/keyvault/copySecrets.bicep b/.azure/modules/keyvault/copySecrets.bicep index c95028f7d..5b68f8f3a 100644 --- a/.azure/modules/keyvault/copySecrets.bicep +++ b/.azure/modules/keyvault/copySecrets.bicep @@ -1,31 +1,48 @@ +/* + This module copies secrets from a source Key Vault to a destination Key Vault and adds references to those secrets in App Configuration. +*/ // Source +@description('Array of keys from the source Key Vault') param srcKeyVaultKeys array + +@description('Name of the source Key Vault') param srcKeyVaultName string + +@description('Resource group name of the source Key Vault') param srcKeyVaultRGNName string = resourceGroup().name + +@description('Subscription ID of the source Key Vault') param srcKeyVaultSubId string = subscription().subscriptionId // Destination +@description('Name of the destination Key Vault') param destKeyVaultName string + +@description('Resource group name of the destination Key Vault') param destKeyVaultRGName string = resourceGroup().name + +@description('Subscription ID of the destination Key Vault') param destKeyVaultSubId string = subscription().subscriptionId // App configuration +@description('Name of the App Configuration to copy secret references to') param appConfigurationName string +@description('Tags to apply to resources') +param tags object + // Secret +@description('Prefix for the secret names') #disable-next-line secure-secrets-in-params param secretPrefix string var filteredKeysBySecretPrefix = filter(srcKeyVaultKeys, key => startsWith(key, secretPrefix)) -var keys = map( - filteredKeysBySecretPrefix, - key => { - secretNameWithoutPrefix: replace(key, secretPrefix, '') - secretName: key - appConfigKey: replace(replace(key, secretPrefix, ''), '--', ':') - } -) +var keys = map(filteredKeysBySecretPrefix, key => { + secretNameWithoutPrefix: replace(key, secretPrefix, '') + secretName: key + appConfigKey: replace(replace(key, secretPrefix, ''), '--', ':') +}) resource srcKeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' existing = { name: srcKeyVaultName @@ -44,6 +61,7 @@ module secrets 'upsertSecret.bicep' = [ destKeyVaultName: destKeyVaultName secretName: key.secretNameWithoutPrefix secretValue: srcKeyVaultResource.getSecret(key.secretName) + tags: tags } } ] @@ -57,6 +75,7 @@ module appConfiguration '../appConfiguration/upsertKeyValue.bicep' = [ key: key.appConfigKey value: 'https://${destKeyVaultName}${az.environment().suffixes.keyvaultDns}/secrets/${key.secretNameWithoutPrefix}' keyValueType: 'keyVaultReference' + tags: tags } } ] diff --git a/.azure/modules/keyvault/create.bicep b/.azure/modules/keyvault/create.bicep index 493d9c427..e0e42fc77 100644 --- a/.azure/modules/keyvault/create.bicep +++ b/.azure/modules/keyvault/create.bicep @@ -1,11 +1,19 @@ +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The location where the resources will be deployed') param location string +@description('Tags to apply to resources') +param tags object + @export() type Sku = { name: 'premium' | 'standard' family: 'A' } + +@description('The SKU of the Key Vault') param sku Sku var keyVaultName = take('${namePrefix}-kv-${uniqueString(resourceGroup().id)}', 24) @@ -21,6 +29,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = { accessPolicies: [] enableRbacAuthorization: true } + tags: tags } output name string = keyVault.name diff --git a/.azure/modules/keyvault/upsertSecret.bicep b/.azure/modules/keyvault/upsertSecret.bicep index 17729a751..468f1d8d6 100644 --- a/.azure/modules/keyvault/upsertSecret.bicep +++ b/.azure/modules/keyvault/upsertSecret.bicep @@ -1,5 +1,6 @@ param destKeyVaultName string param secretName string +param tags object @secure() param secretValue string @@ -8,6 +9,7 @@ resource secret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = { properties: { value: secretValue } + tags: tags } -output secretUri string = secret.properties.secretUri \ No newline at end of file +output secretUri string = secret.properties.secretUri diff --git a/.azure/modules/postgreSql/create.bicep b/.azure/modules/postgreSql/create.bicep index e9da6a852..dd8a85167 100644 --- a/.azure/modules/postgreSql/create.bicep +++ b/.azure/modules/postgreSql/create.bicep @@ -1,22 +1,41 @@ import { uniqueResourceName } from '../../functions/resourceName.bicep' +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The location where the resources will be deployed') param location string + +@description('The name of the environment Key Vault') param environmentKeyVaultName string -param srcSecretName string + +@description('The name of the secret name(key) in the source key vault to store the PostgreSQL administrator login password') +#disable-next-line secure-secrets-in-params +param srcKeyVaultAdministratorLoginPasswordKey string + +@description('The ID of the subnet where the PostgreSQL server will be deployed') param subnetId string + +@description('The ID of the virtual network for the private DNS zone') param vnetId string +@description('Tags to apply to resources') +param tags object + @export() type Sku = { name: 'Standard_B1ms' tier: 'Burstable' | 'GeneralPurpose' | 'MemoryOptimized' } + +@description('The SKU of the PostgreSQL server') param sku Sku +@description('The Key Vault to store the PostgreSQL administrator login password') @secure() param srcKeyVault object +@description('The password for the PostgreSQL administrator login') @secure() param administratorLoginPassword string @@ -39,12 +58,13 @@ var postgresServerName = uniqueResourceName('${namePrefix}-postgres', postgresSe //} module saveAdmPassword '../keyvault/upsertSecret.bicep' = { - name: 'Save_${srcSecretName}' + name: 'Save_${srcKeyVaultAdministratorLoginPasswordKey}' scope: resourceGroup(srcKeyVault.subscriptionId, srcKeyVault.resourceGroupName) params: { destKeyVaultName: srcKeyVault.name - secretName: srcSecretName + secretName: srcKeyVaultAdministratorLoginPasswordKey secretValue: administratorLoginPassword + tags: tags } } @@ -54,6 +74,7 @@ module privateDnsZone '../privateDnsZone/main.bicep' = { namePrefix: namePrefix defaultDomain: '${namePrefix}.postgres.database.azure.com' vnetId: vnetId + tags: tags } } @@ -82,6 +103,7 @@ resource postgres 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' = { collation: 'en_US.utf8' } } + tags: tags } module adoConnectionString '../keyvault/upsertSecret.bicep' = { @@ -90,6 +112,7 @@ module adoConnectionString '../keyvault/upsertSecret.bicep' = { 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;' + tags: tags } } @@ -99,6 +122,7 @@ module psqlConnectionString '../keyvault/upsertSecret.bicep' = { destKeyVaultName: environmentKeyVaultName secretName: 'dialogportenPsqlConnectionString' secretValue: 'psql \'host=${postgres.properties.fullyQualifiedDomainName} port=5432 dbname=${databaseName} user=${administratorLogin} password=${administratorLoginPassword} sslmode=require\'' + tags: tags } } diff --git a/.azure/modules/privateDnsZone/main.bicep b/.azure/modules/privateDnsZone/main.bicep index 148dfd3d7..42703190e 100644 --- a/.azure/modules/privateDnsZone/main.bicep +++ b/.azure/modules/privateDnsZone/main.bicep @@ -7,6 +7,9 @@ param defaultDomain string @description('The ID of the virtual network linked to the private DNS zone') param vnetId string +@description('Tags to apply to resources') +param tags object + type ARecord = { name: string ip: string @@ -19,6 +22,7 @@ resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { name: defaultDomain location: 'global' properties: {} + tags: tags } resource aRecordResources 'Microsoft.Network/privateDnsZones/A@2020-06-01' = [ @@ -46,6 +50,7 @@ resource virtualNetworkLink 'Microsoft.Network/privateDnsZones/virtualNetworkLin id: vnetId } } + tags: tags } output id string = privateDnsZone.id diff --git a/.azure/modules/redis/main.bicep b/.azure/modules/redis/main.bicep index e43851954..c293b75b7 100644 --- a/.azure/modules/redis/main.bicep +++ b/.azure/modules/redis/main.bicep @@ -2,12 +2,26 @@ import { uniqueResourceName } from '../../functions/resourceName.bicep' +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The location where the resources will be deployed') param location string + +@description('The ID of the subnet for the Private Link') param subnetId string + +@description('Tags to apply to resources') +param tags object + +@description('The ID of the virtual network for the private DNS zone') param vnetId string + +@description('The name of the environment Key Vault') @minLength(1) param environmentKeyVaultName string + +@description('The version of the Redis instance') @minLength(1) param version string @@ -18,6 +32,8 @@ type Sku = { @minValue(1) capacity: int } + +@description('The SKU of the Redis instance') param sku Sku var redisNameMaxLength = 63 @@ -40,6 +56,7 @@ resource redis 'Microsoft.Cache/Redis@2023-08-01' = { redisVersion: version publicNetworkAccess: 'Disabled' } + tags: tags } // private endpoint name max characters is 80 @@ -65,6 +82,7 @@ resource redisPrivateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = id: subnetId } } + tags: tags } module privateDnsZone '../privateDnsZone/main.bicep' = { @@ -73,6 +91,7 @@ module privateDnsZone '../privateDnsZone/main.bicep' = { namePrefix: namePrefix defaultDomain: 'privatelink.redis.cache.windows.net' vnetId: vnetId + tags: tags } } @@ -97,6 +116,7 @@ module redisConnectionString '../keyvault/upsertSecret.bicep' = { destKeyVaultName: environmentKeyVaultName secretName: 'dialogportenRedisConnectionString' secretValue: '${redis.properties.hostName}:${redis.properties.sslPort},password=${redis.properties.accessKeys.primaryKey},ssl=True,abortConnect=False' + tags: tags } } diff --git a/.azure/modules/serviceBus/main.bicep b/.azure/modules/serviceBus/main.bicep index 1c989f425..dca532ff6 100644 --- a/.azure/modules/serviceBus/main.bicep +++ b/.azure/modules/serviceBus/main.bicep @@ -3,11 +3,21 @@ // It also configures a private DNS zone for the Service Bus namespace to facilitate network resolution within the virtual network. import { uniqueResourceName } from '../../functions/resourceName.bicep' +@description('The prefix used for naming resources to ensure unique names') param namePrefix string + +@description('The location where the resources will be deployed') param location string + +@description('The ID of the subnet where the Service Bus will be deployed') param subnetId string + +@description('The ID of the virtual network for the private DNS zone') param vnetId string +@description('Tags to apply to resources') +param tags object + @export() type Sku = { name: 'Premium' @@ -15,6 +25,8 @@ type Sku = { @minValue(1) capacity: int } + +@description('The SKU of the Service Bus') param sku Sku var serviceBusNameMaxLength = 50 @@ -30,6 +42,7 @@ resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview properties: { publicNetworkAccess: 'Disabled' } + tags: tags } resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = { @@ -63,6 +76,7 @@ resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = { } ] } + tags: tags } var serviceBusDomainName = '${serviceBusName}.servicebus.windows.net' @@ -80,5 +94,6 @@ module privateDnsZone '../privateDnsZone/main.bicep' = { ip: privateEndpoint.properties.ipConfigurations[0].properties.privateIPAddress } ] + tags: tags } } diff --git a/.azure/modules/vnet/main.bicep b/.azure/modules/vnet/main.bicep index 7ff26daf5..55d5de720 100644 --- a/.azure/modules/vnet/main.bicep +++ b/.azure/modules/vnet/main.bicep @@ -4,6 +4,9 @@ param namePrefix string @description('The location where the resources will be deployed') param location string +@description('Tags to apply to resources') +param tags object + resource defaultNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { name: '${namePrefix}-default-nsg' location: location @@ -40,6 +43,7 @@ resource defaultNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { } ] } + tags: tags } // https://learn.microsoft.com/en-us/azure/container-apps/firewall-integration?tabs=consumption-only @@ -139,6 +143,7 @@ resource containerAppEnvironmentNSG 'Microsoft.Network/networkSecurityGroups@202 } ] } + tags: tags } resource postgresqlNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { @@ -177,6 +182,7 @@ resource postgresqlNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { } ] } + tags: tags } resource redisNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { @@ -215,6 +221,7 @@ resource redisNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { } ] } + tags: tags } resource serviceBusNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { @@ -253,6 +260,7 @@ resource serviceBusNSG 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { } ] } + tags: tags } resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-11-01' = { @@ -328,6 +336,7 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-11-01' = { } ] } + tags: tags } output virtualNetworkName string = virtualNetwork.name