Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

adding function app settings bicep template and updating deploy.py #1973

5 changes: 5 additions & 0 deletions src/deployment/azuredeploy.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ param diagnosticsLogLevel string = 'Verbose'
var log_retention = 30
var tenantId = subscription().tenantId

var python_functions_disabled = '0'
var dotnet_functions_disabled = '1'
stishkin marked this conversation as resolved.
Show resolved Hide resolved

var scaleset_identity = '${name}-scalesetid'

var StorageBlobDataReader = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
Expand Down Expand Up @@ -261,6 +264,7 @@ module pythonFunctionSettings 'bicep-templates/function-settings.bicep' = {
keyvault_name: keyVaultName
monitor_account_name: operationalInsights.outputs.monitorAccountName
multi_tenant_domain: multi_tenant_domain
functions_disabled: python_functions_disabled
}
dependsOn: [
pythonFunction
Expand All @@ -286,6 +290,7 @@ module netFunctionSettings 'bicep-templates/function-settings.bicep' = {
keyvault_name: keyVaultName
monitor_account_name: operationalInsights.outputs.monitorAccountName
multi_tenant_domain: multi_tenant_domain
functions_disabled: dotnet_functions_disabled
}
dependsOn: [
netFunction
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
param functions_disabled_setting string

var allFunctions = [
'agent_can_schedule' //0
AdamL-Microsoft marked this conversation as resolved.
Show resolved Hide resolved
'agent_commands' //1
'agent_events' //2
'agent_registration' //3
'containers' //4
'download' //5
'info' //6
'instance_config' //7
'jobs' //8
'job_templates' //9
'job_templates_manage' //10
'negotiate' //11
'node' //12
'node_add_ssh_key' //13
'notifications' //14
'pool' //15
'proxy' //16
'queue_file_changes' //17
'queue_node_heartbeat' //18
'queue_proxy_update' //19
'queue_signalr_events' //20
'queue_task_heartbeat' //21
'queue_updates' //22
'queue_webhooks' //23
'repro_vms' //24
'scaleset' //25
'tasks' //26
'timer_daily' //27
'timer_proxy' //28
'timer_repro' //29
'timer_retention' //30
'timer_tasks' //31
'timer_workers' //32
'webhooks' //33
'webhooks_logs' //34
'webhooks_ping' //35
]

var disabledFunctions = [for f in allFunctions: 'AzureWebJobs.${f}.Disabled' ]


var disabledFunctionsAppSettings = {
'${disabledFunctions[0]}' : functions_disabled_setting
'${disabledFunctions[1]}' : functions_disabled_setting
'${disabledFunctions[2]}' : functions_disabled_setting
'${disabledFunctions[3]}' : functions_disabled_setting
'${disabledFunctions[4]}' : functions_disabled_setting

'${disabledFunctions[5]}' : functions_disabled_setting
'${disabledFunctions[6]}' : functions_disabled_setting
'${disabledFunctions[7]}' : functions_disabled_setting
'${disabledFunctions[8]}' : functions_disabled_setting
'${disabledFunctions[9]}' : functions_disabled_setting

'${disabledFunctions[10]}' : functions_disabled_setting
'${disabledFunctions[11]}' : functions_disabled_setting
'${disabledFunctions[12]}' : functions_disabled_setting
'${disabledFunctions[13]}' : functions_disabled_setting
'${disabledFunctions[14]}' : functions_disabled_setting

'${disabledFunctions[15]}' : functions_disabled_setting
'${disabledFunctions[16]}' : functions_disabled_setting
'${disabledFunctions[17]}' : functions_disabled_setting
'${disabledFunctions[18]}' : functions_disabled_setting
'${disabledFunctions[19]}' : functions_disabled_setting

'${disabledFunctions[20]}' : functions_disabled_setting
'${disabledFunctions[21]}' : functions_disabled_setting
'${disabledFunctions[22]}' : functions_disabled_setting
'${disabledFunctions[23]}' : functions_disabled_setting
'${disabledFunctions[24]}' : functions_disabled_setting

'${disabledFunctions[25]}' : functions_disabled_setting
'${disabledFunctions[26]}' : functions_disabled_setting
'${disabledFunctions[27]}' : functions_disabled_setting
'${disabledFunctions[28]}' : functions_disabled_setting
'${disabledFunctions[29]}' : functions_disabled_setting

'${disabledFunctions[30]}' : functions_disabled_setting
'${disabledFunctions[31]}' : functions_disabled_setting
'${disabledFunctions[32]}' : functions_disabled_setting
'${disabledFunctions[33]}' : functions_disabled_setting
'${disabledFunctions[34]}' : functions_disabled_setting

'${disabledFunctions[35]}' : functions_disabled_setting
}

output functions array = disabledFunctions
output appSettings object = disabledFunctionsAppSettings
15 changes: 13 additions & 2 deletions src/deployment/bicep-templates/function-settings.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,27 @@ param monitor_account_name string
param functions_worker_runtime string
param functions_extension_version string

param functions_disabled string

var disabledFunctionName = 'disabledFunctions-${functions_worker_runtime}'

var telemetry = 'd7a73cf4-5a1a-4030-85e1-e5b25867e45a'

resource function 'Microsoft.Web/sites@2021-02-01' existing = {
name: name
}

module disabledFunctions 'function-settings-disabled-apps.bicep' = {
name: disabledFunctionName
params:{
functions_disabled_setting: functions_disabled
}
}

resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
parent: function
name: 'appsettings'
properties: {
properties: union({
'FUNCTIONS_EXTENSION_VERSION': functions_extension_version
'FUNCTIONS_WORKER_RUNTIME': functions_worker_runtime
'FUNCTIONS_WORKER_PROCESS_COUNT': '1'
Expand All @@ -56,6 +67,6 @@ resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
'ONEFUZZ_KEYVAULT': keyvault_name
'ONEFUZZ_OWNER': owner
'ONEFUZZ_CLIENT_SECRET': client_secret
}
}, disabledFunctions.outputs.appSettings)
}

76 changes: 76 additions & 0 deletions src/deployment/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import logging
import os
import platform
import resource
import shutil
import subprocess
import sys
Expand Down Expand Up @@ -152,6 +153,7 @@ def __init__(
subscription_id: Optional[str],
admins: List[UUID],
allowed_aad_tenants: List[UUID],
enable_dotnet: List[str]
):
self.subscription_id = subscription_id
self.resource_group = resource_group
Expand Down Expand Up @@ -186,6 +188,8 @@ def __init__(

self.arm_template = bicep_to_arm(bicep_template)

self.enable_dotnet = enable_dotnet

machine = platform.machine()
system = platform.system()

Expand Down Expand Up @@ -1065,6 +1069,69 @@ def deploy_dotnet_app(self) -> None:
if error is not None:
raise error

def enable_dotnet_func(self) -> None:
if self.enable_dotnet:
dotnet_functions = self.enable_dotnet.split(',')
func = shutil.which("az")
assert func is not None
for function_name in dotnet_functions:
error: Optional[subprocess.CalledProcessError] = None
max_tries = 5
for i in range(max_tries):
try:
# disable python function
logger.info(f'disabling PYTHON function: {function_name}')
subprocess.check_output(
[
func,
"functionapp",
"config",
"appsettings",
"set",
"--name",
self.application_name,
"--resource-group",
self.application_name,
"--settings",
f"AzureWebJobs.{function_name}.Disabled=1",
],
env=dict(os.environ, CLI_DEBUG="1"),
)
# enable dotnet function
logger.info(f'enabling DOTNET function: {function_name}')
subprocess.check_output(
[
func,
"functionapp",
"config",
"appsettings",
"set",
"--name",
self.application_name + "-net",
"--resource-group",
self.application_name,
"--settings",
f"AzureWebJobs.{function_name}.Disabled=0",
],
env=dict(os.environ, CLI_DEBUG="1"),
)
break
except subprocess.CalledProcessError as err:
error = err
if i + 1 < max_tries:
logger.debug("func failure error: %s", err)
logger.warning(
f"{function_name} function didn't respond to "
"status change request, waiting 60 seconds "
"and trying again"
)
time.sleep(60)
if error is not None:
raise error
else:
print(f'*** NO DOTNET FUNCTIONS ENABLED: {self.enable_dotnet} ***')


def update_registration(self) -> None:
if not self.create_registration:
return
Expand Down Expand Up @@ -1128,6 +1195,7 @@ def main() -> None:
("dotnet-api", Client.deploy_dotnet_app),
("export_appinsights", Client.add_log_export),
("update_registration", Client.update_registration),
("enable_dotnet", Client.enable_dotnet_func)
]

formatter = argparse.ArgumentDefaultsHelpFormatter
Expand Down Expand Up @@ -1238,7 +1306,14 @@ def main() -> None:
nargs="*",
help="Set additional AAD tenants beyond the tenant the app is deployed in",
)
parser.add_argument(
"--enable_dotnet",
AdamL-Microsoft marked this conversation as resolved.
Show resolved Hide resolved
type=str,
default=None,
help="Enables dotnet functions from a provided csv list and disables the python"
" functions in Azure Function App deployment",

)
args = parser.parse_args()

if shutil.which("func") is None:
Expand Down Expand Up @@ -1268,6 +1343,7 @@ def main() -> None:
subscription_id=args.subscription_id,
admins=args.set_admins,
allowed_aad_tenants=args.allowed_aad_tenants or [],
enable_dotnet=args.enable_dotnet,
)
if args.verbose:
level = logging.DEBUG
Expand Down