From 6a3893748e9747b67a1e2348a5fc7e5e0c869543 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Tue, 10 Dec 2024 16:02:08 +0100 Subject: [PATCH 1/3] chore: use user assigned identity for all applications --- .azure/applications/graphql/main.bicep | 15 ++++++++-- .../main.bicep | 15 ++++++++-- .azure/applications/web-api-eu/main.bicep | 15 ++++++++-- .../web-api-migration-job/main.bicep | 15 ++++++++-- .azure/applications/web-api-so/main.bicep | 15 ++++++++-- .azure/modules/containerApp/main.bicep | 28 ++++++++----------- .azure/modules/containerAppJob/main.bicep | 15 ++++++++-- 7 files changed, 90 insertions(+), 28 deletions(-) diff --git a/.azure/applications/graphql/main.bicep b/.azure/applications/graphql/main.bicep index 2d63bebe9..f655664ac 100644 --- a/.azure/applications/graphql/main.bicep +++ b/.azure/applications/graphql/main.bicep @@ -61,6 +61,12 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' name: containerAppEnvironmentName } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-graphql-identity' + location: location + tags: tags +} + var containerAppEnvVars = [ { name: 'ASPNETCORE_ENVIRONMENT' @@ -74,6 +80,10 @@ var containerAppEnvVars = [ name: 'AZURE_APPCONFIG_URI' value: appConfiguration.properties.endpoint } + { + name: 'AZURE_CLIENT_ID' + value: managedIdentity.properties.clientId + } ] var port = 8080 @@ -157,6 +167,7 @@ module containerApp '../../modules/containerApp/main.bicep' = { probes: probes port: port scale: scale + userAssignedIdentityId: managedIdentity.id } } @@ -164,7 +175,7 @@ module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { keyvaultName: environmentKeyVaultResource.name - principalIds: [containerApp.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } @@ -172,7 +183,7 @@ module appConfigReaderAccessPolicy '../../modules/appConfiguration/addReaderRole name: 'appConfigReaderAccessPolicy-${containerAppName}' params: { appConfigurationName: appConfigurationName - principalIds: [containerApp.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } diff --git a/.azure/applications/sync-subject-resource-mappings-job/main.bicep b/.azure/applications/sync-subject-resource-mappings-job/main.bicep index a2d6203f5..3279e4d7e 100644 --- a/.azure/applications/sync-subject-resource-mappings-job/main.bicep +++ b/.azure/applications/sync-subject-resource-mappings-job/main.bicep @@ -46,6 +46,12 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' name: containerAppEnvironmentName } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-sync-sr-mappings-identity' + location: location + tags: tags +} + var containerAppEnvVars = [ { name: 'Infrastructure__DialogDbConnectionString' @@ -63,6 +69,10 @@ var containerAppEnvVars = [ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' value: appInsightConnectionString } + { + name: 'AZURE_CLIENT_ID' + value: managedIdentity.properties.clientId + } ] // Base URL for accessing secrets in the Key Vault @@ -94,6 +104,7 @@ module migrationJob '../../modules/containerAppJob/main.bicep' = { tags: tags cronExpression: jobSchedule args: 'sync-subject-resource-mappings' + userAssignedIdentityId: managedIdentity.id } } @@ -101,9 +112,9 @@ module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' name: 'keyVaultReaderAccessPolicy-${name}' params: { keyvaultName: environmentKeyVaultName - principalIds: [migrationJob.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } -output identityPrincipalId string = migrationJob.outputs.identityPrincipalId +output identityPrincipalId string = managedIdentity.properties.principalId output name string = migrationJob.outputs.name diff --git a/.azure/applications/web-api-eu/main.bicep b/.azure/applications/web-api-eu/main.bicep index 9f032afbf..b4cbd6592 100644 --- a/.azure/applications/web-api-eu/main.bicep +++ b/.azure/applications/web-api-eu/main.bicep @@ -60,6 +60,12 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' name: containerAppEnvironmentName } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-webapi-eu-identity' + location: location + tags: tags +} + var containerAppEnvVars = [ { name: 'ASPNETCORE_ENVIRONMENT' @@ -77,6 +83,10 @@ var containerAppEnvVars = [ name: 'ASPNETCORE_URLS' value: 'http://+:8080' } + { + name: 'AZURE_CLIENT_ID' + value: managedIdentity.properties.clientId + } ] @description('The scaling configuration for the container app') @@ -159,6 +169,7 @@ module containerApp '../../modules/containerApp/main.bicep' = { probes: probes revisionSuffix: revisionSuffix scale: scale + userAssignedIdentityId: managedIdentity.id } } @@ -166,7 +177,7 @@ module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { keyvaultName: environmentKeyVaultResource.name - principalIds: [containerApp.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } @@ -174,7 +185,7 @@ module appConfigReaderAccessPolicy '../../modules/appConfiguration/addReaderRole name: 'appConfigReaderAccessPolicy-${containerAppName}' params: { appConfigurationName: appConfigurationName - principalIds: [containerApp.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } diff --git a/.azure/applications/web-api-migration-job/main.bicep b/.azure/applications/web-api-migration-job/main.bicep index 5df04957b..ca5857455 100644 --- a/.azure/applications/web-api-migration-job/main.bicep +++ b/.azure/applications/web-api-migration-job/main.bicep @@ -34,11 +34,21 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' name: containerAppEnvironmentName } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-migration-job-identity' + location: location + tags: tags +} + var containerAppEnvVars = [ { name: 'Infrastructure__DialogDbConnectionString' secretRef: 'dbconnectionstring' } + { + name: 'AZURE_CLIENT_ID' + value: managedIdentity.properties.clientId + } ] // https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-deployment#example-1 @@ -62,6 +72,7 @@ module migrationJob '../../modules/containerAppJob/main.bicep' = { environmentVariables: containerAppEnvVars secrets: secrets tags: tags + userAssignedIdentityId: managedIdentity.id } } @@ -69,9 +80,9 @@ module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' name: 'keyVaultReaderAccessPolicy-${name}' params: { keyvaultName: environmentKeyVaultName - principalIds: [migrationJob.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } -output identityPrincipalId string = migrationJob.outputs.identityPrincipalId +output identityPrincipalId string = managedIdentity.properties.principalId output name string = migrationJob.outputs.name diff --git a/.azure/applications/web-api-so/main.bicep b/.azure/applications/web-api-so/main.bicep index d9085b77d..eb1feccc0 100644 --- a/.azure/applications/web-api-so/main.bicep +++ b/.azure/applications/web-api-so/main.bicep @@ -88,6 +88,12 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' name: containerAppEnvironmentName } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-webapi-so-identity' + location: location + tags: tags +} + var containerAppEnvVars = [ { name: 'ASPNETCORE_ENVIRONMENT' @@ -105,6 +111,10 @@ var containerAppEnvVars = [ name: 'ASPNETCORE_URLS' value: 'http://+:8080' } + { + name: 'AZURE_CLIENT_ID' + value: managedIdentity.properties.clientId + } ] resource environmentKeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' existing = { @@ -160,6 +170,7 @@ module containerApp '../../modules/containerApp/main.bicep' = { port: port revisionSuffix: revisionSuffix scale: scale + userAssignedIdentityId: managedIdentity.id } } @@ -167,7 +178,7 @@ module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { keyvaultName: environmentKeyVaultResource.name - principalIds: [containerApp.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } @@ -175,7 +186,7 @@ module appConfigReaderAccessPolicy '../../modules/appConfiguration/addReaderRole name: 'appConfigReaderAccessPolicy-${containerAppName}' params: { appConfigurationName: appConfigurationName - principalIds: [containerApp.outputs.identityPrincipalId] + principalIds: [managedIdentity.properties.principalId] } } diff --git a/.azure/modules/containerApp/main.bicep b/.azure/modules/containerApp/main.bicep index 9259e047e..c2f3c6979 100644 --- a/.azure/modules/containerApp/main.bicep +++ b/.azure/modules/containerApp/main.bicep @@ -58,9 +58,9 @@ param scale Scale = { rules: [] } -// TODO: Refactor to make userAssignedIdentityId a required parameter once all container apps use user-assigned identities -@description('The ID of the user-assigned managed identity (optional)') -param userAssignedIdentityId string = '' +@description('The ID of the user-assigned managed identity') +@minLength(1) +param userAssignedIdentityId string // Container app revision name does not allow '.' character var cleanedRevisionSuffix = replace(revisionSuffix, '.', '-') @@ -81,19 +81,19 @@ var ingress = { ipSecurityRestrictions: ipSecurityRestrictions } -var identityConfig = empty(userAssignedIdentityId) ? { - type: 'SystemAssigned' -} : { - type: 'UserAssigned' - userAssignedIdentities: { - '${userAssignedIdentityId}': {} - } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = { + name: last(split(userAssignedIdentityId, '/')) } resource containerApp 'Microsoft.App/containerApps@2024-03-01' = { name: name location: location - identity: identityConfig + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${userAssignedIdentityId}': {} + } + } properties: { configuration: { ingress: ingress @@ -116,10 +116,6 @@ resource containerApp 'Microsoft.App/containerApps@2024-03-01' = { tags: tags } -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(userAssignedIdentityId)) { - name: last(split(userAssignedIdentityId, '/')) -} - -output identityPrincipalId string = empty(userAssignedIdentityId) ? containerApp.identity.principalId : managedIdentity.properties.principalId +output identityPrincipalId string = managedIdentity.properties.principalId output name string = containerApp.name output revisionName string = containerApp.properties.latestRevisionName diff --git a/.azure/modules/containerAppJob/main.bicep b/.azure/modules/containerAppJob/main.bicep index 8a1628018..836bbd250 100644 --- a/.azure/modules/containerAppJob/main.bicep +++ b/.azure/modules/containerAppJob/main.bicep @@ -25,6 +25,10 @@ param cronExpression string = '' @description('The container args for the job (optional)') param args string = '' +@description('The ID of the user-assigned managed identity') +@minLength(1) +param userAssignedIdentityId string + var isScheduled = !empty(cronExpression) var scheduledJobProperties = { @@ -42,11 +46,18 @@ var manualJobProperties = { } } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = { + name: last(split(userAssignedIdentityId, '/')) +} + resource job 'Microsoft.App/jobs@2024-03-01' = { name: name location: location identity: { - type: 'SystemAssigned' + type: 'UserAssigned' + userAssignedIdentities: { + '${userAssignedIdentityId}': {} + } } properties: { configuration: union( @@ -72,5 +83,5 @@ resource job 'Microsoft.App/jobs@2024-03-01' = { tags: tags } -output identityPrincipalId string = job.identity.principalId +output identityPrincipalId string = managedIdentity.properties.principalId output name string = job.name From f3588553f0e3f8faa37d3ea33b9cb5c3c31983da Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Fri, 20 Dec 2024 13:42:59 +0100 Subject: [PATCH 2/3] fix: it all --- .../sync-resource-policy-information-job/main.bicep | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.azure/applications/sync-resource-policy-information-job/main.bicep b/.azure/applications/sync-resource-policy-information-job/main.bicep index 3c1b5f479..ee6e75df2 100644 --- a/.azure/applications/sync-resource-policy-information-job/main.bicep +++ b/.azure/applications/sync-resource-policy-information-job/main.bicep @@ -46,6 +46,12 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' name: containerAppEnvironmentName } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-sync-rp-info-identity' + location: location + tags: tags +} + var containerAppEnvVars = [ { name: 'Infrastructure__DialogDbConnectionString' @@ -94,6 +100,7 @@ module migrationJob '../../modules/containerAppJob/main.bicep' = { tags: tags cronExpression: jobSchedule args: 'sync-resource-policy-information' + userAssignedIdentityId: managedIdentity.id } } From 506ad435ded4f2287b12ef5cdc3e48d240e0f5f4 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Fri, 20 Dec 2024 13:52:31 +0100 Subject: [PATCH 3/3] fix: it all --- .../sync-resource-policy-information-job/main.bicep | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.azure/applications/sync-resource-policy-information-job/main.bicep b/.azure/applications/sync-resource-policy-information-job/main.bicep index ee6e75df2..740691b41 100644 --- a/.azure/applications/sync-resource-policy-information-job/main.bicep +++ b/.azure/applications/sync-resource-policy-information-job/main.bicep @@ -69,6 +69,10 @@ var containerAppEnvVars = [ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' value: appInsightConnectionString } + { + name: 'AZURE_CLIENT_ID' + value: managedIdentity.properties.clientId + } ] // Base URL for accessing secrets in the Key Vault