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

Ees xxxx add per environment scaling and workload profiles #5483

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ResourceNames } from '../../types.bicep'
import { ResourceNames, ContainerAppResourceConfig } from '../../types.bicep'

@description('Specifies common resource naming variables.')
param resourceNames ResourceNames
Expand Down Expand Up @@ -30,6 +30,9 @@ param apiAppRegistrationClientId string
@description('Specifies the Application Insights connection string for this Container App to use for its monitoring.')
param appInsightsConnectionString string

@description('Resource limits and scaling configuration.')
param resourceAndScalingConfig ContainerAppResourceConfig

@description('Whether to create or update Azure Monitor alerts during this deploy')
param deployAlerts bool

Expand Down Expand Up @@ -145,6 +148,12 @@ module apiContainerAppModule '../../components/containerApp.bicep' = {
]
requireAuthentication: false
}
cpuCores: resourceAndScalingConfig.cpuCores
memorySizeGis: resourceAndScalingConfig.memoryGis
minReplicas: resourceAndScalingConfig.minReplicas
maxReplicas: resourceAndScalingConfig.maxReplicas
scaleAtConcurrentHttpRequests: resourceAndScalingConfig.scaleAtConcurrentHttpRequests
workloadProfileName: resourceAndScalingConfig.workloadProfileName
tagValues: tagValues
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ResourceNames } from '../../types.bicep'
import { ResourceNames, ContainerAppWorkloadProfile } from '../../types.bicep'

@description('Specifies common resource naming variables.')
param resourceNames ResourceNames
Expand All @@ -9,6 +9,9 @@ param location string
@description('Specifies the Application Insights key that is associated with this resource.')
param applicationInsightsKey string

@description('Specifies the workload profiles for this Container App Environment - the default Consumption plan is always included')
param workloadProfiles ContainerAppWorkloadProfile[] = []

@description('Specifies a set of tags with which to tag the resource in Azure.')
param tagValues object

Expand All @@ -33,7 +36,6 @@ module containerAppEnvironmentModule '../../components/containerAppEnvironment.b
subnetId: subnet.id
logAnalyticsWorkspaceName: resourceNames.sharedResources.logAnalyticsWorkspace
applicationInsightsKey: applicationInsightsKey
tagValues: tagValues
azureFileStorages: [
{
storageName: resourceNames.publicApi.publicApiFileShare
Expand All @@ -43,6 +45,8 @@ module containerAppEnvironmentModule '../../components/containerAppEnvironment.b
accessMode: 'ReadWrite'
}
]
workloadProfiles: workloadProfiles
tagValues: tagValues
}
}

Expand Down
5 changes: 5 additions & 0 deletions infrastructure/templates/public-api/ci/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ parameters:
- name: deployDataProcessor
displayName: Does the Data Processor need creating or updating?
default: true
- name: deployDocsSite
displayName: Does the Public API static docs site need creating or updating?
default: true
- name: deployAlerts
displayName: Whether to create or update Azure Monitor alerts during this deploy.
default: false
Expand Down Expand Up @@ -58,6 +61,8 @@ variables:
value: ${{ parameters.deployContainerApp }}
- name: deployDataProcessor
value: ${{ parameters.deployDataProcessor }}
- name: deployDocsSite
value: ${{ parameters.deployDocsSite }}
- name: deployAlerts
value: ${{ parameters.deployAlerts }}
- name: awaitActiveOrchestrations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ parameters:
jobs:
- deployment: DeployPublicApiDocs
displayName: Deploy Public API docs
condition: and(succeeded(), eq(variables.deployDocsSite, true))
dependsOn: ${{ parameters.dependsOn }}
environment: ${{ parameters.environment }}
strategy:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
deployPsqlFlexibleServer: false
deployContainerApp: false
deployDataProcessor: false
deployDocsSite: false
deployAlerts: false
dataProcessorExists: false

Expand Down Expand Up @@ -68,6 +69,7 @@ jobs:
deployPsqlFlexibleServer: $(deployPsqlFlexibleServer)
deployContainerApp: $(deployContainerApp)
deployDataProcessor: $(deployDataProcessor)
deployDocsSite: $(deployDocsSite)
deployAlerts: $(deployAlerts)
dataProcessorExists: $(dataProcessorExists)

Expand Down
3 changes: 3 additions & 0 deletions infrastructure/templates/public-api/ci/tasks/deploy-bicep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ parameters:
default: true
- name: deployDataProcessor
type: string
- name: deployDocsSite
type: string
- name: deployAlerts
type: string
- name: dataProcessorExists
Expand Down Expand Up @@ -55,6 +57,7 @@ steps:
deployPsqlFlexibleServer=${{ parameters.deployPsqlFlexibleServer }} \
deployContainerApp=${{ parameters.deployContainerApp }} \
deployDataProcessor=${{ parameters.deployDataProcessor }} \
deployDocsSite=${{ parameters.deployDocsSite }} \
deployAlerts=${{ parameters.deployAlerts }} \
dataProcessorFunctionAppExists=${{ parameters.dataProcessorExists }} \
dataProcessorAppRegistrationClientId='$(dataProcessorAppRegistrationClientId)' \
Expand Down
60 changes: 27 additions & 33 deletions infrastructure/templates/public-api/components/containerApp.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,31 @@ param corsPolicy {
allowedOrigins: string[]?
}

@description('Name of the workload profile under which this Container App will be deployed. Defaults to Consumption.')
param workloadProfileName string = 'Consumption'

@description('Number of CPU cores the container can use. Can be with a maximum of two decimals.')
@allowed([
'1'
'2'
'3'
'4'
])
param cpuCore string = '4'

@description('Amount of memory (in gibibytes, GiB) allocated to the container up to 4GiB. Can be with a maximum of two decimals. Ratio with CPU cores must be equal to 2.')
@allowed([
'1'
'2'
'3'
'4'
'5'
'6'
'7'
'8'
])
param memorySize string = '8'
@minValue(1)
@maxValue(8)
param cpuCores int = 4

@description('Amount of memory (in gibibytes, GiB) allocated to the container up to 32GiB. Can be with a maximum of two decimals. Ratio with CPU cores must be equal to 2.')
@minValue(1)
@maxValue(32)
param memorySizeGis int = 8

@description('Minimum number of replicas that will be deployed')
@minValue(0)
@maxValue(25)
param minReplica int = 1
param minReplicas int = 1

@description('Maximum number of replicas that will be deployed')
@minValue(0)
@maxValue(25)
param maxReplica int = 3
@maxValue(1000)
param maxReplicas int = 3

@description('Number of concurrent requests required in order to trigger scaling out.')
@minValue(1)
param scaleAtConcurrentHttpRequests int?

@description('Specifies the database connection string')
param appSettings {
Expand Down Expand Up @@ -113,7 +107,7 @@ param tagValues object

var containerImageName = '${acrLoginServer}/${containerAppImageName}'

resource containerApp 'Microsoft.App/containerApps@2023-11-02-preview' = {
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
name: containerAppName
location: location
identity: {
Expand Down Expand Up @@ -160,29 +154,29 @@ resource containerApp 'Microsoft.App/containerApps@2023-11-02-preview' = {
image: containerImageName
env: appSettings
resources: {
cpu: json(cpuCore)
memory: '${memorySize}Gi'
cpu: json(string(cpuCores))
memory: '${memorySizeGis}Gi'
}
volumeMounts: volumeMounts
}
]
scale: {
minReplicas: minReplica
maxReplicas: maxReplica
rules: [
minReplicas: minReplicas
maxReplicas: maxReplicas
rules: union(scaleAtConcurrentHttpRequests != null ? [
{
name: 'http-requests'
http: {
metadata: {
concurrentRequests: '10'
concurrentRequests: string(scaleAtConcurrentHttpRequests)
}
}
}
]
] : [], [])
}
volumes: volumes
}
workloadProfileName: 'Consumption'
workloadProfileName: workloadProfileName
}
tags: tagValues
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ContainerAppWorkloadProfile } from '../types.bicep'

@description('Specifies the location of the Container App Environment - defaults to that of the Resource Group')
param location string

Expand All @@ -13,14 +15,8 @@ param logAnalyticsWorkspaceName string
@description('Specifies the Application Insights key that is associated with this resource')
param applicationInsightsKey string

@description('Specifies the workload profiles for this Container App Environment - defaults to Consumption')
param workloadProfiles {
name: string
workloadProfileType: string
}[] = [{
name: 'Consumption'
workloadProfileType: 'Consumption'
}]
@description('Specifies the workload profiles for this Container App Environment - the default Consumption plan is always included')
param workloadProfiles ContainerAppWorkloadProfile[] = []

@description('Specifies a set of tags with which to tag the resource in Azure')
param tagValues object
Expand Down Expand Up @@ -57,7 +53,12 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01'
sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
}
}
workloadProfiles: workloadProfiles
workloadProfiles: union([{
name: 'Consumption'
workloadProfileType: 'Consumption'
}],
workloadProfiles
)
}
tags: tagValues

Expand Down
24 changes: 21 additions & 3 deletions infrastructure/templates/public-api/main.bicep
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { abbreviations } from 'abbreviations.bicep'
import { IpRange, PrincipalNameAndId, StaticWebAppSku } from 'types.bicep'
import { ContainerAppResourceConfig, IpRange, PrincipalNameAndId, StaticWebAppSku, ContainerAppWorkloadProfile } from 'types.bicep'

@description('Environment : Subscription name e.g. s101d01. Used as a prefix for created resources.')
param subscription string = ''
Expand Down Expand Up @@ -78,6 +78,9 @@ param deployContainerApp bool = true
@description('Does the Data Processor need creating or updating?')
param deployDataProcessor bool = true

@description('Does the Public API static docs site need creating or updating?')
param deployDocsSite bool = true

param deployAlerts bool = false

@description('Public URLs of other components in the service.')
Expand Down Expand Up @@ -107,6 +110,19 @@ param devopsServicePrincipalId string = ''
@description('Specifies whether or not test Themes can be deleted in the environment.')
param enableThemeDeletion bool = false

@description('Specifies the workload profiles for this Container App Environment - the default Consumption plan is always included')
param publicApiContainerAppWorkloadProfiles ContainerAppWorkloadProfile[] = []

@description('Resource configuration for the Public API Container App.')
param publicApiContainerAppConfig ContainerAppResourceConfig = {
cpuCores: 4
memoryGis: 8
minReplicas: 0
maxReplicas: 3
scaleAtConcurrentHttpRequests: 10
workloadProfileName: 'Consumption'
}

var tagValues = union(resourceTags ?? {}, {
Environment: environmentName
DateProvisioned: dateProvisioned
Expand Down Expand Up @@ -254,6 +270,7 @@ module containerAppEnvironmentModule 'application/shared/containerAppEnvironment
location: location
resourceNames: resourceNames
applicationInsightsKey: appInsightsModule.outputs.appInsightsKey
workloadProfiles: publicApiContainerAppWorkloadProfiles
tagValues: tagValues
}
dependsOn: [
Expand Down Expand Up @@ -286,6 +303,7 @@ module apiAppModule 'application/public-api/publicApiApp.bicep' = if (deployCont
dockerImagesTag: dockerImagesTag
appInsightsConnectionString: appInsightsModule.outputs.appInsightsConnectionString
deployAlerts: deployAlerts
resourceAndScalingConfig: publicApiContainerAppConfig
tagValues: tagValues
}
dependsOn: [
Expand All @@ -295,7 +313,7 @@ module apiAppModule 'application/public-api/publicApiApp.bicep' = if (deployCont
}

// Deploy Public API docs.
module docsModule 'application/public-api/publicApiDocs.bicep' = {
module docsModule 'application/public-api/publicApiDocs.bicep' = if (deployDocsSite) {
name: 'publicApiDocsModuleDeploy'
params: {
appSku: docsAppSku
Expand All @@ -307,7 +325,7 @@ module docsModule 'application/public-api/publicApiDocs.bicep' = {
var docsRewriteSetName = '${publicApiResourcePrefix}-docs-rewrites'

// Create an Application Gateway to serve public traffic for the Public API Container App.
module appGatewayModule 'application/shared/appGateway.bicep' = if (deployContainerApp) {
module appGatewayModule 'application/shared/appGateway.bicep' = if (deployContainerApp && deployDocsSite) {
name: 'appGatewayModuleDeploy'
params: {
location: location
Expand Down
16 changes: 16 additions & 0 deletions infrastructure/templates/public-api/parameters/main-dev.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,20 @@ param postgreSqlSkuName = 'Standard_B1ms'
param postgreSqlStorageSizeGB = 32
param postgreSqlAutoGrowStatus = 'Disabled'

param publicApiContainerAppConfig = {
cpuCores: 4
memoryGis: 8
minReplicas: 1
maxReplicas: 100
scaleAtConcurrentHttpRequests: 5
workloadProfileName: 'Consumption'
}

param publicApiContainerAppWorkloadProfiles = [{
name: 'D8'
workloadProfileType: 'D8'
minimumCount: 0
maximumCount: 10
}]

param enableThemeDeletion = true
18 changes: 18 additions & 0 deletions infrastructure/templates/public-api/types.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,21 @@ type KeyVaultRole = 'Secrets User' | 'Certificate User'

@export()
type StaticWebAppSku = 'Free' | 'Standard'

@export()
type ContainerAppResourceConfig = {
workloadProfileName: string
cpuCores: int
memoryGis: int
minReplicas: int
maxReplicas: int
scaleAtConcurrentHttpRequests: int?
}

@export()
type ContainerAppWorkloadProfile = {
name: string
workloadProfileType: 'D4' | 'D8' | 'D16' | 'D32' | 'E4' | 'E8' | 'E16' | 'E32'
minimumCount: int
maximumCount: int
}
Loading