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

@ -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,