Skip to content

Commit 80f9d5c

Browse files
authored
Merge pull request #4919 from dfe-analytical-services/dev
Merge Dev into Master
2 parents d1e8b0e + 6d8be51 commit 80f9d5c

File tree

234 files changed

+10945
-2147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

234 files changed

+10945
-2147
lines changed

.github/workflows/block-autosquash-commits.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ jobs:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- name: Block auto-squash commits
14-
uses: xt0rted/block-autosquash-commits-action@f1ab4d69a90297fde61bc263d2e048eb8480d293
14+
uses: xt0rted/block-autosquash-commits-action@87d56ca2c3f01b9247504ead67a1a3c2ca62b030
1515
with:
1616
repo-token: ${{ secrets.GH_TOKEN }}

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ bin
1313
obj
1414
/data/ees-mssql
1515
/data/public-api-db
16-
/data/public-api-parquet
16+
/data/public-api-data
1717
dfe-meta.db
1818

1919
## CSharp

docker-compose.yml

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ services:
4343

4444
public-api-db:
4545
image: postgres:16.1-alpine
46+
command: postgres -c max_prepared_transactions=100
4647
ports:
4748
- "5432:5432"
4849
volumes:

infrastructure/templates/public-api/api-infrastructure-pipeline.yml

+21-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
trigger: none
22

3-
resources:
4-
pipelines:
5-
- pipeline: EESBuildPipeline
6-
source: Explore Education Statistics
7-
trigger: none
8-
93
parameters:
104
- name: deployContainerApp
115
displayName: Can we deploy the Container App yet? This is dependent on the user-assigned Managed Identity for the API Container App being created with the AcrPull role, and the database users added to PSQL.
@@ -14,6 +8,27 @@ parameters:
148
displayName: Does the PostgreSQL Flexible Server require any updates? False by default to avoid unnecessarily lengthy deploys.
159
default: false
1610

11+
# This param is helpful for debugging to allow the selection of a particular branch from which to base a deploy from this pipeline.
12+
# This should be removed in the long term in favour of using the "Resources" selection from the "Run pipeline" dialog.
13+
#
14+
# - name: buildBranchToDeploy
15+
# displayName: Build branch to deploy. This allows a person who is manually running the pipeline to specify the use of the latest EESBuildPipeline build that was run against that branch.
16+
# default: 'Branch from latest pipeline run'
17+
18+
resources:
19+
pipelines:
20+
- pipeline: EESBuildPipeline
21+
source: Explore Education Statistics
22+
trigger:
23+
branches:
24+
- refs/heads/dev
25+
- refs/heads/test
26+
- refs/heads/master
27+
# This param is helpful for debugging to allow the selection of a particular branch from which to base a deploy from this pipeline.
28+
# This should be removed in the long term in favour of using the "Resources" selection from the "Run pipeline" dialog.
29+
#
30+
# branch: ${{ replace(parameters.buildBranchToDeploy, 'Branch from latest pipeline run', '') }}
31+
1732
variables:
1833
- group: Public API Infrastructure - common
1934
- name: isDev

infrastructure/templates/public-api/application/virtualNetwork.bicep

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,31 @@ param dataProcessorFunctionAppNameSuffix string
1313
@description('Specifies the name suffix of the Container App Environment')
1414
param containerAppEnvironmentNameSuffix string
1515

16-
resource vNet 'Microsoft.Network/virtualNetworks@2023-09-01' existing = {
16+
resource vNet 'Microsoft.Network/virtualNetworks@2023-11-01' existing = {
1717
name: vNetName
1818
}
1919

20-
resource adminSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' existing = {
20+
resource adminSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' existing = {
2121
name: '${subscription}-snet-ees-admin'
2222
parent: vNet
2323
}
2424

25-
resource publisherSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' existing = {
25+
resource publisherSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' existing = {
2626
name: '${subscription}-snet-ees-publisher'
2727
parent: vNet
2828
}
2929

30-
resource dataProcessorSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' existing = {
30+
resource dataProcessorSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' existing = {
3131
name: '${resourcePrefix}-snet-fa-${dataProcessorFunctionAppNameSuffix}'
3232
parent: vNet
3333
}
3434

35-
resource containerAppEnvironmentSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' existing = {
35+
resource containerAppEnvironmentSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' existing = {
3636
name: '${subscription}-ees-snet-cae-${containerAppEnvironmentNameSuffix}'
3737
parent: vNet
3838
}
3939

40-
resource psqlFlexibleServerSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' existing = {
40+
resource psqlFlexibleServerSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' existing = {
4141
name: '${subscription}-ees-snet-psql-flexibleserver'
4242
parent: vNet
4343
}

infrastructure/templates/public-api/components/appServiceSlotConfig.bicep

+27-23
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
@description('Specifies the Web / Function App name that these settings belong to')
22
param appName string
33

4-
@description('Specifies the location of the resources')
5-
param location string
6-
74
@description('Specifies the names of slot settings (settings that stick to their slots rather than swap)')
85
param slotSpecificSettingKeys string[]
96

@@ -16,28 +13,23 @@ param prodOnlySettings object
1613
@description('Specifies a set of appsettings that are specific to the staging slot')
1714
param stagingOnlySettings object
1815

16+
@description('Specifies the name of the staging slot')
17+
param stagingSlotName string = 'staging'
18+
1919
@description('Specifies any existing appsettings from the staging slot')
2020
param existingStagingAppSettings object
2121

2222
@description('Specifies any existing appsettings from the production slot')
2323
param existingProductionAppSettings object
2424

25-
@description('A set of tags with which to tag the resource in Azure')
26-
param tagValues object
27-
28-
@description('Create a staging slot')
29-
resource stagingSlot 'Microsoft.Web/sites/slots@2023-01-01' = {
30-
name: '${appName}/staging'
31-
location: location
32-
identity: {
33-
type: 'SystemAssigned'
34-
}
35-
properties: {
36-
enabled: true
37-
httpsOnly: true
38-
}
39-
tags: tagValues
40-
}
25+
@description('Specifies additional Azure Storage Accounts to make available to the staging slot')
26+
param azureFileShares {
27+
storageName: string
28+
storageAccountKey: string
29+
storageAccountName: string
30+
fileShareName: string
31+
mountPath: string
32+
}[] = []
4133

4234
@description('Set specific appsettings to be slot specific values')
4335
resource functionSlotConfig 'Microsoft.Web/sites/config@2023-01-01' = {
@@ -52,20 +44,32 @@ resource functionSlotConfig 'Microsoft.Web/sites/config@2023-01-01' = {
5244
// infrastructure deploys do not reset appsettings back to original values and cause
5345
// unwanted updates to production appsettings prior to a slot swap deploy process being
5446
// ready to run.
47+
//
48+
// See https://blog.dotnetstudio.nl/posts/2021/04/merge-appsettings-with-bicep.
5549
var combinedStagingSettings = union(commonSettings, stagingOnlySettings, existingStagingAppSettings)
5650
var combinedProductionSettings = union(commonSettings, prodOnlySettings, existingProductionAppSettings)
5751

5852
@description('Set appsettings on the staging slot')
5953
resource appStagingSlotSettings 'Microsoft.Web/sites/slots/config@2023-01-01' = {
60-
name: 'appsettings'
61-
parent: stagingSlot
54+
name: '${appName}/${stagingSlotName}/appsettings'
6255
properties: combinedStagingSettings
6356
}
6457

58+
resource azureStorageAccounts 'Microsoft.Web/sites/slots/config@2021-01-15' = {
59+
name: '${appName}/${stagingSlotName}/azurestorageaccounts'
60+
properties: reduce(azureFileShares, {}, (cur, next) => union(cur, {
61+
'${next.storageName}': {
62+
type: 'AzureFiles'
63+
shareName: next.fileShareName
64+
mountPath: next.mountPath
65+
accountName: next.storageAccountName
66+
accessKey: next.storageAccountKey
67+
}
68+
}))
69+
}
70+
6571
@description('Set appsettings on production slot')
6672
resource appProductionSettings 'Microsoft.Web/sites/config@2023-01-01' = {
6773
name: '${appName}/appsettings'
6874
properties: combinedProductionSettings
6975
}
70-
71-
output stagingSlotPrincipalId string = stagingSlot.identity.principalId

infrastructure/templates/public-api/components/blobStore.bicep

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ param deleteRetentionPolicy int = 7
1010
param storageAccountName string
1111

1212
// Reference an existing Storage Account.
13-
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
13+
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = {
1414
name: storageAccountName
1515
}
1616

17-
resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01' = {
17+
resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2023-04-01' = {
1818
name: blobStoreName
1919
parent: storageAccount
2020
properties: {

infrastructure/templates/public-api/components/containerApp.bicep

+25-8
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,40 @@ param appSettings {
6161
param tagValues object
6262

6363
@description('An existing Managed Identity\'s Resource Id with which to associate this Container App')
64-
param managedIdentityName string
64+
param userAssignedManagedIdentityId string
6565

6666
@description('Id of the owning Container App Environment')
6767
param managedEnvironmentId string
6868

69+
@description('Volumes to mount within Containers - used in conjunction with "volumeMounts"')
70+
param volumes {
71+
name: string
72+
storageType: string
73+
storageName: string
74+
mountOptions: string?
75+
secrets: {
76+
path: string
77+
secretRef: string
78+
}[]?
79+
}[] = []
80+
81+
@description('Volume mount points within Containers - used in conjunction with "volumes"')
82+
param volumeMounts {
83+
mountPath: string
84+
volumeName: string
85+
}[] = []
86+
87+
6988
var containerImageName = '${acrLoginServer}/${containerAppImageName}'
7089
var containerApplicationName = toLower('${resourcePrefix}-ca-${containerAppName}')
7190

72-
resource containerAppIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = {
73-
name: managedIdentityName
74-
}
75-
76-
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
91+
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
7792
name: containerApplicationName
7893
location: location
7994
identity: {
8095
type: 'UserAssigned'
8196
userAssignedIdentities: {
82-
'${containerAppIdentity.id}': {}
97+
'${userAssignedManagedIdentityId}': {}
8398
}
8499
}
85100
properties: {
@@ -101,7 +116,7 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
101116
registries: [
102117
{
103118
server: acrLoginServer
104-
identity: containerAppIdentity.id
119+
identity: userAssignedManagedIdentityId
105120
}
106121
]
107122
}
@@ -115,6 +130,7 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
115130
cpu: json(cpuCore)
116131
memory: '${memorySize}Gi'
117132
}
133+
volumeMounts: volumeMounts
118134
}
119135
]
120136
scale: {
@@ -131,6 +147,7 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
131147
}
132148
]
133149
}
150+
volumes: volumes
134151
}
135152
workloadProfileName: 'Consumption'
136153
}

infrastructure/templates/public-api/components/containerAppEnvironment.bicep

+23-2
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,24 @@ param tagValues object
3131
@description('Specifies a suffix to append to the full name of the Container App Environment')
3232
param containerAppEnvironmentNameSuffix string = ''
3333

34+
@description('Specifies an array of Azure File Shares to be available for Container Apps hosted within this Container App Environment')
35+
param azureFileStorages {
36+
storageName: string
37+
storageAccountKey: string
38+
storageAccountName: string
39+
fileShareName: string
40+
accessMode: 'ReadWrite' | 'ReadOnly'
41+
}[] = []
42+
3443
var containerAppEnvironmentName = empty(containerAppEnvironmentNameSuffix)
3544
? '${subscription}-ees-cae'
3645
: '${subscription}-ees-cae-${containerAppEnvironmentNameSuffix}'
3746

38-
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = {
47+
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = {
3948
name: logAnalyticsWorkspaceName
4049
}
4150

42-
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = {
51+
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' = {
4352
name: containerAppEnvironmentName
4453
location: location
4554
properties: {
@@ -58,6 +67,18 @@ resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2023-05-01'
5867
workloadProfiles: workloadProfiles
5968
}
6069
tags: tagValues
70+
71+
resource azureFileStorage 'storages@2022-03-01' = [for storage in azureFileStorages: {
72+
name: storage.storageName
73+
properties: {
74+
azureFile: {
75+
accountKey: storage.storageAccountKey
76+
accountName: storage.storageAccountName
77+
shareName: storage.fileShareName
78+
accessMode: storage.accessMode
79+
}
80+
}
81+
}]
6182
}
6283

6384
output containerAppEnvironmentName string = containerAppEnvironmentName

infrastructure/templates/public-api/components/fileShares.bicep infrastructure/templates/public-api/components/fileShare.bicep

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ param storageAccountName string
1717
var shareName = '${resourcePrefix}-fs-${fileShareName}'
1818

1919
// Reference an existing Storage Account.
20-
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
20+
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = {
2121
name: storageAccountName
2222
}
2323

24-
resource fileService 'Microsoft.Storage/storageAccounts/fileServices@2023-01-01' = {
24+
resource fileService 'Microsoft.Storage/storageAccounts/fileServices@2023-04-01' = {
2525
name: 'default'
2626
parent: storageAccount
2727
}

0 commit comments

Comments
 (0)