From a309044bd40d9a56c453496aab9122b8f6c67adb Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 16 Oct 2024 12:24:32 +0200 Subject: [PATCH 01/15] feat(service): deploy application in container apps (#1303) ## Description - Added Service in all environments in container app. Using webapi for now until Service is ready - Added user assigned identity instead of using the created managed identity created by the container app to avoid potential race conditions. This should be required eventually for all container apps. Making it optional for now. ## Related Issue(s) - #1301 ## 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) ## Summary by CodeRabbit - **New Features** - Introduced a new infrastructure configuration for deploying a container application in Azure. - Added support for multiple environments (production, staging, test) with dynamic parameter management. - Enhanced identity management for the container app, allowing for user-assigned identities. - **Bug Fixes** - Improved health probe configurations for better application monitoring. - **Documentation** - Updated workflow to include deployment capabilities for the new service component. --- .azure/applications/service/main.bicep | 161 ++++++++++++++++++ .azure/applications/service/prod.bicepparam | 12 ++ .../applications/service/staging.bicepparam | 12 ++ .azure/applications/service/test.bicepparam | 12 ++ .azure/modules/containerApp/main.bicep | 23 ++- .github/workflows/workflow-deploy-apps.yml | 1 + 6 files changed, 217 insertions(+), 4 deletions(-) create mode 100644 .azure/applications/service/main.bicep create mode 100644 .azure/applications/service/prod.bicepparam create mode 100644 .azure/applications/service/staging.bicepparam create mode 100644 .azure/applications/service/test.bicepparam diff --git a/.azure/applications/service/main.bicep b/.azure/applications/service/main.bicep new file mode 100644 index 000000000..d037ce8fe --- /dev/null +++ b/.azure/applications/service/main.bicep @@ -0,0 +1,161 @@ +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 suffix for the revision of the container app') +@minLength(3) +param revisionSuffix string + +@description('CPU and memory resources for the container app') +param resources object? + +@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) +param appConfigurationName string + +@description('The name of the Key Vault for the environment') +@minLength(3) +param environmentKeyVaultName string + +var namePrefix = 'dp-be-${environment}' +var baseImageUrl = 'ghcr.io/digdir/dialogporten-' +var tags = { + Environment: environment + Product: 'Dialogporten' +} + +resource appConfiguration 'Microsoft.AppConfiguration/configurationStores@2023-03-01' existing = { + name: appConfigurationName +} + +resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' existing = { + name: containerAppEnvironmentName +} + +var containerAppEnvVars = [ + { + name: 'ASPNETCORE_ENVIRONMENT' + value: environment + } + { + name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' + value: appInsightConnectionString + } + { + name: 'AZURE_APPCONFIG_URI' + value: appConfiguration.properties.endpoint + } + { + name: 'ASPNETCORE_URLS' + value: 'http://+:8080' + } +] + +resource environmentKeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' existing = { + name: environmentKeyVaultName +} + +var serviceName = 'service' + +var containerAppName = '${namePrefix}-${serviceName}' + +var port = 8080 + +var probes = [ + { + periodSeconds: 5 + initialDelaySeconds: 2 + type: 'Liveness' + httpGet: { + path: '/health/liveness' + port: port + } + } + { + periodSeconds: 5 + initialDelaySeconds: 2 + type: 'Readiness' + httpGet: { + path: '/health/readiness' + port: port + } + } + { + periodSeconds: 5 + initialDelaySeconds: 2 + type: 'Startup' + httpGet: { + path: '/health/startup' + port: port + } + } +] + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-service-identity' + location: location + tags: tags +} + +module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' = { + name: 'keyVaultReaderAccessPolicy-${containerAppName}' + params: { + keyvaultName: environmentKeyVaultResource.name + principalIds: [managedIdentity.properties.principalId] + } +} + +module appConfigReaderAccessPolicy '../../modules/appConfiguration/addReaderRoles.bicep' = { + name: 'appConfigReaderAccessPolicy-${containerAppName}' + params: { + appConfigurationName: appConfigurationName + principalIds: [managedIdentity.properties.principalId] + } +} + +module containerApp '../../modules/containerApp/main.bicep' = { + name: containerAppName + params: { + name: containerAppName + // todo: make this dynamic based on service name. Using webapi for now. + // image: '${baseImageUrl}${serviceName}:${imageTag}' + image: '${baseImageUrl}webapi:${imageTag}' + location: location + envVariables: containerAppEnvVars + containerAppEnvId: containerAppEnvironment.id + tags: tags + resources: resources + probes: probes + port: port + revisionSuffix: revisionSuffix + userAssignedIdentityId: managedIdentity.id + // TODO: Once all container apps use user-assigned identities, remove this comment and ensure userAssignedIdentityId is always provided + } + dependsOn: [ + keyVaultReaderAccessPolicy + appConfigReaderAccessPolicy + ] +} + +output name string = containerApp.outputs.name +output revisionName string = containerApp.outputs.revisionName diff --git a/.azure/applications/service/prod.bicepparam b/.azure/applications/service/prod.bicepparam new file mode 100644 index 000000000..7abc5dfbb --- /dev/null +++ b/.azure/applications/service/prod.bicepparam @@ -0,0 +1,12 @@ +using './main.bicep' + +param environment = 'prod' +param location = 'norwayeast' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') + +// secrets +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/applications/service/staging.bicepparam b/.azure/applications/service/staging.bicepparam new file mode 100644 index 000000000..8f45eca13 --- /dev/null +++ b/.azure/applications/service/staging.bicepparam @@ -0,0 +1,12 @@ +using './main.bicep' + +param environment = 'staging' +param location = 'norwayeast' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') + +// secrets +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/applications/service/test.bicepparam b/.azure/applications/service/test.bicepparam new file mode 100644 index 000000000..b3f5fed67 --- /dev/null +++ b/.azure/applications/service/test.bicepparam @@ -0,0 +1,12 @@ +using './main.bicep' + +param environment = 'test' +param location = 'norwayeast' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') + +// secrets +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/modules/containerApp/main.bicep b/.azure/modules/containerApp/main.bicep index 7eb404bef..503a56da9 100644 --- a/.azure/modules/containerApp/main.bicep +++ b/.azure/modules/containerApp/main.bicep @@ -31,6 +31,10 @@ param revisionSuffix string @description('The probes for the container app') param probes array = [] +// 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 = '' + // Container app revision name does not allow '.' character var cleanedRevisionSuffix = replace(revisionSuffix, '.', '-') @@ -50,12 +54,19 @@ var ingress = { ipSecurityRestrictions: ipSecurityRestrictions } +var identityConfig = empty(userAssignedIdentityId) ? { + type: 'SystemAssigned' +} : { + type: 'UserAssigned' + userAssignedIdentities: { + '${userAssignedIdentityId}': {} + } +} + resource containerApp 'Microsoft.App/containerApps@2024-03-01' = { name: name location: location - identity: { - type: 'SystemAssigned' - } + identity: identityConfig properties: { configuration: { ingress: ingress @@ -81,6 +92,10 @@ resource containerApp 'Microsoft.App/containerApps@2024-03-01' = { tags: tags } -output identityPrincipalId string = containerApp.identity.principalId +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 name string = containerApp.name output revisionName string = containerApp.properties.latestRevisionName diff --git a/.github/workflows/workflow-deploy-apps.yml b/.github/workflows/workflow-deploy-apps.yml index 79a87e76f..4caf110ff 100644 --- a/.github/workflows/workflow-deploy-apps.yml +++ b/.github/workflows/workflow-deploy-apps.yml @@ -145,6 +145,7 @@ jobs: - name: web-api-eu - name: web-api-so - name: graphql + - name: service environment: ${{ inputs.environment }} permissions: id-token: write From b1e6a1495e6ca9cd25a6a8cf060f39456db95c30 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 16 Oct 2024 13:03:58 +0200 Subject: [PATCH 02/15] fix(service): ensure default credentials work (#1306) ## Description - Add AZURE_CLIENT_ID because it is needed when using user assigned identities: https://github.com/microsoft/azure-container-apps/issues/442 ## 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) ## Summary by CodeRabbit - **New Features** - Introduced a managed identity for secure access to Azure resources. - Updated environment variable configuration to include `AZURE_CLIENT_ID` for enhanced security. - **Improvements** - Restructured managed identity usage for better resource management and permissions. --- .azure/applications/service/main.bicep | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.azure/applications/service/main.bicep b/.azure/applications/service/main.bicep index d037ce8fe..1925e1033 100644 --- a/.azure/applications/service/main.bicep +++ b/.azure/applications/service/main.bicep @@ -52,6 +52,12 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' name: containerAppEnvironmentName } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: '${namePrefix}-service-identity' + location: location + tags: tags +} + var containerAppEnvVars = [ { name: 'ASPNETCORE_ENVIRONMENT' @@ -69,6 +75,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 = { @@ -111,12 +121,6 @@ var probes = [ } ] -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: '${namePrefix}-service-identity' - location: location - tags: tags -} - module keyVaultReaderAccessPolicy '../../modules/keyvault/addReaderRoles.bicep' = { name: 'keyVaultReaderAccessPolicy-${containerAppName}' params: { From 7bf41775fa2e1c343972df75d3e4138647fa5742 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 16 Oct 2024 13:40:07 +0200 Subject: [PATCH 03/15] feat(service): add permissions for service-bus (#1305) ## Description ## Related Issue(s) - #1302 ## 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) ## Summary by CodeRabbit - **New Features** - Introduced support for Azure Service Bus integration, including new parameters for configuration. - Added functionality to manage Azure Service Bus role assignments dynamically. - **Bug Fixes** - Updated security handling for the container app environment name. - **Documentation** - Enhanced README with detailed instructions for local development, deployment processes, and database management. - **Chores** - Enhanced CI/CD workflow with new secret variables and input parameters for improved deployment control. --- .azure/applications/service/main.bicep | 14 +++++++++- .azure/applications/service/prod.bicepparam | 6 ++--- .../applications/service/staging.bicepparam | 7 ++--- .azure/applications/service/test.bicepparam | 7 ++--- .../serviceBus/addDataOwnerRoles.bicep | 27 +++++++++++++++++++ .github/workflows/ci-cd-main.yml | 1 + .github/workflows/ci-cd-prod.yml | 2 ++ .../ci-cd-pull-request-release-please.yml | 1 + .github/workflows/ci-cd-pull-request.yml | 1 + .github/workflows/ci-cd-staging.yml | 1 + .github/workflows/dispatch-apps.yml | 1 + .github/workflows/workflow-deploy-apps.yml | 4 +++ README.md | 2 +- 13 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 .azure/modules/serviceBus/addDataOwnerRoles.bicep diff --git a/.azure/applications/service/main.bicep b/.azure/applications/service/main.bicep index 1925e1033..1d170855f 100644 --- a/.azure/applications/service/main.bicep +++ b/.azure/applications/service/main.bicep @@ -21,9 +21,12 @@ param resources object? @description('The name of the container app environment') @minLength(3) -@secure() param containerAppEnvironmentName string +@description('The name of the Service Bus namespace') +@minLength(3) +param serviceBusNamespaceName string + @description('The connection string for Application Insights') @minLength(3) @secure() @@ -137,6 +140,14 @@ module appConfigReaderAccessPolicy '../../modules/appConfiguration/addReaderRole } } +module serviceBusOwnerAccessPolicy '../../modules/serviceBus/addDataOwnerRoles.bicep' = { + name: 'serviceBusOwnerAccessPolicy-${containerAppName}' + params: { + serviceBusNamespaceName: serviceBusNamespaceName + principalIds: [managedIdentity.properties.principalId] + } +} + module containerApp '../../modules/containerApp/main.bicep' = { name: containerAppName params: { @@ -158,6 +169,7 @@ module containerApp '../../modules/containerApp/main.bicep' = { dependsOn: [ keyVaultReaderAccessPolicy appConfigReaderAccessPolicy + serviceBusOwnerAccessPolicy ] } diff --git a/.azure/applications/service/prod.bicepparam b/.azure/applications/service/prod.bicepparam index 7abc5dfbb..b35e25d76 100644 --- a/.azure/applications/service/prod.bicepparam +++ b/.azure/applications/service/prod.bicepparam @@ -4,9 +4,9 @@ param environment = 'prod' param location = 'norwayeast' param imageTag = readEnvironmentVariable('IMAGE_TAG') param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') - -// secrets param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param serviceBusNamespaceName = readEnvironmentVariable('AZURE_SERVICE_BUS_NAMESPACE_NAME') +// secrets param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') -param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/applications/service/staging.bicepparam b/.azure/applications/service/staging.bicepparam index 8f45eca13..f1c8a3305 100644 --- a/.azure/applications/service/staging.bicepparam +++ b/.azure/applications/service/staging.bicepparam @@ -4,9 +4,10 @@ param environment = 'staging' param location = 'norwayeast' param imageTag = readEnvironmentVariable('IMAGE_TAG') param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') - -// secrets param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param serviceBusNamespaceName = readEnvironmentVariable('AZURE_SERVICE_BUS_NAMESPACE_NAME') + +// secrets param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') -param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/applications/service/test.bicepparam b/.azure/applications/service/test.bicepparam index b3f5fed67..87c700860 100644 --- a/.azure/applications/service/test.bicepparam +++ b/.azure/applications/service/test.bicepparam @@ -4,9 +4,10 @@ param environment = 'test' param location = 'norwayeast' param imageTag = readEnvironmentVariable('IMAGE_TAG') param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') - -// secrets param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param serviceBusNamespaceName = readEnvironmentVariable('AZURE_SERVICE_BUS_NAMESPACE_NAME') + +// secrets param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') -param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/modules/serviceBus/addDataOwnerRoles.bicep b/.azure/modules/serviceBus/addDataOwnerRoles.bicep new file mode 100644 index 000000000..fe263062a --- /dev/null +++ b/.azure/modules/serviceBus/addDataOwnerRoles.bicep @@ -0,0 +1,27 @@ +@description('The name of the Service Bus namespace') +param serviceBusNamespaceName string + +@description('Array of principal IDs to assign the Azure Service Bus Data Owner role to') +param principalIds array + +resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' existing = { + name: serviceBusNamespaceName +} + +@description('This is the built-in Azure Service Bus Data Owner role. See https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#azure-service-bus-data-owner') +resource serviceBusDataOwnerRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + scope: subscription() + name: '090c5cfd-751d-490a-894a-3ce6f1109419' +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ + for principalId in principalIds: { + scope: serviceBusNamespace + name: guid(serviceBusNamespace.id, principalId, serviceBusDataOwnerRoleDefinition.id) + properties: { + roleDefinitionId: serviceBusDataOwnerRoleDefinition.id + principalId: principalId + principalType: 'ServicePrincipal' + } + } +] diff --git a/.github/workflows/ci-cd-main.yml b/.github/workflows/ci-cd-main.yml index 8918519ae..350c80019 100644 --- a/.github/workflows/ci-cd-main.yml +++ b/.github/workflows/ci-cd-main.yml @@ -101,6 +101,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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: environment: test region: norwayeast diff --git a/.github/workflows/ci-cd-prod.yml b/.github/workflows/ci-cd-prod.yml index 9189675f2..37fefee08 100644 --- a/.github/workflows/ci-cd-prod.yml +++ b/.github/workflows/ci-cd-prod.yml @@ -73,6 +73,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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: environment: prod region: norwayeast @@ -96,6 +97,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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: environment: prod region: norwayeast diff --git a/.github/workflows/ci-cd-pull-request-release-please.yml b/.github/workflows/ci-cd-pull-request-release-please.yml index 8f559d143..f6a73c4ce 100644 --- a/.github/workflows/ci-cd-pull-request-release-please.yml +++ b/.github/workflows/ci-cd-pull-request-release-please.yml @@ -58,6 +58,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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: environment: staging region: norwayeast diff --git a/.github/workflows/ci-cd-pull-request.yml b/.github/workflows/ci-cd-pull-request.yml index 523f85e78..85909d889 100644 --- a/.github/workflows/ci-cd-pull-request.yml +++ b/.github/workflows/ci-cd-pull-request.yml @@ -82,6 +82,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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: environment: test region: norwayeast diff --git a/.github/workflows/ci-cd-staging.yml b/.github/workflows/ci-cd-staging.yml index c1a818358..9ae57c024 100644 --- a/.github/workflows/ci-cd-staging.yml +++ b/.github/workflows/ci-cd-staging.yml @@ -65,6 +65,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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: environment: staging region: norwayeast diff --git a/.github/workflows/dispatch-apps.yml b/.github/workflows/dispatch-apps.yml index cadcfc066..a23fe7999 100644 --- a/.github/workflows/dispatch-apps.yml +++ b/.github/workflows/dispatch-apps.yml @@ -54,6 +54,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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: environment: ${{ inputs.environment }} region: norwayeast diff --git a/.github/workflows/workflow-deploy-apps.yml b/.github/workflows/workflow-deploy-apps.yml index 4caf110ff..0fc5048cf 100644 --- a/.github/workflows/workflow-deploy-apps.yml +++ b/.github/workflows/workflow-deploy-apps.yml @@ -20,6 +20,8 @@ on: required: true AZURE_APP_CONFIGURATION_NAME: required: true + AZURE_SERVICE_BUS_NAMESPACE_NAME: + required: true inputs: region: @@ -175,6 +177,7 @@ jobs: AZURE_APP_INSIGHTS_CONNECTION_STRING: ${{ secrets.AZURE_APP_INSIGHTS_CONNECTION_STRING }} AZURE_APP_CONFIGURATION_NAME: ${{ secrets.AZURE_APP_CONFIGURATION_NAME }} AZURE_ENVIRONMENT_KEY_VAULT_NAME: ${{ secrets.AZURE_ENVIRONMENT_KEY_VAULT_NAME }} + AZURE_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: scope: resourcegroup template: ./.azure/applications/${{ matrix.name }}/main.bicep @@ -199,6 +202,7 @@ jobs: AZURE_APP_INSIGHTS_CONNECTION_STRING: ${{ secrets.AZURE_APP_INSIGHTS_CONNECTION_STRING }} AZURE_APP_CONFIGURATION_NAME: ${{ secrets.AZURE_APP_CONFIGURATION_NAME }} AZURE_ENVIRONMENT_KEY_VAULT_NAME: ${{ secrets.AZURE_ENVIRONMENT_KEY_VAULT_NAME }} + AZURE_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} with: scope: resourcegroup template: ./.azure/applications/${{ matrix.name }}/main.bicep diff --git a/README.md b/README.md index 09f6fdc17..9744e5000 100644 --- a/README.md +++ b/README.md @@ -347,7 +347,7 @@ Ensure you have followed the steps in [Deploying a new infrastructure environmen Use the following steps: -- From the infrastructure resources created, add the following GitHub secrets in the new environment (this will not be necessary in the future as secrets would be added directly from infrastructure deployment): `AZURE_APP_CONFIGURATION_NAME`, `AZURE_APP_INSIGHTS_CONNECTION_STRING`, `AZURE_CONTAINER_APP_ENVIRONMENT_NAME`, `AZURE_ENVIRONMENT_KEY_VAULT_NAME`, `AZURE_REDIS_NAME`, `AZURE_RESOURCE_GROUP_NAME` and `AZURE_SLACK_NOTIFIER_FUNCTION_APP_NAME` +- From the infrastructure resources created, add the following GitHub secrets in the new environment (this will not be necessary in the future as secrets would be added directly from infrastructure deployment): `AZURE_APP_CONFIGURATION_NAME`, `AZURE_APP_INSIGHTS_CONNECTION_STRING`, `AZURE_CONTAINER_APP_ENVIRONMENT_NAME`, `AZURE_ENVIRONMENT_KEY_VAULT_NAME`, `AZURE_REDIS_NAME`, `AZURE_RESOURCE_GROUP_NAME`, `AZURE_SERVICE_BUS_NAMESPACE_NAME` and `AZURE_SLACK_NOTIFIER_FUNCTION_APP_NAME` - Add new parameter files for the environment in all applications `.azure/applications/*/.bicepparam` From f620f06ddce528e1174f9a7c0aac3485c5d5ab3d Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 16 Oct 2024 13:52:55 +0200 Subject: [PATCH 04/15] chore(servicebus): upgrade version (#1307) ## Description Update to use the new version of servicebus namespace ## 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) --- .azure/modules/serviceBus/addDataOwnerRoles.bicep | 2 +- .azure/modules/serviceBus/main.bicep | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure/modules/serviceBus/addDataOwnerRoles.bicep b/.azure/modules/serviceBus/addDataOwnerRoles.bicep index fe263062a..aa0dd5b1a 100644 --- a/.azure/modules/serviceBus/addDataOwnerRoles.bicep +++ b/.azure/modules/serviceBus/addDataOwnerRoles.bicep @@ -4,7 +4,7 @@ param serviceBusNamespaceName string @description('Array of principal IDs to assign the Azure Service Bus Data Owner role to') param principalIds array -resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' existing = { +resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2023-01-01-preview' existing = { name: serviceBusNamespaceName } diff --git a/.azure/modules/serviceBus/main.bicep b/.azure/modules/serviceBus/main.bicep index dca532ff6..74607b134 100644 --- a/.azure/modules/serviceBus/main.bicep +++ b/.azure/modules/serviceBus/main.bicep @@ -32,7 +32,7 @@ param sku Sku var serviceBusNameMaxLength = 50 var serviceBusName = uniqueResourceName('${namePrefix}-service-bus', serviceBusNameMaxLength) -resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = { +resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2023-01-01-preview' = { name: serviceBusName location: location sku: sku From 462f9080529491775c5763fca6074168ee2d1fdc Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 16 Oct 2024 14:01:11 +0200 Subject: [PATCH 05/15] chore(service): use correct docker image (#1308) ## Description Using the healthz endpoint before the proper service is deployed ## Related Issue(s) - #1301 ## 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) --- .azure/applications/service/main.bicep | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.azure/applications/service/main.bicep b/.azure/applications/service/main.bicep index 1d170855f..5fb8a62dd 100644 --- a/.azure/applications/service/main.bicep +++ b/.azure/applications/service/main.bicep @@ -100,7 +100,7 @@ var probes = [ initialDelaySeconds: 2 type: 'Liveness' httpGet: { - path: '/health/liveness' + path: '/healthz' port: port } } @@ -109,7 +109,7 @@ var probes = [ initialDelaySeconds: 2 type: 'Readiness' httpGet: { - path: '/health/readiness' + path: '/healthz' port: port } } @@ -118,7 +118,7 @@ var probes = [ initialDelaySeconds: 2 type: 'Startup' httpGet: { - path: '/health/startup' + path: '/healthz' port: port } } @@ -152,9 +152,7 @@ module containerApp '../../modules/containerApp/main.bicep' = { name: containerAppName params: { name: containerAppName - // todo: make this dynamic based on service name. Using webapi for now. - // image: '${baseImageUrl}${serviceName}:${imageTag}' - image: '${baseImageUrl}webapi:${imageTag}' + image: '${baseImageUrl}${serviceName}:${imageTag}' location: location envVariables: containerAppEnvVars containerAppEnvId: containerAppEnvironment.id From 4baf47e383047895b6e6e47523e7b35e05ee9a81 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 16 Oct 2024 14:12:10 +0200 Subject: [PATCH 06/15] Revert "chore(service): use correct docker image (#1308)" This reverts commit 462f9080529491775c5763fca6074168ee2d1fdc. --- .azure/applications/service/main.bicep | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.azure/applications/service/main.bicep b/.azure/applications/service/main.bicep index 5fb8a62dd..1d170855f 100644 --- a/.azure/applications/service/main.bicep +++ b/.azure/applications/service/main.bicep @@ -100,7 +100,7 @@ var probes = [ initialDelaySeconds: 2 type: 'Liveness' httpGet: { - path: '/healthz' + path: '/health/liveness' port: port } } @@ -109,7 +109,7 @@ var probes = [ initialDelaySeconds: 2 type: 'Readiness' httpGet: { - path: '/healthz' + path: '/health/readiness' port: port } } @@ -118,7 +118,7 @@ var probes = [ initialDelaySeconds: 2 type: 'Startup' httpGet: { - path: '/healthz' + path: '/health/startup' port: port } } @@ -152,7 +152,9 @@ module containerApp '../../modules/containerApp/main.bicep' = { name: containerAppName params: { name: containerAppName - image: '${baseImageUrl}${serviceName}:${imageTag}' + // todo: make this dynamic based on service name. Using webapi for now. + // image: '${baseImageUrl}${serviceName}:${imageTag}' + image: '${baseImageUrl}webapi:${imageTag}' location: location envVariables: containerAppEnvVars containerAppEnvId: containerAppEnvironment.id From eb0f19bfb5a49da1b4b45a15b6e43785212fc62f Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Wed, 16 Oct 2024 17:45:15 +0200 Subject: [PATCH 07/15] feat(applications): add scalers for cpu and memory (#1295) ## Description - Enable automatic scaling based on CPU and memory for graphql and web-api (enduser only) - Setting 70 as the limit, this can be tweaked as we see how the services behave under load - Set a max number of 10 revisions for now. We might need to increase this in yt01 ## Related Issue(s) - #1293 ## 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) ## Summary by CodeRabbit - **New Features** - Introduced dynamic scaling configuration for container apps, allowing for minimum and maximum replicas and custom scaling based on CPU and memory utilization. - **Enhancements** - Improved deployment flexibility with a centralized scaling parameter for container apps. --- .azure/applications/graphql/main.bicep | 26 +++++++++++++++++++++++ .azure/applications/web-api-eu/main.bicep | 25 ++++++++++++++++++++++ .azure/modules/containerApp/main.bicep | 11 ++++++---- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/.azure/applications/graphql/main.bicep b/.azure/applications/graphql/main.bicep index 7fc384267..2a3765386 100644 --- a/.azure/applications/graphql/main.bicep +++ b/.azure/applications/graphql/main.bicep @@ -106,6 +106,31 @@ var probes = [ } ] +var scale = { + minReplicas: 2 + maxReplicas: 10 + rules: [ + { + custom: { + type: 'cpu' + metricType: 'Utilization' + metadata: { + value: '70' + } + } + } + { + custom: { + type: 'memory' + metricType: 'Utilization' + metadata: { + value: '70' + } + } + } + ] +} + resource environmentKeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' existing = { name: environmentKeyVaultName } @@ -126,6 +151,7 @@ module containerApp '../../modules/containerApp/main.bicep' = { revisionSuffix: revisionSuffix probes: probes port: port + scale: scale } } diff --git a/.azure/applications/web-api-eu/main.bicep b/.azure/applications/web-api-eu/main.bicep index 9726cc300..45c9181e0 100644 --- a/.azure/applications/web-api-eu/main.bicep +++ b/.azure/applications/web-api-eu/main.bicep @@ -77,6 +77,30 @@ var containerAppEnvVars = [ } ] +var scale = { + minReplicas: 2 + maxReplicas: 10 + rules: [ + { + custom: { + type: 'cpu' + metricType: 'Utilization' + metadata: { + value: '70' + } + } + } + { + custom: { + type: 'memory' + metricType: 'Utilization' + metadata: { + value: '70' + } + } + } + ] +} resource environmentKeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' existing = { name: environmentKeyVaultName } @@ -128,6 +152,7 @@ module containerApp '../../modules/containerApp/main.bicep' = { resources: resources probes: probes revisionSuffix: revisionSuffix + scale: scale } } diff --git a/.azure/modules/containerApp/main.bicep b/.azure/modules/containerApp/main.bicep index 503a56da9..68bc34168 100644 --- a/.azure/modules/containerApp/main.bicep +++ b/.azure/modules/containerApp/main.bicep @@ -31,6 +31,12 @@ param revisionSuffix string @description('The probes for the container app') param probes array = [] +@description('The scaling configuration for the container app') +param scale object = { + minReplicas: 1 + maxReplicas: 1 // temp disable scaling by default for outbox scheduling +} + // 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 = '' @@ -74,10 +80,7 @@ resource containerApp 'Microsoft.App/containerApps@2024-03-01' = { environmentId: containerAppEnvId template: { revisionSuffix: cleanedRevisionSuffix - scale: { - minReplicas: 1 - maxReplicas: 1 // temp disable scaling for outbox scheduling - } + scale: scale containers: [ { name: name From 8b8862fb781a9c57dcd9f3c8315ce66c64d399e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Dybvik=20Langfors?= Date: Thu, 17 Oct 2024 01:20:33 +0200 Subject: [PATCH 08/15] fix: Fix ID-porten acr claim parsing (#1299) ## Description This fixes acr-parsing (authentication level) for real ID-porten tokens ## Related Issue(s) N/A ## Verification - [x] **Your** code builds clean without any errors or warnings - [x] Manual testing done (required) - [x] Relevant automated test added (if you find this hard, leave it and we'll help out) ## Note There is a bug in the token generator in https://github.com/Altinn/AltinnTestTools, which is still producing the old "Level3" and "Level4" acr-values. ## Summary by CodeRabbit - **New Features** - Enhanced logic for determining authentication levels, improving efficiency and clarity. - Improved handling of authorization details for better data management. - **Tests** - Introduced unit tests for the authentication level parsing, ensuring accuracy and reliability of the new logic. --- .../Extensions/ClaimsPrincipalExtensions.cs | 21 +++++-- .../ClaimsPrincipalExtensionsTests.cs | 59 +++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 tests/Digdir.Domain.Dialogporten.Application.Unit.Tests/Features/V1/Common/Extensions/ClaimsPrincipalExtensionsTests.cs diff --git a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs index abf33f878..28e4f4df8 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/ClaimsPrincipalExtensions.cs @@ -174,17 +174,26 @@ public static bool TryGetOrganizationNumber(this Claim? consumerClaim, [NotNullW public static bool TryGetAuthenticationLevel(this ClaimsPrincipal claimsPrincipal, [NotNullWhen(true)] out int? authenticationLevel) { - foreach (var claimType in new[] { IdportenAuthLevelClaim, AltinnAuthLevelClaim }) + if (claimsPrincipal.TryGetClaimValue(AltinnAuthLevelClaim, out var claimValue) && int.TryParse(claimValue, out var level)) { - if (!claimsPrincipal.TryGetClaimValue(claimType, out var claimValue)) continue; - // The acr claim value is "LevelX" where X is the authentication level - var valueToParse = claimType == IdportenAuthLevelClaim ? claimValue[5..] : claimValue; - if (!int.TryParse(valueToParse, out var level)) continue; - authenticationLevel = level; return true; } + if (claimsPrincipal.TryGetClaimValue(IdportenAuthLevelClaim, out claimValue)) + { + // The acr claim value is either "idporten-loa-substantial" (previously "Level3") or "idporten-loa-high" (previously "Level4") + // https://docs.digdir.no/docs/idporten/oidc/oidc_protocol_new_idporten#new-acr-values + authenticationLevel = claimValue switch + { + "idporten-loa-substantial" => 3, + "idporten-loa-high" => 4, + _ => null + }; + + return authenticationLevel.HasValue; + } + authenticationLevel = null; return false; } diff --git a/tests/Digdir.Domain.Dialogporten.Application.Unit.Tests/Features/V1/Common/Extensions/ClaimsPrincipalExtensionsTests.cs b/tests/Digdir.Domain.Dialogporten.Application.Unit.Tests/Features/V1/Common/Extensions/ClaimsPrincipalExtensionsTests.cs new file mode 100644 index 000000000..8c2204bdc --- /dev/null +++ b/tests/Digdir.Domain.Dialogporten.Application.Unit.Tests/Features/V1/Common/Extensions/ClaimsPrincipalExtensionsTests.cs @@ -0,0 +1,59 @@ +using System.Security.Claims; +using Digdir.Domain.Dialogporten.Application.Common.Extensions; + +namespace Digdir.Domain.Dialogporten.Application.Unit.Tests.Features.V1.Common.Extensions; + +public class ClaimsPrincipalExtensionsTests +{ + [Fact] + public void TryGetAuthenticationLevel_Should_Parse_Idporten_Acr_Claim_For_Level3() + { + // Arrange + var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new[] + { + new Claim("acr", "idporten-loa-substantial") + })); + + // Act + var result = claimsPrincipal.TryGetAuthenticationLevel(out var authenticationLevel); + + // Assert + Assert.True(result); + Assert.Equal(3, authenticationLevel); + } + + [Fact] + public void TryGetAuthenticationLevel_Should_Parse_Idporten_Acr_Claim_For_Level4() + { + // Arrange + var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new[] + { + new Claim("acr", "idporten-loa-high") + })); + + // Act + var result = claimsPrincipal.TryGetAuthenticationLevel(out var authenticationLevel); + + // Assert + Assert.True(result); + Assert.Equal(4, authenticationLevel); + } + + [Fact] + public void TryGetAuthenticationLevel_Should_Parse_Altinn_Authlevel_First() + { + // Arrange + var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new[] + { + new Claim("acr", "idporten-loa-high"), + new Claim("urn:altinn:authlevel", "5") + })); + + // Act + var result = claimsPrincipal.TryGetAuthenticationLevel(out var authenticationLevel); + + // Assert + Assert.True(result); + Assert.Equal(5, authenticationLevel); + } +} From b8fb3cc956b5365b4008abc946e4d967fd710efe Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Thu, 17 Oct 2024 10:12:17 +0200 Subject: [PATCH 09/15] fix(applications): use correct scale configuration (#1311) ## Description ## 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) ## Summary by CodeRabbit - **New Features** - Enhanced scaling configurations for container apps, allowing for more flexible and efficient resource management. - Introduced new types for scaling rules, improving clarity and structure in scaling configurations. - **Improvements** - Updated parameter declarations for scaling, providing better type safety and default values for minimum and maximum replicas. - Removed unnecessary fields in scaling rules to streamline configurations. --- .azure/applications/graphql/main.bicep | 9 ++++++--- .azure/applications/web-api-eu/main.bicep | 10 +++++++--- .azure/modules/containerApp/main.bicep | 24 +++++++++++++++++++++-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/.azure/applications/graphql/main.bicep b/.azure/applications/graphql/main.bicep index 2a3765386..afb8b86cf 100644 --- a/.azure/applications/graphql/main.bicep +++ b/.azure/applications/graphql/main.bicep @@ -1,5 +1,7 @@ targetScope = 'resourceGroup' +import { Scale } from '../../modules/containerApp/main.bicep' + @description('The tag of the image to be used') @minLength(3) param imageTag string @@ -106,15 +108,16 @@ var probes = [ } ] -var scale = { +@description('The scaling configuration for the container app') +param scale Scale = { minReplicas: 2 maxReplicas: 10 rules: [ { custom: { type: 'cpu' - metricType: 'Utilization' metadata: { + type: 'Utilization' value: '70' } } @@ -122,8 +125,8 @@ var scale = { { custom: { type: 'memory' - metricType: 'Utilization' metadata: { + type: 'Utilization' value: '70' } } diff --git a/.azure/applications/web-api-eu/main.bicep b/.azure/applications/web-api-eu/main.bicep index 45c9181e0..fa86c529a 100644 --- a/.azure/applications/web-api-eu/main.bicep +++ b/.azure/applications/web-api-eu/main.bicep @@ -1,5 +1,7 @@ targetScope = 'resourceGroup' +import { Scale } from '../../modules/containerApp/main.bicep' + @description('The tag of the image to be used') @minLength(3) param imageTag string @@ -77,15 +79,16 @@ var containerAppEnvVars = [ } ] -var scale = { +@description('The scaling configuration for the container app') +param scale Scale = { minReplicas: 2 maxReplicas: 10 rules: [ { custom: { type: 'cpu' - metricType: 'Utilization' metadata: { + type: 'Utilization' value: '70' } } @@ -93,14 +96,15 @@ var scale = { { custom: { type: 'memory' - metricType: 'Utilization' metadata: { + type: 'Utilization' value: '70' } } } ] } + resource environmentKeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' existing = { name: environmentKeyVaultName } diff --git a/.azure/modules/containerApp/main.bicep b/.azure/modules/containerApp/main.bicep index 68bc34168..de6d9e1cd 100644 --- a/.azure/modules/containerApp/main.bicep +++ b/.azure/modules/containerApp/main.bicep @@ -31,10 +31,30 @@ param revisionSuffix string @description('The probes for the container app') param probes array = [] +@export() +type ScaleRule = { + // add additional types as needed: https://keda.sh/docs/2.15/scalers/ + custom: { + type: 'cpu' | 'memory' + metadata: { + type: 'Utilization' + value: string + } + } +} + +@export() +type Scale = { + minReplicas: int + maxReplicas: int + rules: ScaleRule[] +} + @description('The scaling configuration for the container app') -param scale object = { +param scale Scale = { minReplicas: 1 - maxReplicas: 1 // temp disable scaling by default for outbox scheduling + maxReplicas: 1 + rules: [] } // TODO: Refactor to make userAssignedIdentityId a required parameter once all container apps use user-assigned identities From 3ffb72476e1085347f51e39e25600bc7a4de69ea Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Thu, 17 Oct 2024 10:21:58 +0200 Subject: [PATCH 10/15] fix(applications): add missing property for scale configuration --- .azure/applications/graphql/main.bicep | 2 ++ .azure/applications/web-api-eu/main.bicep | 2 ++ .azure/modules/containerApp/main.bicep | 1 + 3 files changed, 5 insertions(+) diff --git a/.azure/applications/graphql/main.bicep b/.azure/applications/graphql/main.bicep index afb8b86cf..2d63bebe9 100644 --- a/.azure/applications/graphql/main.bicep +++ b/.azure/applications/graphql/main.bicep @@ -114,6 +114,7 @@ param scale Scale = { maxReplicas: 10 rules: [ { + name: 'cpu' custom: { type: 'cpu' metadata: { @@ -123,6 +124,7 @@ param scale Scale = { } } { + name: 'memory' custom: { type: 'memory' metadata: { diff --git a/.azure/applications/web-api-eu/main.bicep b/.azure/applications/web-api-eu/main.bicep index fa86c529a..9f032afbf 100644 --- a/.azure/applications/web-api-eu/main.bicep +++ b/.azure/applications/web-api-eu/main.bicep @@ -85,6 +85,7 @@ param scale Scale = { maxReplicas: 10 rules: [ { + name: 'cpu' custom: { type: 'cpu' metadata: { @@ -94,6 +95,7 @@ param scale Scale = { } } { + name: 'memory' custom: { type: 'memory' metadata: { diff --git a/.azure/modules/containerApp/main.bicep b/.azure/modules/containerApp/main.bicep index de6d9e1cd..9259e047e 100644 --- a/.azure/modules/containerApp/main.bicep +++ b/.azure/modules/containerApp/main.bicep @@ -33,6 +33,7 @@ param probes array = [] @export() type ScaleRule = { + name: string // add additional types as needed: https://keda.sh/docs/2.15/scalers/ custom: { type: 'cpu' | 'memory' From d6662ce53cd08a613bdf18ba261c3e6607273f09 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Thu, 17 Oct 2024 11:44:58 +0200 Subject: [PATCH 11/15] chore(applications): add appsettings for yt01 (#1312) ## Description Adds appsettings for the new yt01 environment ## Related Issue(s) - #1258 ## 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) ## Summary by CodeRabbit - **New Features** - Introduced new JSON configuration files for the Dialogporten component across multiple modules, enhancing infrastructure and application parameter setups. - Added structured settings for Redis, database connections, and authentication configurations for improved operational efficiency. These changes are essential for the application's functionality, particularly in a test environment. --------- Co-authored-by: Knut Haug <154342485+knuhau@users.noreply.github.com> --- .../appsettings.yt01.json | 62 +++++++++++++++++++ .../appsettings.yt01.json | 54 ++++++++++++++++ .../appsettings.yt01.json | 62 +++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 src/Digdir.Domain.Dialogporten.GraphQL/appsettings.yt01.json create mode 100644 src/Digdir.Domain.Dialogporten.Janitor/appsettings.yt01.json create mode 100644 src/Digdir.Domain.Dialogporten.WebApi/appsettings.yt01.json diff --git a/src/Digdir.Domain.Dialogporten.GraphQL/appsettings.yt01.json b/src/Digdir.Domain.Dialogporten.GraphQL/appsettings.yt01.json new file mode 100644 index 000000000..30cf793dc --- /dev/null +++ b/src/Digdir.Domain.Dialogporten.GraphQL/appsettings.yt01.json @@ -0,0 +1,62 @@ +{ + "Infrastructure": { + "Redis": { + "ConnectionString": "TODO: Add to local secrets" + }, + "DialogDbConnectionString": "TODO: Add to local secrets", + // Settings from appsettings.json, environment variables or other configuration providers. + // The first three are always mandatory for all client definitions types + "Maskinporten": { + // 1. Valid values are test and prod + "Environment": "test", + // 2. Client Id/integration as configured in Maskinporten + "ClientId": "TODO: Add to local secrets", + // 3. Scope(s) requested, space seperated. Must be provisioned on supplied client id. + "Scope": "altinn:events.publish altinn:events.publish.admin altinn:register/partylookup.admin altinn:authorization/authorize.admin altinn:accessmanagement/authorizedparties.admin", + // -------------------------- + // Any additional settings are specific for the selected client definition type. + // See below for examples using other types. + "EncodedJwk": "TODO: Add to local secrets" + }, + "Altinn": { + "BaseUri": "https://platform.yt01.altinn.cloud/", + "EventsBaseUri": "Secret webhook sink URL in source key vault", + "SubscriptionKey": "TODO: Add to local secrets" + } + }, + "Application": { + "Dialogporten": { + "BaseUri": "https://platform.yt01.altinn.cloud/dialogporten", + "Ed25519KeyPairs": { + "Primary": { + "Kid": "TODO: Add to local secrets", + "PrivateComponent": "TODO: Add to local secrets", + "PublicComponent": "TODO: Add to local secrets" + }, + "Secondary": { + "Kid": "TODO: Add to local secrets", + "PrivateComponent": "TODO: Add to local secrets", + "PublicComponent": "TODO: Add to local secrets" + } + } + } + }, + "GraphQl": { + "Authentication": { + "JwtBearerTokenSchemas": [ + { + "Name": "Maskinporten", + "WellKnown": "https://test.maskinporten.no/.well-known/oauth-authorization-server/" + }, + { + "Name": "Altinn", + "WellKnown": "https://platform.yt01.altinn.cloud/authentication/api/v1/openid/.well-known/openid-configuration" + }, + { + "Name": "Idporten", + "WellKnown": "https://test.idporten.no/.well-known/openid-configuration" + } + ] + } + } +} \ No newline at end of file diff --git a/src/Digdir.Domain.Dialogporten.Janitor/appsettings.yt01.json b/src/Digdir.Domain.Dialogporten.Janitor/appsettings.yt01.json new file mode 100644 index 000000000..56fdf733d --- /dev/null +++ b/src/Digdir.Domain.Dialogporten.Janitor/appsettings.yt01.json @@ -0,0 +1,54 @@ +{ + "Infrastructure": { + "Redis": { + "ConnectionString": "TODO: Add to local secrets" + }, + "DialogDbConnectionString": "TODO: Add to local secrets", + "Maskinporten": { + "Environment": "test", + "ClientId": "TODO: Add to local secrets", + "Scope": "altinn:events.publish altinn:events.publish.admin altinn:register/partylookup.admin altinn:authorization/authorize.admin altinn:accessmanagement/authorizedparties.admin", + "EncodedJwk": "TODO: Add to local secrets" + }, + "Altinn": { + "BaseUri": "https://platform.yt01.altinn.cloud/", + "EventsBaseUri": "Secret webhook sink URL in source key vault", + "SubscriptionKey": "TODO: Add to local secrets" + } + }, + "Application": { + "Dialogporten": { + "BaseUri": "https://platform.yt01.altinn.cloud/dialogporten", + "Ed25519KeyPairs": { + "Primary": { + "Kid": "TODO: Add to local secrets", + "PrivateComponent": "TODO: Add to local secrets", + "PublicComponent": "TODO: Add to local secrets" + }, + "Secondary": { + "Kid": "TODO: Add to local secrets", + "PrivateComponent": "TODO: Add to local secrets", + "PublicComponent": "TODO: Add to local secrets" + } + } + } + }, + "WebApi": { + "Authentication": { + "JwtBearerTokenSchemas": [ + { + "Name": "Maskinporten", + "WellKnown": "https://test.maskinporten.no/.well-known/oauth-authorization-server/" + }, + { + "Name": "Altinn", + "WellKnown": "https://platform.yt01.altinn.cloud/authentication/api/v1/openid/.well-known/openid-configuration" + }, + { + "Name": "Idporten", + "WellKnown": "https://test.idporten.no/.well-known/openid-configuration" + } + ] + } + } +} \ No newline at end of file diff --git a/src/Digdir.Domain.Dialogporten.WebApi/appsettings.yt01.json b/src/Digdir.Domain.Dialogporten.WebApi/appsettings.yt01.json new file mode 100644 index 000000000..cf9a9db70 --- /dev/null +++ b/src/Digdir.Domain.Dialogporten.WebApi/appsettings.yt01.json @@ -0,0 +1,62 @@ +{ + "Infrastructure": { + "Redis": { + "ConnectionString": "TODO: Add to local secrets" + }, + "DialogDbConnectionString": "TODO: Add to local secrets", + // Settings from appsettings.json, environment variables or other configuration providers. + // The first three are always mandatory for all client definitions types + "Maskinporten": { + // 1. Valid values are test and prod + "Environment": "test", + // 2. Client Id/integration as configured in Maskinporten + "ClientId": "TODO: Add to local secrets", + // 3. Scope(s) requested, space seperated. Must be provisioned on supplied client id. + "Scope": "altinn:events.publish altinn:events.publish.admin altinn:register/partylookup.admin altinn:authorization/authorize.admin altinn:accessmanagement/authorizedparties.admin", + // -------------------------- + // Any additional settings are specific for the selected client definition type. + // See below for examples using other types. + "EncodedJwk": "TODO: Add to local secrets" + }, + "Altinn": { + "BaseUri": "https://platform.yt01.altinn.cloud/", + "EventsBaseUri": "Secret webhook sink URL in source key vault", + "SubscriptionKey": "TODO: Add to local secrets" + } + }, + "Application": { + "Dialogporten": { + "BaseUri": "https://platform.yt01.altinn.cloud/dialogporten", + "Ed25519KeyPairs": { + "Primary": { + "Kid": "TODO: Add to local secrets", + "PrivateComponent": "TODO: Add to local secrets", + "PublicComponent": "TODO: Add to local secrets" + }, + "Secondary": { + "Kid": "TODO: Add to local secrets", + "PrivateComponent": "TODO: Add to local secrets", + "PublicComponent": "TODO: Add to local secrets" + } + } + } + }, + "WebApi": { + "Authentication": { + "JwtBearerTokenSchemas": [ + { + "Name": "Maskinporten", + "WellKnown": "https://test.maskinporten.no/.well-known/oauth-authorization-server/" + }, + { + "Name": "Altinn", + "WellKnown": "https://platform.yt01.altinn.cloud/authentication/api/v1/openid/.well-known/openid-configuration" + }, + { + "Name": "Idporten", + "WellKnown": "https://test.idporten.no/.well-known/openid-configuration" + } + ] + } + } +} \ No newline at end of file From 1a1ccc0a81da0be7bf89b105dc3af57ee8ae4e93 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Thu, 17 Oct 2024 12:01:22 +0200 Subject: [PATCH 12/15] feat(infrastructure): create new yt01 app environment (#1291) ## Description Dependent on https://github.com/digdir/dialogporten/pull/1290 ## Related Issue(s) - #1258 ## 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) ## Summary by CodeRabbit - **New Features** - Introduced new Bicep parameter files for various applications, allowing for dynamic configuration based on environment variables. - Added a `deploy-apps` job to the CI/CD workflow for streamlined application deployment to the yt01 environment. - Updated workflow dispatch options to include `yt01` as a selectable environment. - **Bug Fixes** - Streamlined CI/CD configuration by removing commented-out sections for clarity. - **Documentation** - Enhanced parameter definitions for better clarity in deployment configurations. --- .azure/applications/graphql/yt01.bicepparam | 13 ++ .../yt01.bicepparam | 11 ++ .../applications/web-api-eu/yt01.bicepparam | 13 ++ .../web-api-migration-job/yt01.bicepparam | 9 ++ .../applications/web-api-so/yt01.bicepparam | 13 ++ .github/workflows/ci-cd-yt01.yml | 138 +++++++++--------- .github/workflows/dispatch-apps.yml | 1 + 7 files changed, 129 insertions(+), 69 deletions(-) create mode 100644 .azure/applications/graphql/yt01.bicepparam create mode 100644 .azure/applications/sync-subject-resource-mappings-job/yt01.bicepparam create mode 100644 .azure/applications/web-api-eu/yt01.bicepparam create mode 100644 .azure/applications/web-api-migration-job/yt01.bicepparam create mode 100644 .azure/applications/web-api-so/yt01.bicepparam diff --git a/.azure/applications/graphql/yt01.bicepparam b/.azure/applications/graphql/yt01.bicepparam new file mode 100644 index 000000000..6b94c4e0b --- /dev/null +++ b/.azure/applications/graphql/yt01.bicepparam @@ -0,0 +1,13 @@ +using './main.bicep' + +param environment = 'yt01' +param location = 'norwayeast' +param apimIp = '51.13.85.197' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') + +// secrets +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/applications/sync-subject-resource-mappings-job/yt01.bicepparam b/.azure/applications/sync-subject-resource-mappings-job/yt01.bicepparam new file mode 100644 index 000000000..d742f9760 --- /dev/null +++ b/.azure/applications/sync-subject-resource-mappings-job/yt01.bicepparam @@ -0,0 +1,11 @@ +using './main.bicep' + +param environment = 'yt01' +param location = 'norwayeast' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param jobSchedule = '*/5 * * * *' // Runs every 5 minutes + +//secrets +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') diff --git a/.azure/applications/web-api-eu/yt01.bicepparam b/.azure/applications/web-api-eu/yt01.bicepparam new file mode 100644 index 000000000..6b94c4e0b --- /dev/null +++ b/.azure/applications/web-api-eu/yt01.bicepparam @@ -0,0 +1,13 @@ +using './main.bicep' + +param environment = 'yt01' +param location = 'norwayeast' +param apimIp = '51.13.85.197' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') + +// secrets +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.azure/applications/web-api-migration-job/yt01.bicepparam b/.azure/applications/web-api-migration-job/yt01.bicepparam new file mode 100644 index 000000000..ebf1e4731 --- /dev/null +++ b/.azure/applications/web-api-migration-job/yt01.bicepparam @@ -0,0 +1,9 @@ +using './main.bicep' + +param environment = 'yt01' +param location = 'norwayeast' +param imageTag = readEnvironmentVariable('IMAGE_TAG') + +//secrets +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') diff --git a/.azure/applications/web-api-so/yt01.bicepparam b/.azure/applications/web-api-so/yt01.bicepparam new file mode 100644 index 000000000..6b94c4e0b --- /dev/null +++ b/.azure/applications/web-api-so/yt01.bicepparam @@ -0,0 +1,13 @@ +using './main.bicep' + +param environment = 'yt01' +param location = 'norwayeast' +param apimIp = '51.13.85.197' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') + +// secrets +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') diff --git a/.github/workflows/ci-cd-yt01.yml b/.github/workflows/ci-cd-yt01.yml index 10b403330..8dcf2f7df 100644 --- a/.github/workflows/ci-cd-yt01.yml +++ b/.github/workflows/ci-cd-yt01.yml @@ -48,75 +48,75 @@ jobs: region: norwayeast version: ${{ needs.get-current-version.outputs.version }} - # todo: enable when we have infrastructure set up for yt01 - # deploy-apps-yt01: - # name: Deploy apps to yt01 - # needs: - # [get-current-version, check-for-changes, deploy-infra, publish] - # # we want deployment of apps to be dependent on deployment of infrastructure, but if infrastructure is skipped, we still want to deploy the apps - # if: ${{ always() && !failure() && !cancelled() && (github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasBackendChanges == 'true') }} - # uses: ./.github/workflows/workflow-deploy-apps.yml - # secrets: - # AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} - # AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} - # AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - # # todo: consider resolving these in another way since they are created in the infra-step - # AZURE_RESOURCE_GROUP_NAME: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }} - # AZURE_ENVIRONMENT_KEY_VAULT_NAME: ${{ secrets.AZURE_ENVIRONMENT_KEY_VAULT_NAME }} - # 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 }} - # with: - # environment: yt01 - # region: norwayeast - # version: ${{ needs.get-current-version.outputs.version }} - # runMigration: ${{ github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasMigrationChanges == 'true' }} + deploy-apps: + name: Deploy apps to yt01 + needs: + [get-current-version, check-for-changes, deploy-infra, publish] + # we want deployment of apps to be dependent on deployment of infrastructure, but if infrastructure is skipped, we still want to deploy the apps + if: ${{ always() && !failure() && !cancelled() && (github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasBackendChanges == 'true') }} + uses: ./.github/workflows/workflow-deploy-apps.yml + secrets: + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + # todo: consider resolving these in another way since they are created in the infra-step + AZURE_RESOURCE_GROUP_NAME: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }} + AZURE_ENVIRONMENT_KEY_VAULT_NAME: ${{ secrets.AZURE_ENVIRONMENT_KEY_VAULT_NAME }} + 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_SERVICE_BUS_NAMESPACE_NAME: ${{ secrets.AZURE_SERVICE_BUS_NAMESPACE_NAME }} + with: + environment: yt01 + region: norwayeast + version: ${{ needs.get-current-version.outputs.version }} + runMigration: ${{ github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasMigrationChanges == 'true' }} - # deploy-slack-notifier-yt01: - # name: Deploy slack notifier (yt01) - # needs: [check-for-changes] - # if: ${{ github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasSlackNotifierChanges == 'true' }} - # uses: ./.github/workflows/workflow-deploy-function.yml - # secrets: - # AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} - # AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} - # AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - # # todo: resolve this automatically, or use tags - # AZURE_FUNCTION_APP_NAME: ${{ secrets.AZURE_SLACK_NOTIFIER_FUNCTION_APP_NAME }} - # with: - # function-app-name: "slack-notifier" - # function-project-path: "./src/Digdir.Tool.Dialogporten.SlackNotifier" - # environment: yt01 + deploy-slack-notifier: + name: Deploy slack notifier (yt01) + needs: [check-for-changes] + if: ${{ github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasSlackNotifierChanges == 'true' }} + uses: ./.github/workflows/workflow-deploy-function.yml + secrets: + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + # todo: resolve this automatically, or use tags + AZURE_FUNCTION_APP_NAME: ${{ secrets.AZURE_SLACK_NOTIFIER_FUNCTION_APP_NAME }} + with: + function-app-name: "slack-notifier" + function-project-path: "./src/Digdir.Tool.Dialogporten.SlackNotifier" + environment: yt01 - # run-e2e-tests: - # name: "Run K6 functional end-to-end tests" - # # we want the end-to-end tests to be dependent on deployment of infrastructure and apps, but if infrastructure is skipped, we still want to run the tests - # if: ${{ always() && !failure() && !cancelled() && (github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasBackendChanges == 'true') }} - # needs: [deploy-apps-yt01, check-for-changes] - # uses: ./.github/workflows/workflow-run-k6-tests.yml - # secrets: - # TOKEN_GENERATOR_USERNAME: ${{ secrets.TOKEN_GENERATOR_USERNAME }} - # TOKEN_GENERATOR_PASSWORD: ${{ secrets.TOKEN_GENERATOR_PASSWORD }} - # with: - # environment: yt01 - # apiVersion: v1 - # testSuitePath: tests/k6/suites/all-single-pass.js - # permissions: - # checks: write - # pull-requests: write + run-e2e-tests: + name: "Run K6 functional end-to-end tests" + # we want the end-to-end tests to be dependent on deployment of infrastructure and apps, but if infrastructure is skipped, we still want to run the tests + if: ${{ always() && !failure() && !cancelled() && (github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasBackendChanges == 'true') }} + needs: [deploy-apps, check-for-changes] + uses: ./.github/workflows/workflow-run-k6-tests.yml + secrets: + TOKEN_GENERATOR_USERNAME: ${{ secrets.TOKEN_GENERATOR_USERNAME }} + TOKEN_GENERATOR_PASSWORD: ${{ secrets.TOKEN_GENERATOR_PASSWORD }} + with: + environment: yt01 + apiVersion: v1 + testSuitePath: tests/k6/suites/all-single-pass.js + permissions: + checks: write + pull-requests: write - # send-slack-message-on-failure: - # name: Send Slack message on failure - # needs: [deploy-infra, deploy-apps-yt01, deploy-slack-notifier-yt01, run-e2e-tests, publish] - # if: ${{ always() && failure() && !cancelled() }} - # uses: ./.github/workflows/workflow-send-ci-cd-status-slack-message.yml - # with: - # environment: yt01 - # infra_status: ${{ needs.deploy-infra.result }} - # apps_status: ${{ needs.deploy-apps-yt01.result }} - # slack_notifier_status: ${{ needs.deploy-slack-notifier-yt01.result }} - # e2e_tests_status: ${{ needs.run-e2e-tests.result }} - # publish_status: ${{ needs.publish.result }} - # secrets: - # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - # SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID_FOR_CI_CD_STATUS }} + send-slack-message-on-failure: + name: Send Slack message on failure + needs: [deploy-infra, deploy-apps, deploy-slack-notifier, run-e2e-tests, publish] + if: ${{ always() && failure() && !cancelled() }} + uses: ./.github/workflows/workflow-send-ci-cd-status-slack-message.yml + with: + environment: yt01 + infra_status: ${{ needs.deploy-infra.result }} + apps_status: ${{ needs.deploy-apps.result }} + slack_notifier_status: ${{ needs.deploy-slack-notifier.result }} + e2e_tests_status: ${{ needs.run-e2e-tests.result }} + publish_status: ${{ needs.publish.result }} + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID_FOR_CI_CD_STATUS }} diff --git a/.github/workflows/dispatch-apps.yml b/.github/workflows/dispatch-apps.yml index a23fe7999..b4435f72e 100644 --- a/.github/workflows/dispatch-apps.yml +++ b/.github/workflows/dispatch-apps.yml @@ -10,6 +10,7 @@ on: type: choice options: - test + - yt01 - staging - prod version: From 336d0261b2c941ed43becd8a750f9d4083013623 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Thu, 17 Oct 2024 12:16:18 +0200 Subject: [PATCH 13/15] chore(applications): add bicepparam for yt01 for service --- .azure/applications/service/yt01.bicepparam | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .azure/applications/service/yt01.bicepparam diff --git a/.azure/applications/service/yt01.bicepparam b/.azure/applications/service/yt01.bicepparam new file mode 100644 index 000000000..81261d36f --- /dev/null +++ b/.azure/applications/service/yt01.bicepparam @@ -0,0 +1,13 @@ +using './main.bicep' + +param environment = 'yt01' +param location = 'norwayeast' +param imageTag = readEnvironmentVariable('IMAGE_TAG') +param revisionSuffix = readEnvironmentVariable('REVISION_SUFFIX') +param environmentKeyVaultName = readEnvironmentVariable('AZURE_ENVIRONMENT_KEY_VAULT_NAME') +param appConfigurationName = readEnvironmentVariable('AZURE_APP_CONFIGURATION_NAME') +param containerAppEnvironmentName = readEnvironmentVariable('AZURE_CONTAINER_APP_ENVIRONMENT_NAME') +param serviceBusNamespaceName = readEnvironmentVariable('AZURE_SERVICE_BUS_NAMESPACE_NAME') + +// secrets +param appInsightConnectionString = readEnvironmentVariable('AZURE_APP_INSIGHTS_CONNECTION_STRING') From af6329cd56a7db4147ad500fdd2f3fc61a8bb7df Mon Sep 17 00:00:00 2001 From: Dialogporten Automation Bot <164321870+dialogporten-bot@users.noreply.github.com> Date: Thu, 17 Oct 2024 12:29:44 +0200 Subject: [PATCH 14/15] chore(main): release 1.25.0 (#1304) :robot: I have created a release *beep* *boop* --- ## [1.25.0](https://github.com/digdir/dialogporten/compare/v1.24.0...v1.25.0) (2024-10-17) ### Features * **applications:** add scalers for cpu and memory ([#1295](https://github.com/digdir/dialogporten/issues/1295)) ([eb0f19b](https://github.com/digdir/dialogporten/commit/eb0f19bfb5a49da1b4b45a15b6e43785212fc62f)) * **infrastructure:** create new yt01 app environment ([#1291](https://github.com/digdir/dialogporten/issues/1291)) ([1a1ccc0](https://github.com/digdir/dialogporten/commit/1a1ccc0a81da0be7bf89b105dc3af57ee8ae4e93)) * **service:** add permissions for service-bus ([#1305](https://github.com/digdir/dialogporten/issues/1305)) ([7bf4177](https://github.com/digdir/dialogporten/commit/7bf41775fa2e1c343972df75d3e4138647fa5742)) * **service:** deploy application in container apps ([#1303](https://github.com/digdir/dialogporten/issues/1303)) ([a309044](https://github.com/digdir/dialogporten/commit/a309044bd40d9a56c453496aab9122b8f6c67adb)) ### Bug Fixes * **applications:** add missing property for scale configuration ([3ffb724](https://github.com/digdir/dialogporten/commit/3ffb72476e1085347f51e39e25600bc7a4de69ea)) * **applications:** use correct scale configuration ([#1311](https://github.com/digdir/dialogporten/issues/1311)) ([b8fb3cc](https://github.com/digdir/dialogporten/commit/b8fb3cc956b5365b4008abc946e4d967fd710efe)) * Fix ID-porten acr claim parsing ([#1299](https://github.com/digdir/dialogporten/issues/1299)) ([8b8862f](https://github.com/digdir/dialogporten/commit/8b8862fb781a9c57dcd9f3c8315ce66c64d399e2)) * **service:** ensure default credentials work ([#1306](https://github.com/digdir/dialogporten/issues/1306)) ([b1e6a14](https://github.com/digdir/dialogporten/commit/b1e6a1495e6ca9cd25a6a8cf060f39456db95c30)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- CHANGELOG.md | 18 ++++++++++++++++++ version.txt | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7defc6497..11257ee63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [1.25.0](https://github.com/digdir/dialogporten/compare/v1.24.0...v1.25.0) (2024-10-17) + + +### Features + +* **applications:** add scalers for cpu and memory ([#1295](https://github.com/digdir/dialogporten/issues/1295)) ([eb0f19b](https://github.com/digdir/dialogporten/commit/eb0f19bfb5a49da1b4b45a15b6e43785212fc62f)) +* **infrastructure:** create new yt01 app environment ([#1291](https://github.com/digdir/dialogporten/issues/1291)) ([1a1ccc0](https://github.com/digdir/dialogporten/commit/1a1ccc0a81da0be7bf89b105dc3af57ee8ae4e93)) +* **service:** add permissions for service-bus ([#1305](https://github.com/digdir/dialogporten/issues/1305)) ([7bf4177](https://github.com/digdir/dialogporten/commit/7bf41775fa2e1c343972df75d3e4138647fa5742)) +* **service:** deploy application in container apps ([#1303](https://github.com/digdir/dialogporten/issues/1303)) ([a309044](https://github.com/digdir/dialogporten/commit/a309044bd40d9a56c453496aab9122b8f6c67adb)) + + +### Bug Fixes + +* **applications:** add missing property for scale configuration ([3ffb724](https://github.com/digdir/dialogporten/commit/3ffb72476e1085347f51e39e25600bc7a4de69ea)) +* **applications:** use correct scale configuration ([#1311](https://github.com/digdir/dialogporten/issues/1311)) ([b8fb3cc](https://github.com/digdir/dialogporten/commit/b8fb3cc956b5365b4008abc946e4d967fd710efe)) +* Fix ID-porten acr claim parsing ([#1299](https://github.com/digdir/dialogporten/issues/1299)) ([8b8862f](https://github.com/digdir/dialogporten/commit/8b8862fb781a9c57dcd9f3c8315ce66c64d399e2)) +* **service:** ensure default credentials work ([#1306](https://github.com/digdir/dialogporten/issues/1306)) ([b1e6a14](https://github.com/digdir/dialogporten/commit/b1e6a1495e6ca9cd25a6a8cf060f39456db95c30)) + ## [1.24.0](https://github.com/digdir/dialogporten/compare/v1.23.2...v1.24.0) (2024-10-15) diff --git a/version.txt b/version.txt index 53cc1a6f9..ad2191947 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.24.0 +1.25.0 From 007248856b33fc0e4798814a2f0883cee0afd3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20J=C3=B8rgen=20Skogstad?= Date: Thu, 17 Oct 2024 12:34:45 +0200 Subject: [PATCH 15/15] chore(coderabbit): CodeRabbit path filter for Migrations (#1313) ## Summary by CodeRabbit - **New Features** - Introduced a filter to exclude migration files from specific operations. - **Bug Fixes** - Corrected indentation for better configuration clarity. --- .coderabbit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index a92ae0b2c..f28f30133 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -13,7 +13,7 @@ reviews: collapse_walkthrough: true sequence_diagrams: false labeling_instructions: [] - path_filters: [] + path_filters: ["!**/Migrations/**/*Designer.cs", "!**/Migrations/DialogDbContextModelSnapshot.cs"] path_instructions: [] abort_on_close: true auto_review: