mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-21 21:54:26 +00:00
Deploy dotnet Azure function alongside Python Azure function (#1733)
Co-authored-by: stas <statis@microsoft.com>
This commit is contained in:
@ -26,7 +26,6 @@ var tenantId = subscription().tenantId
|
|||||||
|
|
||||||
var scaleset_identity = '${name}-scalesetid'
|
var scaleset_identity = '${name}-scalesetid'
|
||||||
|
|
||||||
var telemetry = 'd7a73cf4-5a1a-4030-85e1-e5b25867e45a'
|
|
||||||
var StorageBlobDataReader = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
|
var StorageBlobDataReader = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
|
||||||
|
|
||||||
var roleAssignmentsParams = [
|
var roleAssignmentsParams = [
|
||||||
@ -68,13 +67,49 @@ module serverFarms 'bicep-templates/server-farms.bicep' = {
|
|||||||
location: location
|
location: location
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var keyVaultName = 'of-kv-${uniqueString(resourceGroup().id)}'
|
||||||
|
resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
|
||||||
|
name: keyVaultName
|
||||||
|
location: location
|
||||||
|
properties: {
|
||||||
|
enabledForDiskEncryption: false
|
||||||
|
enabledForTemplateDeployment: true
|
||||||
|
sku: {
|
||||||
|
family: 'A'
|
||||||
|
name: 'standard'
|
||||||
|
}
|
||||||
|
networkAcls: {
|
||||||
|
defaultAction: 'Allow'
|
||||||
|
bypass: 'AzureServices'
|
||||||
|
}
|
||||||
|
accessPolicies: [
|
||||||
|
{
|
||||||
|
objectId: pythonFunction.outputs.principalId
|
||||||
|
tenantId: tenantId
|
||||||
|
permissions: {
|
||||||
|
secrets: [
|
||||||
|
'get'
|
||||||
|
'list'
|
||||||
|
'set'
|
||||||
|
'delete'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
objectId: netFunction.outputs.principalId
|
||||||
|
tenantId: tenantId
|
||||||
|
permissions: {
|
||||||
|
secrets: [
|
||||||
|
'get'
|
||||||
|
'list'
|
||||||
|
'set'
|
||||||
|
'delete'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module keyVaults 'bicep-templates/keyvaults.bicep' = {
|
]
|
||||||
name: 'keyvaults'
|
tenantId: tenantId
|
||||||
params: {
|
|
||||||
location: location
|
|
||||||
principal_id: reference(pythonFunction.id, pythonFunction.apiVersion, 'Full').identity.principalId
|
|
||||||
tenant_id: tenantId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,19 +163,34 @@ module eventGrid 'bicep-templates/event-grid.bicep' = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
||||||
resource roleAssigments 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for r in roleAssignmentsParams: {
|
resource roleAssigmentsPy 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for r in roleAssignmentsParams: {
|
||||||
name: guid('${resourceGroup().id}${r.suffix}')
|
name: guid('${resourceGroup().id}${r.suffix}')
|
||||||
properties: {
|
properties: {
|
||||||
roleDefinitionId: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/${r.role}'
|
roleDefinitionId: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/${r.role}'
|
||||||
principalId: reference(pythonFunction.id, pythonFunction.apiVersion, 'Full').identity.principalId
|
principalId: pythonFunction.outputs.principalId
|
||||||
}
|
}
|
||||||
dependsOn: [
|
dependsOn: [
|
||||||
eventGrid
|
eventGrid
|
||||||
keyVaults
|
keyVault
|
||||||
serverFarms
|
serverFarms
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
||||||
|
resource roleAssigmentsNet 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for r in roleAssignmentsParams: {
|
||||||
|
name: guid('${resourceGroup().id}${r.suffix}-net')
|
||||||
|
properties: {
|
||||||
|
roleDefinitionId: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/${r.role}'
|
||||||
|
principalId: netFunction.outputs.principalId
|
||||||
|
}
|
||||||
|
dependsOn: [
|
||||||
|
eventGrid
|
||||||
|
keyVault
|
||||||
|
serverFarms
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
||||||
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
||||||
resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
|
resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
|
||||||
name: guid('${resourceGroup().id}-user_managed_idenity_read_blob')
|
name: guid('${resourceGroup().id}-user_managed_idenity_read_blob')
|
||||||
@ -150,111 +200,72 @@ resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10
|
|||||||
}
|
}
|
||||||
dependsOn: [
|
dependsOn: [
|
||||||
eventGrid
|
eventGrid
|
||||||
keyVaults
|
keyVault
|
||||||
serverFarms
|
serverFarms
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
resource pythonFunction 'Microsoft.Web/sites@2021-03-01' = {
|
|
||||||
name: name
|
module pythonFunction 'bicep-templates/function.bicep' = {
|
||||||
location: location
|
name: 'pythonFunction'
|
||||||
kind: 'functionapp,linux'
|
params: {
|
||||||
tags: {
|
functions_worker_runtime: 'python'
|
||||||
'OWNER': owner
|
linux_fx_version: 'Python|3.8'
|
||||||
}
|
functions_extension_version: '~3'
|
||||||
identity: {
|
name: name
|
||||||
type: 'SystemAssigned'
|
|
||||||
}
|
app_logs_sas_url: storage.outputs.FuncSasUrlBlobAppLogs
|
||||||
properties: {
|
app_func_audiences: app_func_audiences
|
||||||
siteConfig: {
|
app_func_issuer: app_func_issuer
|
||||||
linuxFxVersion: 'Python|3.8'
|
app_insights_app_id: operationalInsights.outputs.appInsightsAppId
|
||||||
alwaysOn: true
|
app_insights_key: operationalInsights.outputs.appInsightsInstrumentationKey
|
||||||
defaultDocuments: []
|
client_id: clientId
|
||||||
httpLoggingEnabled: true
|
client_secret: clientSecret
|
||||||
logsDirectorySizeLimit: 100
|
diagnostics_log_level: diagnosticsLogLevel
|
||||||
detailedErrorLoggingEnabled: true
|
func_sas_url: storage.outputs.FuncSasUrl
|
||||||
http20Enabled: true
|
func_storage_resource_id: storage.outputs.FuncId
|
||||||
ftpsState: 'Disabled'
|
fuzz_storage_resource_id: storage.outputs.FuzzId
|
||||||
}
|
keyvault_name: keyVaultName
|
||||||
httpsOnly: true
|
location: location
|
||||||
serverFarmId: serverFarms.outputs.id
|
log_retention: log_retention
|
||||||
clientAffinityEnabled: true
|
monitor_account_name: operationalInsights.outputs.monitorAccountName
|
||||||
|
multi_tenant_domain: multi_tenant_domain
|
||||||
|
owner: owner
|
||||||
|
server_farm_id: serverFarms.outputs.id
|
||||||
|
signal_r_connection_string: signalR.outputs.connectionString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource funcAuthSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
module netFunction 'bicep-templates/function.bicep' = {
|
||||||
name: 'authsettingsV2'
|
name: 'netFunction'
|
||||||
properties: {
|
params: {
|
||||||
login:{
|
functions_worker_runtime: 'dotnet-isolated'
|
||||||
tokenStore: {
|
linux_fx_version: 'DOTNET-ISOLATED|6.0'
|
||||||
enabled: true
|
functions_extension_version: '~4'
|
||||||
}
|
name: '${name}-net'
|
||||||
}
|
|
||||||
globalValidation: {
|
app_logs_sas_url: storage.outputs.FuncSasUrlBlobAppLogs
|
||||||
unauthenticatedClientAction: 'RedirectToLoginPage'
|
app_func_audiences: app_func_audiences
|
||||||
requireAuthentication: true
|
app_func_issuer: app_func_issuer
|
||||||
}
|
app_insights_app_id: operationalInsights.outputs.appInsightsAppId
|
||||||
httpSettings: {
|
app_insights_key: operationalInsights.outputs.appInsightsInstrumentationKey
|
||||||
requireHttps: true
|
client_id: clientId
|
||||||
}
|
client_secret: clientSecret
|
||||||
identityProviders: {
|
diagnostics_log_level: diagnosticsLogLevel
|
||||||
azureActiveDirectory: {
|
func_sas_url: storage.outputs.FuncSasUrl
|
||||||
enabled: true
|
func_storage_resource_id: storage.outputs.FuncId
|
||||||
isAutoProvisioned: false
|
fuzz_storage_resource_id: storage.outputs.FuzzId
|
||||||
registration: {
|
keyvault_name: keyVaultName
|
||||||
clientId: clientId
|
location: location
|
||||||
openIdIssuer: app_func_issuer
|
log_retention: log_retention
|
||||||
clientSecretSettingName: 'ONEFUZZ_CLIENT_SECRET'
|
monitor_account_name: operationalInsights.outputs.monitorAccountName
|
||||||
}
|
multi_tenant_domain: multi_tenant_domain
|
||||||
validation: {
|
owner: owner
|
||||||
allowedAudiences: app_func_audiences
|
server_farm_id: serverFarms.outputs.id
|
||||||
}
|
signal_r_connection_string: signalR.outputs.connectionString
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
parent: pythonFunction
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resource funcLogs 'Microsoft.Web/sites/config@2021-03-01' = {
|
|
||||||
name: 'logs'
|
|
||||||
properties: {
|
|
||||||
applicationLogs: {
|
|
||||||
azureBlobStorage: {
|
|
||||||
level: diagnosticsLogLevel
|
|
||||||
retentionInDays: log_retention
|
|
||||||
sasUrl: storage.outputs.FuncSasUrlBlobAppLogs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parent: pythonFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
resource pythonFunctionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
|
||||||
name: 'appsettings'
|
|
||||||
parent: pythonFunction
|
|
||||||
properties: {
|
|
||||||
'FUNCTIONS_EXTENSION_VERSION': '~3'
|
|
||||||
'FUNCTIONS_WORKER_RUNTIME': 'python'
|
|
||||||
'FUNCTIONS_WORKER_PROCESS_COUNT': '1'
|
|
||||||
'APPINSIGHTS_INSTRUMENTATIONKEY': operationalInsights.outputs.appInsightsInstrumentationKey
|
|
||||||
'APPINSIGHTS_APPID': operationalInsights.outputs.appInsightsAppId
|
|
||||||
'ONEFUZZ_TELEMETRY': telemetry
|
|
||||||
'AzureWebJobsStorage': storage.outputs.FuncSasUrl
|
|
||||||
'MULTI_TENANT_DOMAIN': multi_tenant_domain
|
|
||||||
'AzureWebJobsDisableHomepage': 'true'
|
|
||||||
'AzureSignalRConnectionString': signalR.outputs.connectionString
|
|
||||||
'AzureSignalRServiceTransportType': 'Transient'
|
|
||||||
'ONEFUZZ_INSTANCE_NAME': name
|
|
||||||
'ONEFUZZ_INSTANCE': 'https://${name}.azurewebsites.net'
|
|
||||||
'ONEFUZZ_RESOURCE_GROUP': resourceGroup().id
|
|
||||||
'ONEFUZZ_DATA_STORAGE': storage.outputs.FuzzId
|
|
||||||
'ONEFUZZ_FUNC_STORAGE': storage.outputs.FuncId
|
|
||||||
'ONEFUZZ_MONITOR': operationalInsights.outputs.monitorAccountName
|
|
||||||
'ONEFUZZ_KEYVAULT': keyVaults.outputs.name
|
|
||||||
'ONEFUZZ_OWNER': owner
|
|
||||||
'ONEFUZZ_CLIENT_SECRET': clientSecret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output fuzz_storage string = storage.outputs.FuzzId
|
output fuzz_storage string = storage.outputs.FuzzId
|
||||||
output fuzz_name string = storage.outputs.FuzzName
|
output fuzz_name string = storage.outputs.FuzzName
|
||||||
|
152
src/deployment/bicep-templates/function.bicep
Normal file
152
src/deployment/bicep-templates/function.bicep
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
param name string
|
||||||
|
param location string
|
||||||
|
param owner string
|
||||||
|
|
||||||
|
param server_farm_id string
|
||||||
|
param client_id string
|
||||||
|
param app_func_issuer string
|
||||||
|
param app_func_audiences array
|
||||||
|
|
||||||
|
@secure()
|
||||||
|
param app_logs_sas_url string
|
||||||
|
|
||||||
|
param app_insights_app_id string
|
||||||
|
@secure()
|
||||||
|
param app_insights_key string
|
||||||
|
|
||||||
|
@secure()
|
||||||
|
param func_sas_url string
|
||||||
|
|
||||||
|
param multi_tenant_domain string
|
||||||
|
|
||||||
|
@secure()
|
||||||
|
param signal_r_connection_string string
|
||||||
|
|
||||||
|
@description('The degree of severity for diagnostics logs.')
|
||||||
|
@allowed([
|
||||||
|
'Verbose'
|
||||||
|
'Information'
|
||||||
|
'Warning'
|
||||||
|
'Error'
|
||||||
|
])
|
||||||
|
param diagnostics_log_level string
|
||||||
|
param log_retention int
|
||||||
|
|
||||||
|
param func_storage_resource_id string
|
||||||
|
param fuzz_storage_resource_id string
|
||||||
|
|
||||||
|
param keyvault_name string
|
||||||
|
|
||||||
|
@secure()
|
||||||
|
param client_secret string
|
||||||
|
|
||||||
|
param monitor_account_name string
|
||||||
|
|
||||||
|
param linux_fx_version string
|
||||||
|
param functions_worker_runtime string
|
||||||
|
param functions_extension_version string
|
||||||
|
|
||||||
|
var telemetry = 'd7a73cf4-5a1a-4030-85e1-e5b25867e45a'
|
||||||
|
|
||||||
|
resource function 'Microsoft.Web/sites@2021-03-01' = {
|
||||||
|
name: name
|
||||||
|
location: location
|
||||||
|
kind: 'functionapp,linux'
|
||||||
|
tags: {
|
||||||
|
'OWNER': owner
|
||||||
|
}
|
||||||
|
identity: {
|
||||||
|
type: 'SystemAssigned'
|
||||||
|
}
|
||||||
|
properties: {
|
||||||
|
siteConfig: {
|
||||||
|
linuxFxVersion: linux_fx_version
|
||||||
|
alwaysOn: true
|
||||||
|
defaultDocuments: []
|
||||||
|
httpLoggingEnabled: true
|
||||||
|
logsDirectorySizeLimit: 100
|
||||||
|
detailedErrorLoggingEnabled: true
|
||||||
|
http20Enabled: true
|
||||||
|
ftpsState: 'Disabled'
|
||||||
|
}
|
||||||
|
httpsOnly: true
|
||||||
|
serverFarmId: server_farm_id
|
||||||
|
clientAffinityEnabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource funcAuthSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||||
|
name: 'authsettingsV2'
|
||||||
|
properties: {
|
||||||
|
login:{
|
||||||
|
tokenStore: {
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalValidation: {
|
||||||
|
unauthenticatedClientAction: 'RedirectToLoginPage'
|
||||||
|
requireAuthentication: true
|
||||||
|
}
|
||||||
|
httpSettings: {
|
||||||
|
requireHttps: true
|
||||||
|
}
|
||||||
|
identityProviders: {
|
||||||
|
azureActiveDirectory: {
|
||||||
|
enabled: true
|
||||||
|
isAutoProvisioned: false
|
||||||
|
registration: {
|
||||||
|
clientId: client_id
|
||||||
|
openIdIssuer: app_func_issuer
|
||||||
|
clientSecretSettingName: 'ONEFUZZ_CLIENT_SECRET'
|
||||||
|
}
|
||||||
|
validation: {
|
||||||
|
allowedAudiences: app_func_audiences
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent: function
|
||||||
|
}
|
||||||
|
|
||||||
|
resource funcLogs 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||||
|
name: 'logs'
|
||||||
|
properties: {
|
||||||
|
applicationLogs: {
|
||||||
|
azureBlobStorage: {
|
||||||
|
level: diagnostics_log_level
|
||||||
|
retentionInDays: log_retention
|
||||||
|
sasUrl: app_logs_sas_url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent: function
|
||||||
|
}
|
||||||
|
|
||||||
|
resource pythonFunctionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||||
|
name: 'appsettings'
|
||||||
|
parent: function
|
||||||
|
properties: {
|
||||||
|
'FUNCTIONS_EXTENSION_VERSION': functions_extension_version
|
||||||
|
'FUNCTIONS_WORKER_RUNTIME': functions_worker_runtime
|
||||||
|
'FUNCTIONS_WORKER_PROCESS_COUNT': '1'
|
||||||
|
'APPINSIGHTS_INSTRUMENTATIONKEY': app_insights_key
|
||||||
|
'APPINSIGHTS_APPID': app_insights_app_id
|
||||||
|
'ONEFUZZ_TELEMETRY': telemetry
|
||||||
|
'AzureWebJobsStorage': func_sas_url
|
||||||
|
'MULTI_TENANT_DOMAIN': multi_tenant_domain
|
||||||
|
'AzureWebJobsDisableHomepage': 'true'
|
||||||
|
'AzureSignalRConnectionString': signal_r_connection_string
|
||||||
|
'AzureSignalRServiceTransportType': 'Transient'
|
||||||
|
'ONEFUZZ_INSTANCE_NAME': name
|
||||||
|
'ONEFUZZ_INSTANCE': 'https://${name}.azurewebsites.net'
|
||||||
|
'ONEFUZZ_RESOURCE_GROUP': resourceGroup().id
|
||||||
|
'ONEFUZZ_DATA_STORAGE': fuzz_storage_resource_id
|
||||||
|
'ONEFUZZ_FUNC_STORAGE': func_storage_resource_id
|
||||||
|
'ONEFUZZ_MONITOR': monitor_account_name
|
||||||
|
'ONEFUZZ_KEYVAULT': keyvault_name
|
||||||
|
'ONEFUZZ_OWNER': owner
|
||||||
|
'ONEFUZZ_CLIENT_SECRET': client_secret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output principalId string = reference(function.id, function.apiVersion, 'Full').identity.principalId
|
@ -1,39 +0,0 @@
|
|||||||
param tenant_id string
|
|
||||||
param principal_id string
|
|
||||||
param location string
|
|
||||||
|
|
||||||
var keyVaultName = 'of-kv-${uniqueString(resourceGroup().id)}'
|
|
||||||
|
|
||||||
resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
|
|
||||||
name: keyVaultName
|
|
||||||
location: location
|
|
||||||
properties: {
|
|
||||||
enabledForDiskEncryption: false
|
|
||||||
enabledForTemplateDeployment: true
|
|
||||||
sku: {
|
|
||||||
family: 'A'
|
|
||||||
name: 'standard'
|
|
||||||
}
|
|
||||||
networkAcls: {
|
|
||||||
defaultAction: 'Allow'
|
|
||||||
bypass: 'AzureServices'
|
|
||||||
}
|
|
||||||
tenantId: tenant_id
|
|
||||||
accessPolicies: [
|
|
||||||
{
|
|
||||||
objectId: principal_id
|
|
||||||
tenantId: tenant_id
|
|
||||||
permissions: {
|
|
||||||
secrets: [
|
|
||||||
'get'
|
|
||||||
'list'
|
|
||||||
'set'
|
|
||||||
'delete'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output name string = keyVaultName
|
|
@ -24,7 +24,7 @@ var storageAccountFuncContainersParams = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
var storageAccountFuncQueuesParams = [
|
var storageAccountFuncQueuesParams = [
|
||||||
'file-chages'
|
'file-changes'
|
||||||
'task-heartbeat'
|
'task-heartbeat'
|
||||||
'node-heartbeat'
|
'node-heartbeat'
|
||||||
'proxy'
|
'proxy'
|
||||||
|
Reference in New Issue
Block a user