port arm template to bicep (#1724)

* port template to bicep

* Update src/deployment/azuredeploy.bicep

Co-authored-by: Teo Voinea <58236992+tevoinea@users.noreply.github.com>

* port template to bicep

* adding type annotation

* apply changes from #1679

Co-authored-by: stas <statis@microsoft.com>
Co-authored-by: Teo Voinea <58236992+tevoinea@users.noreply.github.com>
This commit is contained in:
Stas
2022-03-31 08:18:44 -07:00
committed by GitHub
parent a2e87c6158
commit dc354cffe3
5 changed files with 790 additions and 48 deletions

View File

@ -38,7 +38,7 @@ While viewing an open workbook instance:
Each workbook is stored as a serialized JSON string value in
`deployments/workbook-data.json`.
The serialized workbook data will be referenced in `azuredeploy.json` using the
The serialized workbook data will be referenced in `azuredeploy.json` or `azuredeploy.bicep` using the
property in `workbook-data.json`.
The value must be the exact string you copied from the example ARM Template in
@ -47,10 +47,10 @@ the Advanced Editor view.
If adding a new workbook, add a new property and value. If editing a workbook,
overwrite the existing value.
4. Ensure the resource is deployed in `azuredeploy.json`
4. Ensure the resource is deployed in `azuredeploy.json` or `azuredeploy.bicep`
To actually deploy a workbook instance, you must include it as a resource in
`azuredeploy.json`.
`azuredeploy.json` or `azuredeploy.bicep`.
It should be a child resource of the Log Analytics workspace resource
(`Microsoft.Insights/components` component).

View File

@ -18,6 +18,11 @@ There are currently two uses of Managed Identities within OneFuzz:
See [azuredeploy.json](../src/deployment/azuredeploy.json) for the specific
implementation of these role assignments.
or
See [azuredeploy.bicep](../src/deployment/azuredeploy.bicep) for the specific
implementation of these role assignments.
1. VMs created by OneFuzz are created using the Managed Identities without roles
assigned in order to enable the OneFuzz agent running in the VMs to
authenticate to the service itself.

View File

@ -0,0 +1,701 @@
param name string
param owner string
param clientId string
param clientSecret string
param signedExpiry string
param app_func_issuer string
param app_func_audiences array
param multi_tenant_domain string
param location string = resourceGroup().location
@description('Azure monitor workbook definitions.')
param workbookData object
@description('The degree of severity for diagnostics logs.')
@allowed([
'Verbose'
'Information'
'Warning'
'Error'
])
param diagnosticsLogLevel string = 'Verbose'
var suffix = uniqueString(resourceGroup().id)
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 = [
{
suffix: '-vmss'
role: '9980e02c-c2be-4d73-94e8-173b1dc7cf3c' //VirtualMachineContributor
}
{
suffix: '-storage'
role:'17d1049b-9a84-46fb-8f53-869881c3d3ab' //StorageAccountContributor
}
{
suffix: '-network'
role: '4d97b98b-1d4f-4787-a291-c67834d212e7'//NetworkContributor
}
{
suffix: '-logs'
role: '92aaf0da-9dab-42b6-94a3-d43ce8d16293'//LogAnalyticsContributor
}
{
suffix: '-user_managed_identity'
role: 'f1a07417-d97a-45cb-824c-7a7467783830'//ManagedIdentityOperator
}
{
suffix: '-contributor'
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'
]
}
}
]
}
}
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
}
}
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
}
}
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
}
}
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'
}
}
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
}
}
}
}
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
]
}]
// 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: {
name: guid('${resourceGroup().id}${r.suffix}')
properties: {
roleDefinitionId: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/${r.role}'
principalId: reference(pythonFunction.id, pythonFunction.apiVersion, 'Full').identity.principalId
}
dependsOn: [
eventSubscriptions
keyVault
serverFarms
]
}]
// 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' = {
name: guid('${resourceGroup().id}-user_managed_idenity_read_blob')
properties: {
roleDefinitionId: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/${StorageBlobDataReader}'
principalId: reference(scalesetIdentity.id, scalesetIdentity.apiVersion, 'Full').properties.principalId
}
dependsOn: [
eventSubscriptions
keyVault
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
]
location: location
properties: {
source: storageAccount.id
topicType: 'microsoft.storage.storageaccounts'
}
}
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
}
}
}
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}'
}
}
}
parent: pythonFunction
}
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: clientId
openIdIssuer: app_func_issuer
clientSecretSettingName: 'ONEFUZZ_CLIENT_SECRET'
}
validation: {
allowedAudiences: app_func_audiences
}
}
}
}
parent: pythonFunction
}
resource pythonFunction 'Microsoft.Web/sites@2021-03-01' = {
name: name
location: location
kind: 'functionapp,linux'
tags: {
'OWNER': owner
}
identity: {
type: 'SystemAssigned'
}
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'
}
httpsOnly: true
serverFarmId: serverFarms.id
clientAffinityEnabled: true
}
}
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
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 scaleset_identity string = scaleset_identity
output tenant_id string = tenantId

View File

@ -921,31 +921,31 @@
}
],
"outputs": {
"fuzz-storage": {
"fuzz_storage": {
"type": "string",
"value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
},
"fuzz-name": {
"fuzz_name": {
"type": "string",
"value": "[variables('storageAccountName')]"
},
"fuzz-key": {
"fuzz_key": {
"type": "string",
"value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value]"
},
"func-name": {
"func_name": {
"type": "string",
"value": "[variables('storageAccountNameFunc')]"
},
"func-storage": {
"func_storage": {
"type": "string",
"value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc'))]"
},
"func-key": {
"func_key": {
"type": "string",
"value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameFunc')), '2019-06-01').keys[0].value]"
},
"scaleset-identity": {
"scaleset_identity": {
"type": "string",
"value": "[variables('scaleset_identity')]"
},

View File

@ -101,6 +101,31 @@ def gen_guid() -> str:
return str(uuid.uuid4())
def bicep_to_arm(bicep_template: str) -> str:
from azure.cli.core import get_default_cli
az_cli = get_default_cli()
az_cli.invoke(["bicep", "install"])
az_cli.invoke(
[
"bicep",
"build",
"--file",
bicep_template,
"--outfile",
"azuredeploy-bicep.json",
]
)
from importlib import reload
# az_cli hijacks logging, so need to reset it
logging.shutdown()
reload(logging)
global logger
logger = logging.getLogger("deploy")
return "azuredeploy-bicep.json"
class Client:
def __init__(
self,
@ -116,7 +141,7 @@ class Client:
tools: str,
instance_specific: str,
third_party: str,
arm_template: str,
arm_or_bicep_template: str,
workbook_data: str,
create_registration: bool,
migrations: List[str],
@ -129,7 +154,6 @@ class Client:
):
self.subscription_id = subscription_id
self.resource_group = resource_group
self.arm_template = arm_template
self.location = location
self.application_name = application_name
self.owner = owner
@ -158,6 +182,13 @@ class Client:
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
machine = platform.machine()
system = platform.system()
@ -211,37 +242,42 @@ class Client:
client = ResourceManagementClient(
credential, subscription_id=self.get_subscription_id()
)
providers = {x.namespace: x for x in client.providers.list()}
providers = {x.namespace.lower(): x for x in client.providers.list()}
unsupported = []
# we cannot validate site/config resources since they require resource group
# to exist. check_region only validates subscription level resources.
resource_group_level_resources = ["sites/config"]
for resource in arm["resources"]:
namespace, name = resource["type"].split("/", 1)
namespace, name = resource["type"].lower().split("/", 1)
# resource types are in the form of a/b/c....
# only the top two are listed as resource types within providers
name = "/".join(name.split("/")[:2])
if namespace not in providers:
unsupported.append("Unsupported provider: %s" % namespace)
continue
provider = providers[namespace]
resource_types = {x.resource_type: x for x in provider.resource_types}
if name not in resource_types:
unsupported.append(
"Unsupported resource type: %s/%s" % (namespace, name)
)
continue
resource_types = {
x.resource_type.lower(): x for x in provider.resource_types
}
if name not in resource_group_level_resources:
if name not in resource_types:
unsupported.append(
"Unsupported resource type: %s/%s" % (namespace, name)
)
continue
resource_type = resource_types[name]
if (
location not in resource_type.locations
and len(resource_type.locations) > 0
):
unsupported.append(
"%s/%s is unsupported in %s" % (namespace, name, self.location)
)
resource_type = resource_types[name]
if (
location not in resource_type.locations
and len(resource_type.locations) > 0
):
unsupported.append(
"%s/%s is unsupported in %s" % (namespace, name, self.location)
)
if unsupported:
print("The following resources required by onefuzz are not supported:")
@ -605,7 +641,7 @@ class Client:
logger.info("assigning the user managed identity role")
assign_instance_app_role(
self.application_name,
self.results["deploy"]["scaleset-identity"]["value"],
self.results["deploy"]["scaleset_identity"]["value"],
self.get_subscription_id(),
OnefuzzAppRole.ManagedNode,
)
@ -646,15 +682,15 @@ class Client:
def apply_migrations(self) -> None:
logger.info("applying database migrations")
name = self.results["deploy"]["func-name"]["value"]
key = self.results["deploy"]["func-key"]["value"]
name = self.results["deploy"]["func_name"]["value"]
key = self.results["deploy"]["func_key"]["value"]
table_service = TableService(account_name=name, account_key=key)
migrate(table_service, self.migrations)
def set_instance_config(self) -> None:
logger.info("setting instance config")
name = self.results["deploy"]["func-name"]["value"]
key = self.results["deploy"]["func-key"]["value"]
name = self.results["deploy"]["func_name"]["value"]
key = self.results["deploy"]["func_key"]["value"]
tenant = UUID(self.results["deploy"]["tenant_id"]["value"])
table_service = TableService(account_name=name, account_key=key)
@ -747,8 +783,8 @@ class Client:
container_name = "base-config"
blob_name = "instance_id"
account_name = self.results["deploy"]["func-name"]["value"]
key = self.results["deploy"]["func-key"]["value"]
account_name = self.results["deploy"]["func_name"]["value"]
key = self.results["deploy"]["func_key"]["value"]
account_url = "https://%s.blob.core.windows.net" % account_name
client = BlobServiceClient(account_url, credential=key)
if container_name not in [x["name"] for x in client.list_containers()]:
@ -773,8 +809,8 @@ class Client:
container_name = "app-insights"
logger.info("adding appinsight log export")
account_name = self.results["deploy"]["func-name"]["value"]
key = self.results["deploy"]["func-key"]["value"]
account_name = self.results["deploy"]["func_name"]["value"]
key = self.results["deploy"]["func_key"]["value"]
account_url = "https://%s.blob.core.windows.net" % account_name
client = BlobServiceClient(account_url, credential=key)
if container_name not in [x["name"] for x in client.list_containers()]:
@ -833,8 +869,8 @@ class Client:
def upload_tools(self) -> None:
logger.info("uploading tools from %s", self.tools)
account_name = self.results["deploy"]["func-name"]["value"]
key = self.results["deploy"]["func-key"]["value"]
account_name = self.results["deploy"]["func_name"]["value"]
key = self.results["deploy"]["func_key"]["value"]
account_url = "https://%s.blob.core.windows.net" % account_name
client = BlobServiceClient(account_url, credential=key)
if "tools" not in [x["name"] for x in client.list_containers()]:
@ -870,8 +906,8 @@ class Client:
def upload_instance_setup(self) -> None:
logger.info("uploading instance-specific-setup from %s", self.instance_specific)
account_name = self.results["deploy"]["func-name"]["value"]
key = self.results["deploy"]["func-key"]["value"]
account_name = self.results["deploy"]["func_name"]["value"]
key = self.results["deploy"]["func_key"]["value"]
account_url = "https://%s.blob.core.windows.net" % account_name
client = BlobServiceClient(account_url, credential=key)
if "instance-specific-setup" not in [
@ -916,8 +952,8 @@ class Client:
def upload_third_party(self) -> None:
logger.info("uploading third-party tools from %s", self.third_party)
account_name = self.results["deploy"]["fuzz-name"]["value"]
key = self.results["deploy"]["fuzz-key"]["value"]
account_name = self.results["deploy"]["fuzz_name"]["value"]
key = self.results["deploy"]["fuzz_key"]["value"]
account_url = "https://%s.blob.core.windows.net" % account_name
client = BlobServiceClient(account_url, credential=key)
@ -1067,9 +1103,9 @@ def main() -> None:
parser.add_argument("owner")
parser.add_argument("nsg_config")
parser.add_argument(
"--arm-template",
"--arm-or-bicep-template",
type=arg_file,
default="azuredeploy.json",
default="azuredeploy.bicep",
help="(default: %(default)s)",
)
parser.add_argument(
@ -1180,7 +1216,7 @@ def main() -> None:
tools=args.tools,
instance_specific=args.instance_specific,
third_party=args.third_party,
arm_template=args.arm_template,
arm_or_bicep_template=args.arm_or_bicep_template,
workbook_data=args.workbook_data,
create_registration=args.create_pool_registration,
migrations=args.apply_migrations,