Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use app identity for deployment of storage accounts #441

Merged
merged 11 commits into from
May 22, 2024
75 changes: 33 additions & 42 deletions .azure/applications/api/main.bicep
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
targetScope = 'resourceGroup'
targetScope = 'subscription'

@minLength(3)
param imageTag string
Expand All @@ -15,90 +15,81 @@ param maskinporten_environment string
param sourceKeyVaultName string
@secure()
param keyVaultUrl string

@secure()
param client_id string

@secure()
param tenant_id string
@secure()
param namePrefix string

var baseImageUrl = 'ghcr.io/altinn/altinn-broker'
var image = 'ghcr.io/altinn/altinn-broker:${imageTag}'
var containerAppName = '${namePrefix}-app'

resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${namePrefix}-app-identity'
var resourceGroupName = '${namePrefix}-rg'
resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: resourceGroupName
location: location
}

module appIdentity '../../modules/identity/create.bicep' = {
name: 'appIdentity'
scope: resourceGroup
params: {
namePrefix: namePrefix
location: location
}
}

module addContributorAccess '../../modules/identity/addContributorAccess.bicep' = {
name: 'appDeployToAzureAccess'
params: {
userAssignedIdentityPrincipalId: appIdentity.outputs.principalId
}
}

module keyVaultReaderAccessPolicyUserIdentity '../../modules/keyvault/addReaderRoles.bicep' = {
name: 'kvreader-${namePrefix}-app'
scope: resourceGroup
params: {
keyvaultName: sourceKeyVaultName
tenantId: userAssignedIdentity.properties.tenantId
principalIds: [userAssignedIdentity.properties.principalId]
tenantId: appIdentity.outputs.tenantId
principalIds: [appIdentity.outputs.principalId]
}
}

module databaseAccess '../../modules/postgreSql/AddAdministrationAccess.bicep' = {
name: 'databaseAccess'
scope: resourceGroup
dependsOn: [
keyVaultReaderAccessPolicyUserIdentity // Timing issue
]
params: {
tenantId: userAssignedIdentity.properties.tenantId
principalId: userAssignedIdentity.properties.principalId
appName: userAssignedIdentity.name
tenantId: appIdentity.outputs.tenantId
principalId: appIdentity.outputs.principalId
appName: appIdentity.name
namePrefix: namePrefix
}
}

resource keyvault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
name: sourceKeyVaultName
scope: resourceGroup
}

module containerApp '../../modules/containerApp/main.bicep' = {
name: containerAppName
scope: resourceGroup
dependsOn: [keyVaultReaderAccessPolicyUserIdentity, databaseAccess]
params: {
namePrefix: namePrefix
image: '${baseImageUrl}:${imageTag}'
image: image
location: location
environment: environment
client_id: client_id
tenant_id: tenant_id
subscription_id: subscription().subscriptionId
principal_id: userAssignedIdentity.id
principal_id: appIdentity.outputs.id
platform_base_url: platform_base_url
keyVaultUrl: keyVaultUrl
maskinporten_environment: maskinporten_environment
malwarescan_event_grid_topic_name: eventgrid_topic.name
userIdentityTenantId: userAssignedIdentity.properties.tenantId
userIdentityClientId: userAssignedIdentity.properties.clientId
userIdentityPrincipalId: userAssignedIdentity.properties.principalId
userIdentityClientId: appIdentity.outputs.clientId
containerAppEnvId: keyvault.getSecret('container-app-env-id')
}
}

resource eventgrid_topic 'Microsoft.EventGrid/topics@2022-06-15' = {
name: '${namePrefix}-malware-scan-event-topic'
location: location
}

resource eventgrid_event_subscription 'Microsoft.EventGrid/topics/eventSubscriptions@2022-06-15' = {
name: '${namePrefix}-malware-scan-event-subscription'
parent: eventgrid_topic
dependsOn: [containerApp]
properties: {
destination: {
endpointType: 'WebHook'
properties: {
endpointUrl: 'https://${containerApp.outputs.app.properties.configuration.ingress.fqdn}/broker/api/v1/webhooks/malwarescanresults'
}
}
}
}

output name string = containerApp.outputs.name
output revisionName string = containerApp.outputs.revisionName
4 changes: 1 addition & 3 deletions .azure/applications/api/params.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ using './main.bicep'
param namePrefix = readEnvironmentVariable('NAME_PREFIX')
param location = 'norwayeast'
param imageTag = readEnvironmentVariable('IMAGE_TAG')
param platform_base_url = 'https://platform.tt02.altinn.no/'
param platform_base_url = readEnvironmentVariable('PLATFORM_BASE_URL')
param maskinporten_environment = 'ver2'
param environment = readEnvironmentVariable('ENVIRONMENT')
// secrets
param sourceKeyVaultName = readEnvironmentVariable('KEY_VAULT_NAME')
param keyVaultUrl = readEnvironmentVariable('KEY_VAULT_URL')
param client_id = readEnvironmentVariable('CLIENT_ID')
param tenant_id = readEnvironmentVariable('TENANT_ID')
2 changes: 1 addition & 1 deletion .azure/applications/migration/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ resource containerAppEnv 'Microsoft.App/managedEnvironments@2023-11-02-preview'
name: containerAppEnvName
}

module containerAppJob '../../modules/containerAppJob/main.bicep' = {
module containerAppJob '../../modules/migrationJob/main.bicep' = {
name: containerAppJobName
dependsOn: [
addKeyvaultRead
Expand Down
17 changes: 0 additions & 17 deletions .azure/infrastructure/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ param sourceKeyVaultName string
@secure()
param tenantId string
@secure()
param azureClientId string
@secure()
param test_client_id string
@secure()
param deploySecret string
param environment string
@secure()
param namePrefix string
Expand All @@ -37,18 +33,6 @@ param postgresSku PostgresSku
var resourceGroupName = '${namePrefix}-rg'

var secrets = [
{
name: 'deploy-id'
value: azureClientId
}
{
name: 'deploy-secret'
value: deploySecret
}
{
name: 'deploy-tenant-id'
value: tenantId
}
{
name: 'maskinporten-client-id'
value: maskinportenClientId
Expand Down Expand Up @@ -78,7 +62,6 @@ module environmentKeyVault '../modules/keyvault/create.bicep' = {
sku: keyVaultSku
tenant_id: tenantId
environment: environment
azureClientId: azureClientId
test_client_id: test_client_id
}
}
Expand Down
2 changes: 0 additions & 2 deletions .azure/infrastructure/params.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ param environment = readEnvironmentVariable('ENVIRONMENT')
// secrets
param brokerPgAdminPassword = readEnvironmentVariable('BROKER_PG_ADMIN_PASSWORD')
param tenantId = readEnvironmentVariable('TENANT_ID')
param azureClientId = readEnvironmentVariable('CLIENT_ID')
param test_client_id = readEnvironmentVariable('TEST_CLIENT_ID')
param sourceKeyVaultName = readEnvironmentVariable('KEY_VAULT_NAME')
param migrationsStorageAccountName = readEnvironmentVariable('MIGRATION_STORAGE_ACCOUNT_NAME')
param deploySecret = readEnvironmentVariable('CLIENT_SECRET')
param maskinportenJwk = readEnvironmentVariable('MASKINPORTEN_JWK')
param maskinportenClientId = readEnvironmentVariable('MASKINPORTEN_CLIENT_ID')
param platformSubscriptionKey = readEnvironmentVariable('PLATFORM_SUBSCRIPTION_KEY')
Expand Down
39 changes: 20 additions & 19 deletions .azure/modules/containerApp/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,12 @@ param maskinporten_environment string
@secure()
param subscription_id string
@secure()
param client_id string
@secure()
param tenant_id string
@secure()
param principal_id string
@secure()
param keyVaultUrl string
@secure()
param malwarescan_event_grid_topic_name string
@secure()
param userIdentityTenantId string
@secure()
param userIdentityClientId string
@secure()
param userIdentityPrincipalId string
@secure()
param containerAppEnvId string

var probes = [
Expand All @@ -44,11 +34,8 @@ var containerAppEnvVars = [
{ name: 'AzureResourceManagerOptions__SubscriptionId', value: subscription_id }
{ name: 'AzureResourceManagerOptions__Location', value: 'norwayeast' }
{ name: 'AzureResourceManagerOptions__Environment', value: environment }
{ name: 'AzureResourceManagerOptions__ClientId', value: client_id }
{ name: 'AzureResourceManagerOptions__TenantId', value: tenant_id }
{ name: 'AzureResourceManagerOptions__ClientSecret', secretRef: 'deploy-client-secret' }
{ name: 'AzureResourceManagerOptions__ApplicationResourceGroupName', value: '${namePrefix}-rg' }
{ name: 'AzureResourceManagerOptions__MalwareScanEventGridTopicName', value: malwarescan_event_grid_topic_name }
{ name: 'AzureResourceManagerOptions__MalwareScanEventGridTopicName', value: eventgrid_topic.name }
{ name: 'AZURE_CLIENT_ID', value: userIdentityClientId }
{
name: 'AltinnOptions__OpenIdWellKnown'
Expand Down Expand Up @@ -81,11 +68,6 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
transport: 'Auto'
}
secrets: [
{
identity: principal_id
keyVaultUrl: '${keyVaultUrl}/secrets/deploy-secret'
name: 'deploy-client-secret'
}
{
identity: principal_id
keyVaultUrl: '${keyVaultUrl}/secrets/platform-subscription-key'
Expand Down Expand Up @@ -168,6 +150,25 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
}
}

resource eventgrid_topic 'Microsoft.EventGrid/topics@2022-06-15' = {
name: '${namePrefix}-malware-scan-event-topic'
location: location
}

resource eventgrid_event_subscription 'Microsoft.EventGrid/topics/eventSubscriptions@2022-06-15' = {
name: '${namePrefix}-malware-scan-event-subscription'
parent: eventgrid_topic
properties: {
destination: {
endpointType: 'WebHook'
properties: {
endpointUrl: 'https://${containerApp.properties.configuration.ingress.fqdn}/broker/api/v1/webhooks/malwarescanresults'
}
}
}
}

output name string = containerApp.name
output revisionName string = containerApp.properties.latestRevisionName
output app object = containerApp
output eventGridTopicName string = eventgrid_topic.name
13 changes: 13 additions & 0 deletions .azure/modules/identity/addContributorAccess.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
targetScope = 'subscription'

param userAssignedIdentityPrincipalId string

var roleDefinitionResourceId = 'b24988ac-6180-42a0-ab88-20f7382dd24c' // Contributor role
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, userAssignedIdentityPrincipalId, roleDefinitionResourceId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionResourceId)
principalId: userAssignedIdentityPrincipalId
principalType: 'ServicePrincipal'
}
}
13 changes: 13 additions & 0 deletions .azure/modules/identity/create.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@secure()
param namePrefix string
param location string


resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${namePrefix}-app-identity'
location: location
}
output id string = userAssignedIdentity.id
output clientId string = userAssignedIdentity.properties.clientId
output principalId string = userAssignedIdentity.properties.principalId
output tenantId string = userAssignedIdentity.properties.tenantId
32 changes: 1 addition & 31 deletions .azure/modules/keyvault/create.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ param environment string
param tenant_id string
@secure()
param test_client_id string
@secure()
param azureClientId string
@export()
type Sku = {
name: 'standard'
Expand All @@ -25,19 +23,6 @@ resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
tenantId: tenant_id
accessPolicies: environment == 'test'
? [
{
applicationId: null
tenantId: tenant_id
objectId: azureClientId
permissions: {
keys: []
secrets: [
'Get'
'List'
]
certificates: []
}
}
{
applicationId: null
tenantId: tenant_id
Expand All @@ -52,22 +37,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
certificates: []
}
}
]
: [
{
applicationId: null
tenantId: tenant_id
objectId: azureClientId
permissions: {
keys: []
secrets: [
'Get'
'List'
]
certificates: []
}
}
]
]: []
}
}

Expand Down
12 changes: 4 additions & 8 deletions .github/actions/release-version/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ inputs:
environment:
description: "Github environment to deploy from"
required: true
AZURE_CLIENT_ID:
description: "Client ID for the service principal"
required: true
AZURE_TENANT_ID:
description: "Tenant ID for the service principal"
required: true
AZURE_SUBSCRIPTION_ID:
description: "Subscription ID for the service principal"
required: true
Expand All @@ -24,6 +18,9 @@ inputs:
AZURE_NAME_PREFIX:
description: "Prefix for all resources"
required: true
PLATFORM_BASE_URL:
description: "Base url for Altinn platform"
required: true

runs:
using: "composite"
Expand Down Expand Up @@ -51,8 +48,7 @@ runs:
KEY_VAULT_NAME: ${{ inputs.AZURE_ENVIRONMENT_KEY_VAULT_NAME }}
KEY_VAULT_URL: https://${{ inputs.AZURE_ENVIRONMENT_KEY_VAULT_NAME }}.vault.azure.net
NAME_PREFIX: ${{ inputs.AZURE_NAME_PREFIX }}
CLIENT_ID: ${{ inputs.AZURE_CLIENT_ID }}
TENANT_ID: ${{ inputs.AZURE_TENANT_ID }}
PLATFORM_BASE_URL: ${{ inputs.PLATFORM_BASE_URL }}
with:
scope: subscription
subscriptionId: ${{ inputs.AZURE_SUBSCRIPTION_ID }}
Expand Down
Loading
Loading