diff --git a/src/deployment/azuredeploy.bicep b/src/deployment/azuredeploy.bicep index ad3e4aff8e..de3c8a2232 100644 --- a/src/deployment/azuredeploy.bicep +++ b/src/deployment/azuredeploy.bicep @@ -21,27 +21,13 @@ param workbookData object ]) param diagnosticsLogLevel string = 'Verbose' -var suffix = uniqueString(resourceGroup().id) +var log_retention = 30 var tenantId = subscription().tenantId -var autoscale_name = 'onefuzz-autoscale-${suffix}' -var log_retention = 30 -var monitorAccountName = name var scaleset_identity = '${name}-scalesetid' -var signalr_name = 'onefuzz-${suffix}' -var storage_account_sas = { - signedExpiry: signedExpiry - signedPermission: 'rwdlacup' - signedResourceTypes: 'sco' - signedServices: 'bfqt' -} -var storageAccountName = 'fuzz${suffix}' -var storageAccountNameFunc = 'func${suffix}' var telemetry = 'd7a73cf4-5a1a-4030-85e1-e5b25867e45a' var StorageBlobDataReader = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' -var keyVaultName = 'of-kv-${suffix}' -var fuzz_blob_topic_name ='fuzz-blob-topic-${suffix}' var roleAssignmentsParams = [ { @@ -69,368 +55,77 @@ var roleAssignmentsParams = [ role: 'b24988ac-6180-42a0-ab88-20f7382dd24c'//Contributor } ] - -var onefuzz = { - severitiesAtMostInfo: [ - { - severity: 'emerg' - } - { - severity: 'alert' - } - { - severity: 'crit' - } - { - severity: 'err' - } - { - severity: 'warning' - } - { - severity: 'notice' - } - { - severity: 'info' - } - ] -} - resource scalesetIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { name: scaleset_identity location: location } -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: tenantId - accessPolicies: [ - { - objectId: reference(resourceId('Microsoft.Web/sites', name), '2019-08-01', 'full').identity.principalId - tenantId: tenantId - permissions: { - secrets: [ - 'get' - 'list' - 'set' - 'delete' - ] - } - } - ] +module serverFarms 'bicep-templates/server-farms.bicep' = { + name: 'server-farms' + params: { + server_farm_name: name + owner: owner + location: location } } -resource serverFarms 'Microsoft.Web/serverfarms@2021-03-01' = { - name: name - location: location - kind: 'linux' - properties: { - reserved: true - } - sku: { - name: 'P2v2' - tier: 'PremiumV2' - family: 'Pv2' - capacity: 1 - } - tags: { - OWNER: owner +module keyVaults 'bicep-templates/keyvaults.bicep' = { + name: 'keyvaults' + params: { + location: location + principal_id: reference(pythonFunction.id, pythonFunction.apiVersion, 'Full').identity.principalId + tenant_id: tenantId } } -resource autoscaleSettings 'Microsoft.Insights/autoscalesettings@2015-04-01' = { - name: autoscale_name - location: location - properties: { - name: autoscale_name - enabled: true - targetResourceUri: serverFarms.id - targetResourceLocation: location - notifications: [] - profiles:[ - { - name: 'Auto scale condition' - capacity: { - default: '1' - maximum: '20' - minimum: '1' - } - rules: [ - { - metricTrigger: { - metricName: 'CpuPercentage' - metricResourceUri: serverFarms.id - operator: 'GreaterThanOrEqual' - statistic: 'Average' - threshold: 20 - timeAggregation: 'Average' - timeGrain: 'PT1M' - timeWindow: 'PT1M' - } - scaleAction: { - cooldown: 'PT1M' - direction: 'Increase' - type: 'ChangeCount' - value: '5' - } - } - { - metricTrigger: { - metricName: 'CpuPercentage' - metricResourceUri: serverFarms.id - operator: 'LessThan' - statistic: 'Average' - threshold: 20 - timeAggregation:'Average' - timeGrain: 'PT1M' - timeWindow: 'PT1M' - } - scaleAction: { - cooldown: 'PT5M' - direction: 'Decrease' - type: 'ChangeCount' - value: '1' - } - } - - ] - } - ] - } - tags: { - OWNER: owner +module signalR 'bicep-templates/signalR.bicep' = { + name: 'signalR' + params: { + location: location } } -var linuxDataSources = [ - { - name: 'syslogDataSourcesKern' - syslogName: 'kern' - kind: 'LinuxSyslog' - } - { - name: 'syslogDataSourcesUser' - syslogName: 'user' - kind: 'LinuxSyslog' - } - { - name: 'syslogDataSourcesCron' - syslogName: 'cron' - kind: 'LinuxSyslog' - } - { - name: 'syslogDataSourcesDaemon' - syslogName: 'daemon' - kind: 'LinuxSyslog' - } -] - -var windowsDataSources = [ - { - name: 'windowsEventSystem' - eventLogName: 'System' - kind: 'WindowsEvent' - } - { - name: 'windowsEventApplication' - eventLogName: 'Application' - kind: 'WindowsEvent' - } -] - -resource insightsMonitorAccount 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { - name: monitorAccountName - location: location - properties: { - sku: { - name: 'PerGB2018' - } - retentionInDays: log_retention - features: { - enableLogAccessUsingOnlyResourcePermissions: true - } - } - resource linux 'dataSources@2020-08-01' = [for d in linuxDataSources : { - name: d.name - kind: d.kind - properties: { - syslogName: d.syslogName - syslogSeverities: onefuzz.severitiesAtMostInfo - } - }] - - resource linuxCollection 'dataSources@2020-08-01' = { - name: 'syslogDataSourceCollection' - kind: 'LinuxSyslogCollection' - properties: { - state: 'Enabled' - } - } - - resource windows 'dataSources@2020-08-01' = [for d in windowsDataSources : { - name: d.name - kind: d.kind - properties: { - eventLogName: d.eventLogName - eventTypes: [ - { - eventType: 'Error' - } - { - eventType: 'Warning' - } - { - eventType: 'Information' - } - ] - } - }] -} - -resource vmInsights 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = { - name: 'VMInsights(${monitorAccountName})' - location: location - dependsOn: [ - insightsMonitorAccount - ] - properties: { - workspaceResourceId: resourceId('Microsoft.OperationalInsights/workspaces', monitorAccountName) - } - plan: { - name: 'VMInsights(${monitorAccountName})' - publisher: 'Microsoft' - product: 'OMSGallery/VMInsights' - promotionCode: '' - } -} - -resource insightsComponents 'Microsoft.Insights/components@2020-02-02' = { - name: name - location: location - kind: '' - properties: { - Application_Type: 'other' - RetentionInDays: log_retention - WorkspaceResourceId: insightsMonitorAccount.id - } - tags: { - OWNER: owner +module storage 'bicep-templates/storageAccounts.bicep' = { + name: 'storage' + params: { + location: location + owner: owner + signedExpiry: signedExpiry } } -resource insightsWorkbooks 'Microsoft.Insights/workbooks@2021-08-01' = { - name: 'df20765c-ed5b-46f9-a47b-20f4aaf7936d' - location: location - kind: 'shared' - properties: { - displayName: 'Libfuzzer Job Dashboard' - serializedData: workbookData.libFuzzerJob - version: '1.0' - sourceId: insightsComponents.id - category: 'tsg' +module autoscaleSettings 'bicep-templates/autoscale-settings.bicep' = { + name: 'autoscaleSettings' + params: { + location: location + server_farm_id: serverFarms.outputs.id + owner: owner } } -var storageAccountFuncContainersParams = [ - 'vm-scripts' - 'repro-scripts' - 'proxy-configs' - 'task-configs' - 'app-logs' -] - -var storageAccountFuncQueuesParams = [ - 'file-chages' - 'task-heartbeat' - 'node-heartbeat' - 'proxy' - 'update-queue' - 'webhooks' - 'signalr-events' -] - -var fileChangesIndex = 0 - -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-08-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - properties: { - supportsHttpsTrafficOnly: true - accessTier: 'Hot' - allowBlobPublicAccess: false - } - tags: { - OWNER: owner - } - - resource blobServices 'blobServices' = { - name: 'default' - properties: { - deleteRetentionPolicy: { - enabled: true - days: 30 - } - } +module operationalInsights 'bicep-templates/operational-insights.bicep' = { + name: 'operational-insights' + params: { + name: name + location: location + log_retention: log_retention + owner: owner + workbookData: workbookData } } -resource storageAccountFunc 'Microsoft.Storage/storageAccounts@2021-08-01' = { - name: storageAccountNameFunc - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - properties: { - supportsHttpsTrafficOnly: true - accessTier: 'Hot' - allowBlobPublicAccess: false - } - tags: { - OWNER: owner +module eventGrid 'bicep-templates/event-grid.bicep' = { + name: 'event-grid' + params:{ + location: location + storageFuzzId: storage.outputs.FuzzId + storageFuncId: storage.outputs.FuncId + fileChangesQueueName: storage.outputs.FileChangesQueueName } - - resource blobServices 'blobServices' = { - name: 'default' - properties: { - deleteRetentionPolicy: { - enabled: true - days: 30 - } - } - } -} - -resource storageAccountFuncQueues 'Microsoft.Storage/storageAccounts/queueServices/queues@2021-08-01' = [for q in storageAccountFuncQueuesParams: { - name: '${storageAccountNameFunc}/default/${q}' - dependsOn: [ - storageAccountFunc - ] -}] - -resource storageAccountFunBlobContainers 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-08-01' = [for c in storageAccountFuncContainersParams: { - name: '${storageAccountNameFunc}/default/${c}' dependsOn: [ - storageAccountFunc + storage ] -}] +} // 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: { @@ -440,8 +135,8 @@ resource roleAssigments 'Microsoft.Authorization/roleAssignments@2020-10-01-prev principalId: reference(pythonFunction.id, pythonFunction.apiVersion, 'Full').identity.principalId } dependsOn: [ - eventSubscriptions - keyVault + eventGrid + keyVaults serverFarms ] }] @@ -454,95 +149,37 @@ resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10 principalId: reference(scalesetIdentity.id, scalesetIdentity.apiVersion, 'Full').properties.principalId } dependsOn: [ - eventSubscriptions - keyVault + eventGrid + keyVaults serverFarms ] } -resource signalR 'Microsoft.SignalRService/signalR@2021-10-01' = { - name: signalr_name - location: location - sku: { - name: 'Standard_S1' - tier: 'Standard' - capacity: 1 - } - properties: { - features: [ - { - flag: 'ServiceMode' - value: 'Serverless' - properties: {} - } - { - flag: 'EnableConnectivityLogs' - value: 'True' - properties: {} - } - { - flag: 'EnableMessagingLogs' - value: 'False' - properties: {} - } - ] - } -} - -resource eventGridSystemTopics 'Microsoft.EventGrid/systemTopics@2021-12-01' = { - name: fuzz_blob_topic_name - dependsOn: [ - storageAccountFuncQueues[fileChangesIndex] - storageAccountFunc - ] +resource pythonFunction 'Microsoft.Web/sites@2021-03-01' = { + name: name location: location - properties: { - source: storageAccount.id - topicType: 'microsoft.storage.storageaccounts' + kind: 'functionapp,linux' + tags: { + 'OWNER': owner } -} - -resource eventSubscriptions 'Microsoft.EventGrid/systemTopics/eventSubscriptions@2021-12-01' = { - name: 'onefuzz1_subscription' - parent: eventGridSystemTopics - dependsOn: [ - storageAccountFuncQueues[fileChangesIndex] - storageAccount - ] - properties: { - destination: { - properties: { - resourceId: storageAccountFunc.id - queueName: storageAccountFuncQueuesParams[fileChangesIndex] - } - endpointType: 'StorageQueue' - } - filter: { - includedEventTypes: [ - 'Microsoft.Storage.BlobCreated' - 'Microsoft.Storage.BlobDeleted' - ] - } - eventDeliverySchema: 'EventGridSchema' - retryPolicy: { - maxDeliveryAttempts: 30 - eventTimeToLiveInMinutes: 1440 - } + identity: { + type: 'SystemAssigned' } -} - -resource funcLogs 'Microsoft.Web/sites/config@2021-03-01' = { - name: 'logs' properties: { - applicationLogs: { - azureBlobStorage: { - level: diagnosticsLogLevel - retentionInDays: log_retention - sasUrl: '${storageAccountFunc.properties.primaryEndpoints.blob}app-logs?${storageAccountFunc.listAccountSas('2021-08-01', storage_account_sas).accountSasToken}' - } + siteConfig: { + linuxFxVersion: 'Python|3.8' + alwaysOn: true + defaultDocuments: [] + httpLoggingEnabled: true + logsDirectorySizeLimit: 100 + detailedErrorLoggingEnabled: true + http20Enabled: true + ftpsState: 'Disabled' } + httpsOnly: true + serverFarmId: serverFarms.outputs.id + clientAffinityEnabled: true } - parent: pythonFunction } resource funcAuthSettings 'Microsoft.Web/sites/config@2021-03-01' = { @@ -578,124 +215,54 @@ resource funcAuthSettings 'Microsoft.Web/sites/config@2021-03-01' = { parent: pythonFunction } -resource pythonFunction 'Microsoft.Web/sites@2021-03-01' = { - name: name - location: location - kind: 'functionapp,linux' - tags: { - 'OWNER': owner - } - identity: { - type: 'SystemAssigned' - } +resource funcLogs 'Microsoft.Web/sites/config@2021-03-01' = { + name: 'logs' properties: { - siteConfig: { - appSettings: [ - { - name: 'FUNCTIONS_EXTENSION_VERSION' - value: '~3' - } - { - name: 'FUNCTIONS_WORKER_RUNTIME' - value: 'python' - } - { - name: 'FUNCTIONS_WORKER_PROCESS_COUNT' - value: '1' - } - { - name: 'APPINSIGHTS_INSTRUMENTATIONKEY' - value: insightsComponents.properties.InstrumentationKey - } - { - name: 'APPINSIGHTS_APPID' - value: insightsComponents.properties.AppId - } - { - name: 'ONEFUZZ_TELEMETRY' - value: telemetry - } - { - name: 'AzureWebJobsStorage' - value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountFunc.name};AccountKey=${storageAccountFunc.listKeys().keys[0].value};EndpointSuffix=core.windows.net' - } - { - name: 'MULTI_TENANT_DOMAIN' - value: multi_tenant_domain - } - { - name: 'AzureWebJobsDisableHomepage' - value: 'true' - } - { - name: 'AzureSignalRConnectionString' - value: signalR.listKeys().primaryConnectionString - } - { - name: 'AzureSignalRServiceTransportType' - value: 'Transient' - } - { - name: 'ONEFUZZ_INSTANCE_NAME' - value: name - } - { - name: 'ONEFUZZ_INSTANCE' - value: 'https://${name}.azurewebsites.net' - } - { - name: 'ONEFUZZ_RESOURCE_GROUP' - value: resourceGroup().id - } - { - name: 'ONEFUZZ_DATA_STORAGE' - value: storageAccount.id - } - { - name: 'ONEFUZZ_FUNC_STORAGE' - value: storageAccountFunc.id - } - { - name: 'ONEFUZZ_MONITOR' - value: monitorAccountName - } - { - name: 'ONEFUZZ_KEYVAULT' - value: keyVaultName - } - { - name: 'ONEFUZZ_OWNER' - value: owner - } - { - name: 'ONEFUZZ_CLIENT_SECRET' - value: clientSecret - } - ] - linuxFxVersion: 'Python|3.8' - alwaysOn: true - defaultDocuments: [] - httpLoggingEnabled: true - logsDirectorySizeLimit: 100 - detailedErrorLoggingEnabled: true - http20Enabled: true - ftpsState: 'Disabled' + applicationLogs: { + azureBlobStorage: { + level: diagnosticsLogLevel + retentionInDays: log_retention + sasUrl: storage.outputs.FuncSasUrlBlobAppLogs + } } - httpsOnly: true - serverFarmId: serverFarms.id - clientAffinityEnabled: true + } + 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 } } -var fuzz_key = storageAccount.listKeys().keys[0].value -output fuzz_storage string = storageAccount.id -output fuzz_name string = storageAccountName -output fuzz_key string = fuzz_key +output fuzz_storage string = storage.outputs.FuzzId +output fuzz_name string = storage.outputs.FuzzName +output fuzz_key string = storage.outputs.FuzzKey -var func_key = storageAccountFunc.listKeys().keys[0].value -output func_storage string = storageAccountFunc.id -output func_name string = storageAccountNameFunc -output func_key string = func_key +output func_storage string = storage.outputs.FuncId +output func_name string = storage.outputs.FuncName +output func_key string = storage.outputs.FuncKey output scaleset_identity string = scaleset_identity output tenant_id string = tenantId diff --git a/src/deployment/azuredeploy.json b/src/deployment/azuredeploy.json deleted file mode 100644 index b839272cbe..0000000000 --- a/src/deployment/azuredeploy.json +++ /dev/null @@ -1,957 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json", - "contentVersion": "1.0.0.0", - "parameters": { - "name": { - "type": "string" - }, - "owner": { - "type": "string" - }, - "clientId": { - "type": "string" - }, - "clientSecret": { - "type": "string" - }, - "signedExpiry": { - "type": "string" - }, - "app_func_issuer": { - "type": "string" - }, - "app_func_audiences": { - "type": "array" - }, - "multi_tenant_domain": { - "type": "string" - }, - "diagnosticsLogsLevel": { - "type": "string", - "defaultValue": "Verbose", - "allowedValues": [ - "Verbose", - "Information", - "Warning", - "Error" - ], - "metadata": { - "description": "The degree of severity for diagnostics logs." - } - }, - "workbookData": { - "type": "object", - "metadata": { - "description": "Azure Monitor workbook definitions." - } - } - }, - "variables": { - "autoscale_name": "[concat('onefuzz-autoscale-', uniquestring(resourceGroup().id))]", - "log_retention": 30, - "appInsightsName": "[parameters('name')]", - "functionAppName": "[parameters('name')]", - "serverFarmName": "[parameters('name')]", - "monitorAccountName": "[parameters('name')]", - "vmInsightsName": "[concat('VMInsights', '(', variables('monitorAccountName'), ')')]", - "scaleset_identity": "[concat(parameters('name'), '-scalesetid')]", - "signalr-name": "[concat('onefuzz-', uniquestring(resourceGroup().id))]", - "storage_account_sas": { - "signedExpiry": "[parameters('signedExpiry')]", - "signedPermission": "rwdlacup", - "signedResourceTypes": "sco", - "signedServices": "bfqt" - }, - "storageAccountName": "[concat('fuzz', uniquestring(resourceGroup().id))]", - "storageAccountNameFunc": "[concat('func', uniquestring(resourceGroup().id))]", - "telemetry": "d7a73cf4-5a1a-4030-85e1-e5b25867e45a", - "Log Analytics Contributor": "92aaf0da-9dab-42b6-94a3-d43ce8d16293", - "Managed Identity Operator": "f1a07417-d97a-45cb-824c-7a7467783830", - "Network Contributor": "4d97b98b-1d4f-4787-a291-c67834d212e7", - "Storage Account Contributor": "17d1049b-9a84-46fb-8f53-869881c3d3ab", - "Virtual Machine Contributor": "9980e02c-c2be-4d73-94e8-173b1dc7cf3c", - "Storage Blob Data Reader": "2a2b9908-6ea1-4ae2-8e65-a410df84e7d1", - "Contributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", - "keyVaultName": "[concat('of-kv-', uniquestring(resourceGroup().id))]", - "fuzz-blob-topic-name": "[concat('fuzz-blob-topic-', uniquestring(resourceGroup().id))]" - }, - "functions": [ - { - "namespace": "onefuzz", - "members": { - "severitiesAtMostInfo": { - "parameters": [], - "output": { - "type": "array", - "value": [ - { - "severity": "emerg" - }, - { - "severity": "alert" - }, - { - "severity": "crit" - }, - { - "severity": "err" - }, - { - "severity": "warning" - }, - { - "severity": "notice" - }, - { - "severity": "info" - } - ] - } - } - } - } - ], - "resources": [ - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "name": "[variables('scaleset_identity')]", - "apiVersion": "2018-11-30", - "location": "[resourceGroup().location]" - }, - { - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2019-09-01", - "name": "[variables('keyVaultName')]", - "location": "[resourceGroup().location]", - "properties": { - "enabledForDiskEncryption": false, - "enabledForTemplateDeployment": true, - "tenantId": "[subscription().tenantId]", - "accessPolicies": [ - { - "objectId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2019-08-01', 'full').identity.principalId]", - "tenantId": "[subscription().tenantId]", - "permissions": { - "secrets": [ - "get", - "list", - "set", - "delete" - ] - } - } - ], - "sku": { - "name": "standard", - "family": "A" - }, - "networkAcls": { - "defaultAction": "Allow", - "bypass": "AzureServices" - } - } - }, - { - "apiVersion": "2018-11-01", - "name": "[variables('functionAppName')]", - "type": "Microsoft.Web/sites", - "kind": "functionapp,linux", - "location": "[resourceGroup().location]", - "tags": { - "OWNER": "[parameters('owner')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.SignalRService/SignalR', variables('signalr-name'))]", - "[resourceId('microsoft.insights/components/', variables('appInsightsName'))]", - "[resourceId('Microsoft.Web/serverFarms', variables('serverFarmName'))]", - "[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]", - "[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountNameFunc'))]" - ], - "identity": { - "type": "SystemAssigned" - }, - "resources": [ - { - "apiVersion": "2018-02-01", - "type": "config", - "name": "logs", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[concat('Microsoft.Web/sites/', variables('functionAppName'))]", - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ], - "properties": { - "applicationLogs": { - "azureBlobStorage": { - "level": "[parameters('diagnosticsLogsLevel')]", - "sasUrl": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountNameFunc'))).primaryEndpoints.blob, 'app-logs', '?', listAccountSas(variables('storageAccountNameFunc'), '2018-02-01', variables('storage_account_sas')).accountSasToken)]", - "retentionInDays": "[variables('log_retention')]" - } - } - } - } - ], - "properties": { - "name": "[variables('functionAppName')]", - "siteConfig": { - "appSettings": [ - { - "name": "FUNCTIONS_EXTENSION_VERSION", - "value": "~3" - }, - { - "name": "FUNCTIONS_WORKER_RUNTIME", - "value": "python" - }, - { - "name": "FUNCTIONS_WORKER_PROCESS_COUNT", - "value": "1" - }, - { - "name": "APPINSIGHTS_INSTRUMENTATIONKEY", - "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2015-05-01').InstrumentationKey]" - }, - { - "name": "APPINSIGHTS_APPID", - "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2015-05-01').AppId]" - }, - { - "name": "ONEFUZZ_TELEMETRY", - "value": "[variables('telemetry')]" - }, - { - "name": "AzureWebJobsStorage", - "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',variables('storageAccountNameFunc'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]" - }, - { - "name": "MULTI_TENANT_DOMAIN", - "value": "[parameters('multi_tenant_domain')]" - }, - { - "name": "AzureWebJobsDisableHomepage", - "value": "true" - }, - { - "name": "AzureSignalRConnectionString", - "value": "[listkeys(resourceId('Microsoft.SignalRService/SignalR', variables('signalr-name')), '2018-10-01').primaryConnectionString]" - }, - { - "name": "AzureSignalRServiceTransportType", - "value": "Transient" - }, - { - "name": "ONEFUZZ_INSTANCE_NAME", - "value": "[parameters('name')]" - }, - { - "name": "ONEFUZZ_INSTANCE", - "value": "[concat('https://', parameters('name'), '.azurewebsites.net')]" - }, - { - "name": "ONEFUZZ_RESOURCE_GROUP", - "value": "[resourceGroup().id]" - }, - { - "name": "ONEFUZZ_DATA_STORAGE", - "value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]" - }, - { - "name": "ONEFUZZ_FUNC_STORAGE", - "value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - }, - { - "name": "ONEFUZZ_MONITOR", - "value": "[variables('monitorAccountName')]" - }, - { - "name": "ONEFUZZ_KEYVAULT", - "value": "[variables('keyVaultName')]" - }, - { - "name": "ONEFUZZ_OWNER", - "value": "[parameters('owner')]" - } - ], - "linuxFxVersion": "Python|3.8", - "alwaysOn": true, - "defaultDocuments": [], - "httpLoggingEnabled": true, - "logsDirectorySizeLimit": 100, - "detailedErrorLoggingEnabled": true, - "http20Enabled": true, - "minTlsVersion": "1.2", - "ftpsState": "Disabled", - "siteAuthSettings": { - "enabled": true, - "unauthenticatedClientAction": "RedirectToLoginPage", - "tokenStoreEnabled": true, - "clientId": "[parameters('clientId')]", - "clientSecret": "[parameters('clientSecret')]", - "issuer": "[parameters('app_func_issuer')]", - "defaultProvider": "AzureActiveDirectory", - "allowedAudiences": "[parameters('app_func_audiences')]", - "isAadAutoProvisioned": false - } - }, - "serverFarmId": "[resourceId('Microsoft.Web/serverFarms', variables('serverFarmName'))]", - "hostingEnvironment": "", - "clientAffinityEnabled": false, - "httpsOnly": true - } - }, - { - "apiVersion": "2018-02-01", - "name": "[variables('serverFarmName')]", - "type": "Microsoft.Web/serverFarms", - "location": "[resourceGroup().location]", - "kind": "linux", - "dependsOn": [], - "properties": { - "name": "[variables('serverFarmName')]", - "reserved": true - }, - "sku": { - "name": "P2v2", - "tier": "PremiumV2", - "size": "P2v2", - "family": "Pv2", - "capacity": 1 - }, - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "apiVersion": "2014-04-01", - "name": "[variables('autoscale_name')]", - "type": "microsoft.insights/autoscalesettings", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Web/serverFarms', variables('serverFarmName'))]" - ], - "properties": { - "name": "[variables('autoscale_name')]", - "enabled": true, - "targetResourceUri": "[resourceId('Microsoft.Web/serverFarms/', variables('serverFarmName'))]", - "profiles": [ - { - "name": "Auto scale condition", - "capacity": { - "minimum": 1, - "maximum": 20, - "default": 1 - }, - "rules": [ - { - "scaleAction": { - "direction": "Increase", - "type": "ChangeCount", - "value": 5, - "cooldown": "PT1M" - }, - "metricTrigger": { - "metricName": "CpuPercentage", - "metricNamespace": "microsoft.web/serverfarms", - "metricResourceUri": "[resourceId('Microsoft.Web/serverFarms/', variables('serverFarmName'))]", - "operator": "GreaterThanOrEqual", - "statistic": "Average", - "threshold": 20, - "timeAggregation": "Average", - "timeGrain": "PT1M", - "timeWindow": "PT1M", - "Dimensions": [], - "dividePerInstance": false - } - }, - { - "scaleAction": { - "direction": "Decrease", - "type": "ChangeCount", - "value": 1, - "cooldown": "PT5M" - }, - "metricTrigger": { - "metricName": "CpuPercentage", - "metricNamespace": "microsoft.web/serverfarms", - "metricResourceUri": "[resourceId('Microsoft.Web/serverFarms/', variables('serverFarmName'))]", - "operator": "LessThan", - "statistic": "Average", - "threshold": 20, - "timeAggregation": "Average", - "timeGrain": "PT1M", - "timeWindow": "PT1M", - "Dimensions": [], - "dividePerInstance": false - } - } - ] - } - ], - "notifications": [], - "targetResourceLocation": "[resourceGroup().location]" - }, - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - - { - "type": "Microsoft.OperationalInsights/workspaces", - "name": "[variables('monitorAccountName')]", - "apiVersion": "2017-03-15-preview", - "location": "[resourceGroup().location]", - "properties": { - "sku": { - "name": "PerGB2018" - }, - "retentionInDays": "[variables('log_retention')]", - "features": { - "searchVersion": 1, - "legacy": 0, - "enableLogAccessUsingOnlyResourcePermissions": true - } - }, - "resources": [ - { - "apiVersion": "2015-11-01-preview", - "location": "[resourceGroup().location]", - "name": "[variables('vmInsightsName')]", - "type": "Microsoft.OperationsManagement/solutions", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "properties": { - "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - }, - "plan": { - "name": "[variables('vmInsightsName')]", - "publisher": "Microsoft", - "product": "[Concat('OMSGallery/', 'VMInsights')]", - "promotionCode": "" - } - }, - { - "apiVersion": "2015-11-01-preview", - "type": "datasources", - "name": "syslogDataSourceKern", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "kind": "LinuxSyslog", - "properties": { - "syslogName": "kern", - "syslogSeverities": "[onefuzz.severitiesAtMostInfo()]" - } - }, - { - "apiVersion": "2015-11-01-preview", - "type": "datasources", - "name": "syslogDataSourceUser", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "kind": "LinuxSyslog", - "properties": { - "syslogName": "user", - "syslogSeverities": "[onefuzz.severitiesAtMostInfo()]" - } - }, - { - "apiVersion": "2015-11-01-preview", - "type": "datasources", - "name": "syslogDataSourceDaemon", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "kind": "LinuxSyslog", - "properties": { - "syslogName": "daemon", - "syslogSeverities": "[onefuzz.severitiesAtMostInfo()]" - } - }, - { - "apiVersion": "2015-11-01-preview", - "type": "datasources", - "name": "syslogDataSourceCron", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "kind": "LinuxSyslog", - "properties": { - "syslogName": "cron", - "syslogSeverities": "[onefuzz.severitiesAtMostInfo()]" - } - }, - { - "apiVersion": "2015-11-01-preview", - "type": "datasources", - "name": "syslogDataSourceCollection", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "kind": "LinuxSyslogCollection", - "properties": { - "state": "Enabled" - } - }, - { - "apiVersion": "2015-11-01-preview", - "type": "datasources", - "name": "windowsEventSystem", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "kind": "WindowsEvent", - "properties": { - "eventLogName": "System", - "eventTypes": [ - { - "eventType": "Error" - }, - { - "eventType": "Warning" - }, - { - "eventType": "Information" - } - ] - } - }, - { - "apiVersion": "2015-11-01-preview", - "type": "datasources", - "name": "windowsEventApplication", - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "kind": "WindowsEvent", - "properties": { - "eventLogName": "Application", - "eventTypes": [ - { - "eventType": "Error" - }, - { - "eventType": "Warning" - }, - { - "eventType": "Information" - } - ] - } - } - ] - }, - - { - "apiVersion": "2020-02-02-preview", - "name": "[variables('appInsightsName')]", - "type": "microsoft.insights/components", - "location": "[resourceGroup().location]", - "kind": "", - "properties": { - "ApplicationId": "[variables('appInsightsName')]", - "Application_Type": "other", - "RetentionInDays": "[variables('log_retention')]", - "WorkspaceResourceId" : "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - }, - "tags": { - "OWNER": "[parameters('owner')]" - }, - "dependsOn" : [ - "[resourceId('Microsoft.OperationalInsights/workspaces', variables('monitorAccountName'))]" - ], - "resources": [ - { - "name": "df20765c-ed5b-46f9-a47b-20f4aaf7936d", - "type": "microsoft.insights/workbooks", - "location": "[resourceGroup().location]", - "apiVersion": "2018-06-17-preview", - "dependsOn": [ - "[resourceId('microsoft.insights/components', variables('appInsightsName'))]" - ], - "kind": "shared", - "properties": { - "displayName": "LibFuzzer Job Dashboard", - "serializedData": "[parameters('workbookData').libFuzzerJob]", - "version": "1.0", - "sourceId": "[resourceId('microsoft.insights/components', variables('appInsightsName'))]", - "category": "tsg" - } - } - ] - }, - - { - "apiVersion": "2019-06-01", - "type": "Microsoft.Storage/storageAccounts", - "name": "[variables('storageAccountName')]", - "location": "[resourceGroup().location]", - "kind": "StorageV2", - "sku": { - "name": "Standard_LRS", - "tier": "Standard" - }, - "properties": { - "supportsHttpsTrafficOnly": true, - "accessTier": "Hot", - "allowBlobPublicAccess": false - }, - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "apiVersion": "2019-06-01", - "type": "Microsoft.Storage/storageAccounts", - "name": "[variables('storageAccountNameFunc')]", - "location": "[resourceGroup().location]", - "kind": "StorageV2", - "sku": { - "name": "Standard_LRS", - "tier": "Standard" - }, - "properties": { - "supportsHttpsTrafficOnly": true, - "accessTier": "Hot", - "allowBlobPublicAccess": false - }, - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default')]", - "type": "Microsoft.Storage/storageAccounts/blobServices", - "apiVersion": "2019-06-01", - "properties": { - "deleteRetentionPolicy": { - "enabled": true, - "days": 30 - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountName'), '/default')]", - "type": "Microsoft.Storage/storageAccounts/blobServices", - "apiVersion": "2019-06-01", - "properties": { - "deleteRetentionPolicy": { - "enabled": true, - "days": 30 - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]" - ] - }, - { - "type": "Microsoft.Storage/storageAccounts/blobServices/containers", - "apiVersion": "2018-03-01-preview", - "name": "[concat(variables('storageAccountNameFunc'), '/default/', 'vm-scripts')]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "type": "Microsoft.Storage/storageAccounts/blobServices/containers", - "apiVersion": "2018-03-01-preview", - "name": "[concat(variables('storageAccountNameFunc'), '/default/', 'repro-scripts')]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "type": "Microsoft.Storage/storageAccounts/blobServices/containers", - "apiVersion": "2018-03-01-preview", - "name": "[concat(variables('storageAccountNameFunc'), '/default/', 'proxy-configs')]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "type": "Microsoft.Storage/storageAccounts/blobServices/containers", - "apiVersion": "2018-03-01-preview", - "name": "[concat(variables('storageAccountNameFunc'), '/default/', 'task-configs')]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "type": "Microsoft.Storage/storageAccounts/blobServices/containers", - "apiVersion": "2018-03-01-preview", - "name": "[concat(variables('storageAccountNameFunc'), '/default/', 'app-logs')]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default/file-changes')]", - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2019-06-01", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default/task-heartbeat')]", - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2019-06-01", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default/node-heartbeat')]", - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2019-06-01", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default/proxy')]", - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2019-06-01", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default/update-queue')]", - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2019-06-01", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default/webhooks')]", - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2019-06-01", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "name": "[concat(variables('storageAccountNameFunc'), '/default/signalr-events')]", - "type": "Microsoft.Storage/storageAccounts/queueServices/queues", - "apiVersion": "2019-06-01", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2017-09-01", - "name": "[guid(concat(resourceGroup().id, '-vmss'))]", - "properties": { - "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Virtual Machine Contributor'))]", - "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2018-02-01', 'Full').identity.principalId]" - }, - "DependsOn": [ - "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]" - ], - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2017-09-01", - "name": "[guid(concat(resourceGroup().id, '-storage'))]", - "properties": { - "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Storage Account Contributor'))]", - "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2018-02-01', 'Full').identity.principalId]" - }, - "DependsOn": [ - "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]" - ], - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2017-09-01", - "name": "[guid(concat(resourceGroup().id, '-network'))]", - "properties": { - "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Network Contributor'))]", - "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2018-02-01', 'Full').identity.principalId]" - }, - "DependsOn": [ - "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]" - ], - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2017-09-01", - "name": "[guid(concat(resourceGroup().id, '-logs'))]", - "properties": { - "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Log Analytics Contributor'))]", - "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2018-02-01', 'Full').identity.principalId]" - }, - "DependsOn": [ - "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]" - ], - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2017-09-01", - "name": "[guid(concat(resourceGroup().id, '-user_managed_idenity'))]", - "properties": { - "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Managed Identity Operator'))]", - "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2018-02-01', 'Full').identity.principalId]" - }, - "DependsOn": [ - "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]" - ], - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2017-09-01", - "name": "[guid(concat(resourceGroup().id, '-contributor'))]", - "properties": { - "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Contributor'))]", - "principalId": "[reference(resourceId('Microsoft.Web/sites', parameters('name')), '2018-02-01', 'Full').identity.principalId]" - }, - "DependsOn": [ - "[resourceId('Microsoft.Web/sites', parameters('name'))]" - ], - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2018-07-01", - "name": "[guid(concat(resourceGroup().id, '-user_managed_idenity_read_blob'))]", - "properties": { - "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('Storage Blob Data Reader'))]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('scaleset_identity')), '2018-11-30', 'Full').properties.principalId]" - }, - "DependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - ], - "tags": { - "OWNER": "[parameters('owner')]" - } - }, - { - "type": "Microsoft.SignalRService/SignalR", - "apiVersion": "2018-10-01", - "name": "[variables('signalr-name')]", - "location": "[resourceGroup().location]", - "sku": { - "name": "Standard_S1", - "tier": "Standard", - "size": "S1", - "capacity": 1 - }, - "properties": { - "hostNamePrefix": "[variables('signalr-name')]", - "features": [ - { - "flag": "ServiceMode", - "value": "Serverless", - "properties": {} - }, - { - "flag": "EnableConnectivityLogs", - "value": "True", - "properties": {} - }, - { - "flag": "EnableMessagingLogs", - "value": "False", - "properties": {} - } - ] - } - }, - { - "type": "Microsoft.EventGrid/systemTopics", - "apiVersion": "2021-12-01", - "name": "[variables('fuzz-blob-topic-name')]", - "location": "[resourceGroup().location]", - "properties": { - "source": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]", - "topicType": "microsoft.storage.storageaccounts" - } - }, - { - "type": "Microsoft.EventGrid/systemTopics/eventSubscriptions", - "apiVersion": "2021-12-01", - "name": "[concat(variables('fuzz-blob-topic-name'), '/onefuzz1_subscription')]", - "dependsOn": [ - "[resourceId('Microsoft.EventGrid/systemTopics', variables('fuzz-blob-topic-name'))]" - ], - "properties": { - "destination": { - "properties": { - "resourceId": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]", - "queueName": "file-changes" - }, - "endpointType": "StorageQueue" - }, - "filter": { - "includedEventTypes": [ - "Microsoft.Storage.BlobCreated", - "Microsoft.Storage.BlobDeleted" - ] - }, - "eventDeliverySchema": "EventGridSchema", - "retryPolicy": { - "maxDeliveryAttempts": 30, - "eventTimeToLiveInMinutes": 1440 - } - } - } - ], - "outputs": { - "fuzz_storage": { - "type": "string", - "value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]" - }, - "fuzz_name": { - "type": "string", - "value": "[variables('storageAccountName')]" - }, - "fuzz_key": { - "type": "string", - "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value]" - }, - "func_name": { - "type": "string", - "value": "[variables('storageAccountNameFunc')]" - }, - "func_storage": { - "type": "string", - "value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]" - }, - "func_key": { - "type": "string", - "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc')), '2019-06-01').keys[0].value]" - }, - "scaleset_identity": { - "type": "string", - "value": "[variables('scaleset_identity')]" - }, - "tenant_id": { - "type": "string", - "value": "[subscription().tenantId]" - } - } -} \ No newline at end of file diff --git a/src/deployment/bicep-templates/autoscale-settings.bicep b/src/deployment/bicep-templates/autoscale-settings.bicep new file mode 100644 index 0000000000..01b8c60b8d --- /dev/null +++ b/src/deployment/bicep-templates/autoscale-settings.bicep @@ -0,0 +1,69 @@ +param location string +param server_farm_id string +param owner string + +var autoscale_name = 'onefuzz-autoscale-${uniqueString(resourceGroup().id)}' + +resource autoscaleSettings 'Microsoft.Insights/autoscalesettings@2015-04-01' = { + name: autoscale_name + location: location + properties: { + name: autoscale_name + enabled: true + targetResourceUri: server_farm_id + targetResourceLocation: location + notifications: [] + profiles:[ + { + name: 'Auto scale condition' + capacity: { + default: '1' + maximum: '20' + minimum: '1' + } + rules: [ + { + metricTrigger: { + metricName: 'CpuPercentage' + metricResourceUri: server_farm_id + operator: 'GreaterThanOrEqual' + statistic: 'Average' + threshold: 20 + timeAggregation: 'Average' + timeGrain: 'PT1M' + timeWindow: 'PT1M' + } + scaleAction: { + cooldown: 'PT1M' + direction: 'Increase' + type: 'ChangeCount' + value: '5' + } + } + { + metricTrigger: { + metricName: 'CpuPercentage' + metricResourceUri: server_farm_id + operator: 'LessThan' + statistic: 'Average' + threshold: 20 + timeAggregation:'Average' + timeGrain: 'PT1M' + timeWindow: 'PT1M' + } + scaleAction: { + cooldown: 'PT5M' + direction: 'Decrease' + type: 'ChangeCount' + value: '1' + } + } + + ] + } + ] + } + tags: { + OWNER: owner + } +} diff --git a/src/deployment/bicep-templates/event-grid.bicep b/src/deployment/bicep-templates/event-grid.bicep new file mode 100644 index 0000000000..447478305d --- /dev/null +++ b/src/deployment/bicep-templates/event-grid.bicep @@ -0,0 +1,41 @@ +param location string +param storageFuzzId string +param storageFuncId string +param fileChangesQueueName string + +var suffix = uniqueString(resourceGroup().id) +var fuzz_blob_topic_name ='fuzz-blob-topic-${suffix}' + +resource eventGridSystemTopics 'Microsoft.EventGrid/systemTopics@2021-12-01' = { + name: fuzz_blob_topic_name + location: location + properties: { + source: storageFuzzId + topicType: 'microsoft.storage.storageaccounts' + } +} + +resource eventSubscriptions 'Microsoft.EventGrid/systemTopics/eventSubscriptions@2021-12-01' = { + name: 'onefuzz1_subscription' + parent: eventGridSystemTopics + properties: { + destination: { + properties: { + resourceId: storageFuncId + queueName: fileChangesQueueName + } + endpointType: 'StorageQueue' + } + filter: { + includedEventTypes: [ + 'Microsoft.Storage.BlobCreated' + 'Microsoft.Storage.BlobDeleted' + ] + } + eventDeliverySchema: 'EventGridSchema' + retryPolicy: { + maxDeliveryAttempts: 30 + eventTimeToLiveInMinutes: 1440 + } + } +} diff --git a/src/deployment/bicep-templates/keyvaults.bicep b/src/deployment/bicep-templates/keyvaults.bicep new file mode 100644 index 0000000000..09c1e4aaa3 --- /dev/null +++ b/src/deployment/bicep-templates/keyvaults.bicep @@ -0,0 +1,39 @@ +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 diff --git a/src/deployment/bicep-templates/operational-insights.bicep b/src/deployment/bicep-templates/operational-insights.bicep new file mode 100644 index 0000000000..108671b675 --- /dev/null +++ b/src/deployment/bicep-templates/operational-insights.bicep @@ -0,0 +1,167 @@ +param name string +param location string +param log_retention int +param owner string +param workbookData object + +var monitorAccountName = name + +var linuxDataSources = [ + { + name: 'syslogDataSourcesKern' + syslogName: 'kern' + kind: 'LinuxSyslog' + } + { + name: 'syslogDataSourcesUser' + syslogName: 'user' + kind: 'LinuxSyslog' + } + { + name: 'syslogDataSourcesCron' + syslogName: 'cron' + kind: 'LinuxSyslog' + } + { + name: 'syslogDataSourcesDaemon' + syslogName: 'daemon' + kind: 'LinuxSyslog' + } +] + +var windowsDataSources = [ + { + name: 'windowsEventSystem' + eventLogName: 'System' + kind: 'WindowsEvent' + } + { + name: 'windowsEventApplication' + eventLogName: 'Application' + kind: 'WindowsEvent' + } +] + +var onefuzz = { + severitiesAtMostInfo: [ + { + severity: 'emerg' + } + { + severity: 'alert' + } + { + severity: 'crit' + } + { + severity: 'err' + } + { + severity: 'warning' + } + { + severity: 'notice' + } + { + severity: 'info' + } + ] +} + + +resource insightsMonitorAccount 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { + name: monitorAccountName + location: location + properties: { + sku: { + name: 'PerGB2018' + } + retentionInDays: log_retention + features: { + enableLogAccessUsingOnlyResourcePermissions: true + } + } + resource linux 'dataSources@2020-08-01' = [for d in linuxDataSources : { + name: d.name + kind: d.kind + properties: { + syslogName: d.syslogName + syslogSeverities: onefuzz.severitiesAtMostInfo + } + }] + + resource linuxCollection 'dataSources@2020-08-01' = { + name: 'syslogDataSourceCollection' + kind: 'LinuxSyslogCollection' + properties: { + state: 'Enabled' + } + } + + resource windows 'dataSources@2020-08-01' = [for d in windowsDataSources : { + name: d.name + kind: d.kind + properties: { + eventLogName: d.eventLogName + eventTypes: [ + { + eventType: 'Error' + } + { + eventType: 'Warning' + } + { + eventType: 'Information' + } + ] + } + }] +} + +resource vmInsights 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = { + name: 'VMInsights(${monitorAccountName})' + location: location + dependsOn: [ + insightsMonitorAccount + ] + properties: { + workspaceResourceId: resourceId('Microsoft.OperationalInsights/workspaces', monitorAccountName) + } + plan: { + name: 'VMInsights(${monitorAccountName})' + publisher: 'Microsoft' + product: 'OMSGallery/VMInsights' + promotionCode: '' + } +} + +resource insightsComponents 'Microsoft.Insights/components@2020-02-02' = { + name: name + location: location + kind: '' + properties: { + Application_Type: 'other' + RetentionInDays: log_retention + WorkspaceResourceId: insightsMonitorAccount.id + } + tags: { + OWNER: owner + } +} + +resource insightsWorkbooks 'Microsoft.Insights/workbooks@2021-08-01' = { + name: 'df20765c-ed5b-46f9-a47b-20f4aaf7936d' + location: location + kind: 'shared' + properties: { + displayName: 'Libfuzzer Job Dashboard' + serializedData: workbookData.libFuzzerJob + version: '1.0' + sourceId: insightsComponents.id + category: 'tsg' + } +} + +output monitorAccountName string = monitorAccountName +output appInsightsAppId string = insightsComponents.properties.AppId +output appInsightsInstrumentationKey string = insightsComponents.properties.InstrumentationKey diff --git a/src/deployment/bicep-templates/server-farms.bicep b/src/deployment/bicep-templates/server-farms.bicep new file mode 100644 index 0000000000..b4453832e1 --- /dev/null +++ b/src/deployment/bicep-templates/server-farms.bicep @@ -0,0 +1,24 @@ +param server_farm_name string +param owner string +param location string + +resource serverFarms 'Microsoft.Web/serverfarms@2021-03-01' = { + name: server_farm_name + location: location + kind: 'linux' + properties: { + reserved: true + } + sku: { + name: 'P2v2' + tier: 'PremiumV2' + family: 'Pv2' + capacity: 1 + } + tags: { + OWNER: owner + } +} + + +output id string = serverFarms.id diff --git a/src/deployment/bicep-templates/signalR.bicep b/src/deployment/bicep-templates/signalR.bicep new file mode 100644 index 0000000000..b054f7ed12 --- /dev/null +++ b/src/deployment/bicep-templates/signalR.bicep @@ -0,0 +1,34 @@ +param location string + +var signalr_name = 'onefuzz-${uniqueString(resourceGroup().id)}' +resource signalR 'Microsoft.SignalRService/signalR@2021-10-01' = { + name: signalr_name + location: location + sku: { + name: 'Standard_S1' + tier: 'Standard' + capacity: 1 + } + properties: { + features: [ + { + flag: 'ServiceMode' + value: 'Serverless' + properties: {} + } + { + flag: 'EnableConnectivityLogs' + value: 'True' + properties: {} + } + { + flag: 'EnableMessagingLogs' + value: 'False' + properties: {} + } + ] + } +} + +var connectionString = signalR.listKeys().primaryConnectionString +output connectionString string = connectionString diff --git a/src/deployment/bicep-templates/storageAccounts.bicep b/src/deployment/bicep-templates/storageAccounts.bicep new file mode 100644 index 0000000000..619f3c020d --- /dev/null +++ b/src/deployment/bicep-templates/storageAccounts.bicep @@ -0,0 +1,122 @@ +param owner string +param location string +param signedExpiry string + +var suffix = uniqueString(resourceGroup().id) +var storageAccountNameFuzz = 'fuzz${suffix}' +var storageAccountNameFunc = 'func${suffix}' + + +var storage_account_sas = { + signedExpiry: signedExpiry + signedPermission: 'rwdlacup' + signedResourceTypes: 'sco' + signedServices: 'bfqt' +} + + +var storageAccountFuncContainersParams = [ + 'vm-scripts' + 'repro-scripts' + 'proxy-configs' + 'task-configs' + 'app-logs' +] + +var storageAccountFuncQueuesParams = [ + 'file-chages' + 'task-heartbeat' + 'node-heartbeat' + 'proxy' + 'update-queue' + 'webhooks' + 'signalr-events' +] +var fileChangesQueueIndex = 0 + +resource storageAccountFuzz 'Microsoft.Storage/storageAccounts@2021-08-01' = { + name: storageAccountNameFuzz + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + supportsHttpsTrafficOnly: true + accessTier: 'Hot' + allowBlobPublicAccess: false + } + tags: { + OWNER: owner + } + + resource blobServices 'blobServices' = { + name: 'default' + properties: { + deleteRetentionPolicy: { + enabled: true + days: 30 + } + } + } +} + +resource storageAccountFunc 'Microsoft.Storage/storageAccounts@2021-08-01' = { + name: storageAccountNameFunc + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + supportsHttpsTrafficOnly: true + accessTier: 'Hot' + allowBlobPublicAccess: false + } + tags: { + OWNER: owner + } + + resource blobServices 'blobServices' = { + name: 'default' + properties: { + deleteRetentionPolicy: { + enabled: true + days: 30 + } + } + } +} + +resource storageAccountFuncQueues 'Microsoft.Storage/storageAccounts/queueServices/queues@2021-08-01' = [for q in storageAccountFuncQueuesParams: { + name: '${storageAccountNameFunc}/default/${q}' + dependsOn: [ + storageAccountFunc + ] +}] + +resource storageAccountFunBlobContainers 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-08-01' = [for c in storageAccountFuncContainersParams: { + name: '${storageAccountNameFunc}/default/${c}' + dependsOn: [ + storageAccountFunc + ] +}] + +output FuzzName string = storageAccountNameFuzz +output FuncName string = storageAccountNameFunc + +output FuzzId string = storageAccountFuzz.id +output FuncId string = storageAccountFunc.id + +output FileChangesQueueName string = storageAccountFuncQueuesParams[fileChangesQueueIndex] + +var sas = storageAccountFunc.listAccountSas('2021-08-01', storage_account_sas) +output FuncSasUrlBlobAppLogs string = '${storageAccountFunc.properties.primaryEndpoints.blob}app-logs?${sas.accountSasToken}' + +var fuzz_key = storageAccountFuzz.listKeys().keys[0].value +output FuzzKey string = fuzz_key + +var func_key = storageAccountFunc.listKeys().keys[0].value +output FuncKey string = func_key + +output FuncSasUrl string = 'DefaultEndpointsProtocol=https;AccountName=${storageAccountFunc.name};AccountKey=${func_key};EndpointSuffix=core.windows.net' diff --git a/src/deployment/deploy.py b/src/deployment/deploy.py index 0652162af9..cb5e6b3df2 100644 --- a/src/deployment/deploy.py +++ b/src/deployment/deploy.py @@ -141,7 +141,7 @@ def __init__( tools: str, instance_specific: str, third_party: str, - arm_or_bicep_template: str, + bicep_template: str, workbook_data: str, create_registration: bool, migrations: List[str], @@ -182,12 +182,7 @@ def __init__( self.admins = admins self.allowed_aad_tenants = allowed_aad_tenants - if arm_or_bicep_template: - file_name, file_extension = os.path.splitext(arm_or_bicep_template) - if file_extension == ".bicep": - self.arm_template = bicep_to_arm(arm_or_bicep_template) - else: - self.arm_template = arm_or_bicep_template + self.arm_template = bicep_to_arm(bicep_template) machine = platform.machine() system = platform.system() @@ -1103,7 +1098,7 @@ def main() -> None: parser.add_argument("owner") parser.add_argument("nsg_config") parser.add_argument( - "--arm-or-bicep-template", + "--bicep-template", type=arg_file, default="azuredeploy.bicep", help="(default: %(default)s)", @@ -1216,7 +1211,7 @@ def main() -> None: tools=args.tools, instance_specific=args.instance_specific, third_party=args.third_party, - arm_or_bicep_template=args.arm_or_bicep_template, + bicep_template=args.bicep_template, workbook_data=args.workbook_data, create_registration=args.create_pool_registration, migrations=args.apply_migrations,