From 669d28afa996d57943aca30ba0bcded955e220fb Mon Sep 17 00:00:00 2001 From: Patrick Hallisey Date: Thu, 27 Jun 2024 13:58:14 -0700 Subject: [PATCH 1/5] Add vnet resources to pipeline witness bicep --- .../bicep/appResourceGroup.bicep | 81 +++++++++++++++++-- .../bicep/logsResourceGroup.bicep | 19 +++-- .../infrastructure/bicep/parameters.test.json | 6 ++ .../infrastructure/bicep/resourceGroups.bicep | 5 ++ 4 files changed, 98 insertions(+), 13 deletions(-) diff --git a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep index 686fa33e48b..732e2d280f3 100644 --- a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep @@ -1,4 +1,6 @@ param webAppName string +param networkSecurityGroupName string +param vnetName string param appServicePlanName string param appStorageAccountName string param cosmosAccountName string @@ -6,6 +8,65 @@ param location string var cosmosContributorRoleId = '00000000-0000-0000-0000-000000000002' // Built-in Contributor role +resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-11-01' = { + name: networkSecurityGroupName + location: 'westus2' + properties: { + securityRules: [] + } +} + +resource vnet 'Microsoft.Network/virtualNetworks@2023-11-01' = { + name: vnetName + location: 'westus2' + properties: { + addressSpace: { + addressPrefixes: [ + '10.8.0.0/16' + ] + } + virtualNetworkPeerings: [] + enableDdosProtection: false + } +} + +resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' = { + parent: vnet + name: 'default' + properties: { + addressPrefix: '10.8.0.0/24' + networkSecurityGroup: { + id: networkSecurityGroup.id + } + serviceEndpoints: [ + { + service: 'Microsoft.Storage' + locations: [ + 'westus2' + 'westcentralus' + ] + } + { + service: 'Microsoft.AzureCosmosDB' + locations: [ + '*' + ] + } + ] + delegations: [ + { + name: 'delegation' + properties: { + serviceName: 'Microsoft.Web/serverfarms' + } + type: 'Microsoft.Network/virtualNetworks/subnets/delegations' + } + ] + privateEndpointNetworkPolicies: 'Disabled' + privateLinkServiceNetworkPolicies: 'Enabled' + } +} + resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = { name: appServicePlanName location: location @@ -28,6 +89,8 @@ resource webApp 'Microsoft.Web/sites@2022-03-01' = { linuxFxVersion: 'DOTNETCORE|6.0' } httpsOnly: true + virtualNetworkSubnetId: subnet.id + publicNetworkAccess: 'Enabled' } identity: { type: 'SystemAssigned' @@ -46,13 +109,12 @@ resource appStorageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { defaultToOAuthAuthentication: false allowCrossTenantReplication: true minimumTlsVersion: 'TLS1_2' - allowBlobPublicAccess: true - allowSharedKeyAccess: true + allowBlobPublicAccess: false + allowSharedKeyAccess: false networkAcls: { bypass: 'AzureServices' - virtualNetworkRules: [] - ipRules: [] - defaultAction: 'Allow' + virtualNetworkRules: [{ id: subnet.id }] + defaultAction: 'Deny' } supportsHttpsTrafficOnly: true encryption: { @@ -120,8 +182,10 @@ resource cosmosAccount 'Microsoft.DocumentDB/databaseAccounts@2024-02-15-preview publicNetworkAccess: 'Enabled' enableAutomaticFailover: false enableMultipleWriteLocations: false - isVirtualNetworkFilterEnabled: false - virtualNetworkRules: [] + isVirtualNetworkFilterEnabled: true + virtualNetworkRules: [{ + id: subnet.id + }] disableKeyBasedMetadataWriteAccess: false enableFreeTier: false enableAnalyticalStorage: false @@ -129,7 +193,7 @@ resource cosmosAccount 'Microsoft.DocumentDB/databaseAccounts@2024-02-15-preview databaseAccountOfferType: 'Standard' enableMaterializedViews: false networkAclBypass: 'None' - disableLocalAuth: false + disableLocalAuth: true enablePartitionMerge: false enablePerRegionPerPartitionAutoscale: false enableBurstCapacity: false @@ -276,3 +340,4 @@ resource sqlRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignm } output appIdentityPrincipalId string = webApp.identity.principalId +output subnetId string = subnet.id diff --git a/tools/pipeline-witness/infrastructure/bicep/logsResourceGroup.bicep b/tools/pipeline-witness/infrastructure/bicep/logsResourceGroup.bicep index 6476c5201c6..e2c85460c5d 100644 --- a/tools/pipeline-witness/infrastructure/bicep/logsResourceGroup.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/logsResourceGroup.bicep @@ -3,6 +3,7 @@ param logsStorageAccountName string param kustoClusterName string param kustoDatabaseName string param webAppName string +param subnetId string param appIdentityPrincipalId string var tables = [ @@ -54,13 +55,12 @@ resource logsStorageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { defaultToOAuthAuthentication: false allowCrossTenantReplication: true minimumTlsVersion: 'TLS1_2' - allowBlobPublicAccess: true - allowSharedKeyAccess: true + allowBlobPublicAccess: false + allowSharedKeyAccess: false networkAcls: { bypass: 'AzureServices' - virtualNetworkRules: [] - ipRules: [] - defaultAction: 'Allow' + virtualNetworkRules: [{ id: subnetId }] + defaultAction: 'Deny' } supportsHttpsTrafficOnly: true encryption: { @@ -180,6 +180,7 @@ resource kustoCluster 'Microsoft.Kusto/Clusters@2022-02-01' = { enableAutoStop: false publicIPType: 'IPv4' } + resource database 'Databases' = { name: kustoDatabaseName location: location @@ -188,6 +189,14 @@ resource kustoCluster 'Microsoft.Kusto/Clusters@2022-02-01' = { hotCachePeriod: 'P31D' } } + + resource managedEndpoint 'managedPrivateEndpoints' = { + name: logsStorageAccountName + properties: { + groupId: 'blob' + privateLinkResourceId: logsStorageAccount.id + } + } } // Resources per table diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.test.json b/tools/pipeline-witness/infrastructure/bicep/parameters.test.json index f9b7dc4b5e7..fbaddd8608d 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.test.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.test.json @@ -31,6 +31,12 @@ }, "kustoDatabaseName": { "value": "test" + }, + "networkSecurityGroupName": { + "value": "pipelinewitnesstest" + }, + "vnetName": { + "value": "pipelinewitnesstest" } } } \ No newline at end of file diff --git a/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep b/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep index c97baad39c5..7ee7505c8ee 100644 --- a/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep @@ -5,6 +5,8 @@ param location string param appResourceGroupName string param appServicePlanName string param webAppName string +param networkSecurityGroupName string +param vnetName string param cosmosAccountName string param appStorageAccountName string @@ -28,6 +30,8 @@ module pipelineWitness 'appResourceGroup.bicep' = { webAppName: webAppName cosmosAccountName: cosmosAccountName appStorageAccountName: appStorageAccountName + networkSecurityGroupName: networkSecurityGroupName + vnetName: vnetName } } @@ -49,5 +53,6 @@ module pipelineLogs 'logsResourceGroup.bicep' = { kustoDatabaseName: kustoDatabaseName webAppName: webAppName appIdentityPrincipalId: pipelineWitness.outputs.appIdentityPrincipalId + subnetId: pipelineWitness.outputs.subnetId } } From 3ec9c1ee1a33a155b72c89860e7b3a4c2d6c8e87 Mon Sep 17 00:00:00 2001 From: Patrick Hallisey Date: Tue, 9 Jul 2024 12:21:20 -0700 Subject: [PATCH 2/5] Add vnet and environment setting to bicep --- .../appsettings.test.json | 7 +++++++ .../infrastructure/bicep/appResourceGroup.bicep | 14 ++++++++++++++ .../infrastructure/bicep/appSettings.bicep | 13 +++++++++++++ .../bicep/parameters.production.json | 3 +++ .../infrastructure/bicep/parameters.staging.json | 3 +++ .../infrastructure/bicep/parameters.test.json | 3 +++ .../infrastructure/bicep/resourceGroups.bicep | 2 ++ 7 files changed, 45 insertions(+) create mode 100644 tools/pipeline-witness/Azure.Sdk.Tools.PipelineWitness/appsettings.test.json create mode 100644 tools/pipeline-witness/infrastructure/bicep/appSettings.bicep diff --git a/tools/pipeline-witness/Azure.Sdk.Tools.PipelineWitness/appsettings.test.json b/tools/pipeline-witness/Azure.Sdk.Tools.PipelineWitness/appsettings.test.json new file mode 100644 index 00000000000..428f706905c --- /dev/null +++ b/tools/pipeline-witness/Azure.Sdk.Tools.PipelineWitness/appsettings.test.json @@ -0,0 +1,7 @@ +{ + "PipelineWitness": { + "QueueStorageAccountUri": "https://pipelinewitnesstest.queue.core.windows.net", + "BlobStorageAccountUri": "https://pipelinelogstest.blob.core.windows.net", + "CosmosAccountUri": "https://pipelinewitnesstest.documents.azure.com" + } +} diff --git a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep index 732e2d280f3..3e8bb52e9d5 100644 --- a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep @@ -3,6 +3,7 @@ param networkSecurityGroupName string param vnetName string param appServicePlanName string param appStorageAccountName string +param aspEnvironment string param cosmosAccountName string param location string @@ -339,5 +340,18 @@ resource sqlRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignm } } +// Use a module to merge the current app settings with the new ones to prevent overwritting the app insights configured settings +module appSettings 'appsettings.bicep' = { + name: '${webAppName}-appsettings' + params: { + webAppName: webApp.name + // Get the current appsettings + currentAppSettings: list(resourceId('Microsoft.Web/sites/config', webApp.name, 'appsettings'), '2022-03-01').properties + appSettings: { + ASPNETCORE_ENVIRONMENT: aspEnvironment + } + } +} + output appIdentityPrincipalId string = webApp.identity.principalId output subnetId string = subnet.id diff --git a/tools/pipeline-witness/infrastructure/bicep/appSettings.bicep b/tools/pipeline-witness/infrastructure/bicep/appSettings.bicep new file mode 100644 index 00000000000..ed51dd88066 --- /dev/null +++ b/tools/pipeline-witness/infrastructure/bicep/appSettings.bicep @@ -0,0 +1,13 @@ +param webAppName string +param appSettings object +param currentAppSettings object + +resource webApp 'Microsoft.Web/sites@2022-03-01' existing = { + name: webAppName +} + +resource siteconfig 'Microsoft.Web/sites/config@2022-03-01' = { + parent: webApp + name: 'appsettings' + properties: union(currentAppSettings, appSettings) +} diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.production.json b/tools/pipeline-witness/infrastructure/bicep/parameters.production.json index 874d2e2fabe..14aefa5acac 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.production.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.production.json @@ -20,6 +20,9 @@ "appStorageAccountName": { "value": "pipelinewitnessprod" }, + "aspEnvironment": { + "value": "production" + }, "logsResourceGroupName": { "value": "pipelinelogs" }, diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json b/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json index b9c1e44f461..e8662ac3a52 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json @@ -20,6 +20,9 @@ "appStorageAccountName": { "value": "pipelinewitnessstaging" }, + "aspEnvironment": { + "value": "staging" + }, "logsResourceGroupName": { "value": "pipelinelogs" }, diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.test.json b/tools/pipeline-witness/infrastructure/bicep/parameters.test.json index fbaddd8608d..ebfac490dc7 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.test.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.test.json @@ -20,6 +20,9 @@ "appStorageAccountName": { "value": "pipelinewitnesstest" }, + "aspEnvironment": { + "value": "test" + }, "logsResourceGroupName": { "value": "pipelinelogstest" }, diff --git a/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep b/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep index 7ee7505c8ee..a0c76732cbf 100644 --- a/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep @@ -9,6 +9,7 @@ param networkSecurityGroupName string param vnetName string param cosmosAccountName string param appStorageAccountName string +param aspEnvironment string param logsResourceGroupName string param logsStorageAccountName string @@ -30,6 +31,7 @@ module pipelineWitness 'appResourceGroup.bicep' = { webAppName: webAppName cosmosAccountName: cosmosAccountName appStorageAccountName: appStorageAccountName + aspEnvironment: aspEnvironment networkSecurityGroupName: networkSecurityGroupName vnetName: vnetName } From 45e1862fa6beeafe0ea7b5c8bbb8a3a07711807e Mon Sep 17 00:00:00 2001 From: Patrick Hallisey Date: Tue, 9 Jul 2024 12:24:24 -0700 Subject: [PATCH 3/5] Add vnet parameters to staging and prod --- .../infrastructure/bicep/parameters.production.json | 6 ++++++ .../infrastructure/bicep/parameters.staging.json | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.production.json b/tools/pipeline-witness/infrastructure/bicep/parameters.production.json index 14aefa5acac..d722a4090c3 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.production.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.production.json @@ -34,6 +34,12 @@ }, "kustoDatabaseName": { "value": "Pipelines" + }, + "networkSecurityGroupName": { + "value": "pipelinewitnessprod" + }, + "vnetName": { + "value": "pipelinewitnessprod" } } } \ No newline at end of file diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json b/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json index e8662ac3a52..3fb27183a7d 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json @@ -34,6 +34,12 @@ }, "kustoDatabaseName": { "value": "Staging" + }, + "networkSecurityGroupName": { + "value": "pipelinewitnessstaging" + }, + "vnetName": { + "value": "pipelinewitnessstaging" } } } \ No newline at end of file From c9bade9b2c8512c12c01608da3fa8dc19e91fa18 Mon Sep 17 00:00:00 2001 From: Patrick Hallisey Date: Tue, 9 Jul 2024 13:45:37 -0700 Subject: [PATCH 4/5] Fix caps in bicep file name --- .../infrastructure/bicep/appResourceGroup.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep index 3e8bb52e9d5..1a5faffd34b 100644 --- a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep @@ -341,7 +341,7 @@ resource sqlRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignm } // Use a module to merge the current app settings with the new ones to prevent overwritting the app insights configured settings -module appSettings 'appsettings.bicep' = { +module appSettings 'appSettings.bicep' = { name: '${webAppName}-appsettings' params: { webAppName: webApp.name From b8fd42f68b528e44b9c7bad533ed9c59d1ec7da0 Mon Sep 17 00:00:00 2001 From: Patrick Hallisey Date: Tue, 9 Jul 2024 15:26:34 -0700 Subject: [PATCH 5/5] Add vnet address space parameters --- .../infrastructure/bicep/appResourceGroup.bicep | 6 ++++-- .../infrastructure/bicep/parameters.production.json | 6 ++++++ .../infrastructure/bicep/parameters.staging.json | 6 ++++++ .../infrastructure/bicep/parameters.test.json | 6 ++++++ .../infrastructure/bicep/resourceGroups.bicep | 4 ++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep index 1a5faffd34b..1ad73a302ac 100644 --- a/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/appResourceGroup.bicep @@ -6,6 +6,8 @@ param appStorageAccountName string param aspEnvironment string param cosmosAccountName string param location string +param vnetPrefix string +param subnetPrefix string var cosmosContributorRoleId = '00000000-0000-0000-0000-000000000002' // Built-in Contributor role @@ -23,7 +25,7 @@ resource vnet 'Microsoft.Network/virtualNetworks@2023-11-01' = { properties: { addressSpace: { addressPrefixes: [ - '10.8.0.0/16' + vnetPrefix ] } virtualNetworkPeerings: [] @@ -35,7 +37,7 @@ resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' = { parent: vnet name: 'default' properties: { - addressPrefix: '10.8.0.0/24' + addressPrefix: subnetPrefix networkSecurityGroup: { id: networkSecurityGroup.id } diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.production.json b/tools/pipeline-witness/infrastructure/bicep/parameters.production.json index d722a4090c3..e20b6bbe45a 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.production.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.production.json @@ -40,6 +40,12 @@ }, "vnetName": { "value": "pipelinewitnessprod" + }, + "vnetPrefix": { + "value": "10.9.0.0/16" + }, + "subnetPrefix": { + "value": "10.9.0.0/24" } } } \ No newline at end of file diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json b/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json index 3fb27183a7d..32342d8c04a 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.staging.json @@ -40,6 +40,12 @@ }, "vnetName": { "value": "pipelinewitnessstaging" + }, + "vnetPrefix": { + "value": "10.8.0.0/16" + }, + "subnetPrefix": { + "value": "10.8.0.0/24" } } } \ No newline at end of file diff --git a/tools/pipeline-witness/infrastructure/bicep/parameters.test.json b/tools/pipeline-witness/infrastructure/bicep/parameters.test.json index ebfac490dc7..b7c356abe23 100644 --- a/tools/pipeline-witness/infrastructure/bicep/parameters.test.json +++ b/tools/pipeline-witness/infrastructure/bicep/parameters.test.json @@ -40,6 +40,12 @@ }, "vnetName": { "value": "pipelinewitnesstest" + }, + "vnetPrefix": { + "value": "10.7.0.0/16" + }, + "subnetPrefix": { + "value": "10.7.0.0/24" } } } \ No newline at end of file diff --git a/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep b/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep index a0c76732cbf..845f495c162 100644 --- a/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep +++ b/tools/pipeline-witness/infrastructure/bicep/resourceGroups.bicep @@ -7,6 +7,8 @@ param appServicePlanName string param webAppName string param networkSecurityGroupName string param vnetName string +param vnetPrefix string +param subnetPrefix string param cosmosAccountName string param appStorageAccountName string param aspEnvironment string @@ -28,6 +30,8 @@ module pipelineWitness 'appResourceGroup.bicep' = { params: { location: location appServicePlanName: appServicePlanName + vnetPrefix: vnetPrefix + subnetPrefix: subnetPrefix webAppName: webAppName cosmosAccountName: cosmosAccountName appStorageAccountName: appStorageAccountName