mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-15 03:18:07 +00:00
* updating deploy.py for dotnet packages * dotnet deployment needs to be alongside python if flagged * individual deployment state for dotnet api since this will deploy alongside python api * correcting state order for dotnet-api deployment step to follow python api deployment * cleanup deploy.py formatting * Adding dotnet's zip package arguments to deploy and fixing func command flags * changed quotes to pass black check * reconfiguring bicep templates to deploy function app settings correctly by moving app settings into a separate template
This commit is contained in:
@ -162,7 +162,7 @@ module eventGrid 'bicep-templates/event-grid.bicep' = {
|
||||
]
|
||||
}
|
||||
|
||||
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
||||
// try to make role assignments to deploy as late as possible in order to have principalId ready
|
||||
resource roleAssigmentsPy 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for r in roleAssignmentsParams: {
|
||||
name: guid('${resourceGroup().id}${r.suffix}-python')
|
||||
properties: {
|
||||
@ -176,7 +176,7 @@ resource roleAssigmentsPy 'Microsoft.Authorization/roleAssignments@2020-10-01-pr
|
||||
]
|
||||
}]
|
||||
|
||||
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
||||
// try to make role assignments to deploy as late as possible in order to have principalId ready
|
||||
resource roleAssigmentsNet 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for r in roleAssignmentsParams: {
|
||||
name: guid('${resourceGroup().id}${r.suffix}-net')
|
||||
properties: {
|
||||
@ -191,7 +191,7 @@ resource roleAssigmentsNet 'Microsoft.Authorization/roleAssignments@2020-10-01-p
|
||||
}]
|
||||
|
||||
|
||||
// try to make role assignments to deploy as late as possible in order to has principalId ready
|
||||
// try to make role assignments to deploy as late as possible in order to have principalId ready
|
||||
resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
|
||||
name: guid('${resourceGroup().id}-user_managed_idenity_read_blob')
|
||||
properties: {
|
||||
@ -209,63 +209,87 @@ resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10
|
||||
module pythonFunction 'bicep-templates/function.bicep' = {
|
||||
name: 'pythonFunction'
|
||||
params: {
|
||||
functions_worker_runtime: 'python'
|
||||
linux_fx_version: 'Python|3.8'
|
||||
functions_extension_version: '~3'
|
||||
name: name
|
||||
linux_fx_version: 'Python|3.8'
|
||||
|
||||
instance_name: name
|
||||
app_logs_sas_url: storage.outputs.FuncSasUrlBlobAppLogs
|
||||
app_func_audiences: app_func_audiences
|
||||
app_func_issuer: app_func_issuer
|
||||
app_insights_app_id: operationalInsights.outputs.appInsightsAppId
|
||||
app_insights_key: operationalInsights.outputs.appInsightsInstrumentationKey
|
||||
client_id: clientId
|
||||
client_secret: clientSecret
|
||||
|
||||
diagnostics_log_level: diagnosticsLogLevel
|
||||
func_sas_url: storage.outputs.FuncSasUrl
|
||||
func_storage_resource_id: storage.outputs.FuncId
|
||||
fuzz_storage_resource_id: storage.outputs.FuzzId
|
||||
keyvault_name: keyVaultName
|
||||
location: location
|
||||
log_retention: log_retention
|
||||
monitor_account_name: operationalInsights.outputs.monitorAccountName
|
||||
multi_tenant_domain: multi_tenant_domain
|
||||
owner: owner
|
||||
server_farm_id: serverFarms.outputs.id
|
||||
signal_r_connection_string: signalR.outputs.connectionString
|
||||
client_id: clientId
|
||||
}
|
||||
}
|
||||
|
||||
module netFunction 'bicep-templates/function.bicep' = {
|
||||
name: 'netFunction'
|
||||
params: {
|
||||
functions_worker_runtime: 'dotnet-isolated'
|
||||
linux_fx_version: 'DOTNET-ISOLATED|6.0'
|
||||
functions_extension_version: '~4'
|
||||
name: '${name}-net'
|
||||
|
||||
instance_name: name
|
||||
app_logs_sas_url: storage.outputs.FuncSasUrlBlobAppLogs
|
||||
app_func_audiences: app_func_audiences
|
||||
app_func_issuer: app_func_issuer
|
||||
client_id: clientId
|
||||
diagnostics_log_level: diagnosticsLogLevel
|
||||
location: location
|
||||
log_retention: log_retention
|
||||
owner: owner
|
||||
server_farm_id: serverFarms.outputs.id
|
||||
}
|
||||
}
|
||||
|
||||
module pythonFunctionSettings 'bicep-templates/function-settings.bicep' = {
|
||||
name: 'pythonFunctionSettings'
|
||||
params: {
|
||||
name: name
|
||||
owner: owner
|
||||
functions_worker_runtime: 'python'
|
||||
functions_extension_version: '~3'
|
||||
instance_name: name
|
||||
app_insights_app_id: operationalInsights.outputs.appInsightsAppId
|
||||
app_insights_key: operationalInsights.outputs.appInsightsInstrumentationKey
|
||||
client_id: clientId
|
||||
client_secret: clientSecret
|
||||
diagnostics_log_level: diagnosticsLogLevel
|
||||
signal_r_connection_string: signalR.outputs.connectionString
|
||||
func_sas_url: storage.outputs.FuncSasUrl
|
||||
func_storage_resource_id: storage.outputs.FuncId
|
||||
fuzz_storage_resource_id: storage.outputs.FuzzId
|
||||
keyvault_name: keyVaultName
|
||||
location: location
|
||||
log_retention: log_retention
|
||||
monitor_account_name: operationalInsights.outputs.monitorAccountName
|
||||
multi_tenant_domain: multi_tenant_domain
|
||||
owner: owner
|
||||
server_farm_id: serverFarms.outputs.id
|
||||
signal_r_connection_string: signalR.outputs.connectionString
|
||||
}
|
||||
dependsOn: [
|
||||
pythonFunction
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
module netFunctionSettings 'bicep-templates/function-settings.bicep' = {
|
||||
name: 'netFunctionSettings'
|
||||
params: {
|
||||
owner: owner
|
||||
name: '${name}-net'
|
||||
signal_r_connection_string: signalR.outputs.connectionString
|
||||
app_insights_app_id: operationalInsights.outputs.appInsightsAppId
|
||||
app_insights_key: operationalInsights.outputs.appInsightsInstrumentationKey
|
||||
functions_worker_runtime: 'dotnet-isolated'
|
||||
functions_extension_version: '~4'
|
||||
instance_name: name
|
||||
client_secret: clientSecret
|
||||
func_sas_url: storage.outputs.FuncSasUrl
|
||||
func_storage_resource_id: storage.outputs.FuncId
|
||||
fuzz_storage_resource_id: storage.outputs.FuzzId
|
||||
keyvault_name: keyVaultName
|
||||
monitor_account_name: operationalInsights.outputs.monitorAccountName
|
||||
multi_tenant_domain: multi_tenant_domain
|
||||
}
|
||||
dependsOn: [
|
||||
netFunction
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
61
src/deployment/bicep-templates/function-settings.bicep
Normal file
61
src/deployment/bicep-templates/function-settings.bicep
Normal file
@ -0,0 +1,61 @@
|
||||
param name string
|
||||
param instance_name string
|
||||
param owner string
|
||||
param app_insights_app_id string
|
||||
@secure()
|
||||
param app_insights_key string
|
||||
|
||||
@secure()
|
||||
param func_sas_url string
|
||||
|
||||
param multi_tenant_domain string
|
||||
|
||||
@secure()
|
||||
param signal_r_connection_string string
|
||||
|
||||
param func_storage_resource_id string
|
||||
param fuzz_storage_resource_id string
|
||||
|
||||
param keyvault_name string
|
||||
|
||||
@secure()
|
||||
param client_secret string
|
||||
|
||||
param monitor_account_name string
|
||||
|
||||
param functions_worker_runtime string
|
||||
param functions_extension_version string
|
||||
|
||||
var telemetry = 'd7a73cf4-5a1a-4030-85e1-e5b25867e45a'
|
||||
|
||||
resource function 'Microsoft.Web/sites@2021-02-01' existing = {
|
||||
name: name
|
||||
}
|
||||
|
||||
resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||
parent: function
|
||||
name: 'appsettings'
|
||||
properties: {
|
||||
'FUNCTIONS_EXTENSION_VERSION': functions_extension_version
|
||||
'FUNCTIONS_WORKER_RUNTIME': functions_worker_runtime
|
||||
'FUNCTIONS_WORKER_PROCESS_COUNT': '1'
|
||||
'APPINSIGHTS_INSTRUMENTATIONKEY': app_insights_key
|
||||
'APPINSIGHTS_APPID': app_insights_app_id
|
||||
'ONEFUZZ_TELEMETRY': telemetry
|
||||
'AzureWebJobsStorage': func_sas_url
|
||||
'MULTI_TENANT_DOMAIN': multi_tenant_domain
|
||||
'AzureWebJobsDisableHomepage': 'true'
|
||||
'AzureSignalRConnectionString': signal_r_connection_string
|
||||
'AzureSignalRServiceTransportType': 'Transient'
|
||||
'ONEFUZZ_INSTANCE_NAME': instance_name
|
||||
'ONEFUZZ_INSTANCE': 'https://${name}.azurewebsites.net'
|
||||
'ONEFUZZ_RESOURCE_GROUP': resourceGroup().id
|
||||
'ONEFUZZ_DATA_STORAGE': fuzz_storage_resource_id
|
||||
'ONEFUZZ_FUNC_STORAGE': func_storage_resource_id
|
||||
'ONEFUZZ_MONITOR': monitor_account_name
|
||||
'ONEFUZZ_KEYVAULT': keyvault_name
|
||||
'ONEFUZZ_OWNER': owner
|
||||
'ONEFUZZ_CLIENT_SECRET': client_secret
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
param name string
|
||||
param instance_name string
|
||||
param location string
|
||||
param owner string
|
||||
|
||||
@ -11,18 +10,6 @@ param app_func_audiences array
|
||||
@secure()
|
||||
param app_logs_sas_url string
|
||||
|
||||
param app_insights_app_id string
|
||||
@secure()
|
||||
param app_insights_key string
|
||||
|
||||
@secure()
|
||||
param func_sas_url string
|
||||
|
||||
param multi_tenant_domain string
|
||||
|
||||
@secure()
|
||||
param signal_r_connection_string string
|
||||
|
||||
@description('The degree of severity for diagnostics logs.')
|
||||
@allowed([
|
||||
'Verbose'
|
||||
@ -32,22 +19,8 @@ param signal_r_connection_string string
|
||||
])
|
||||
param diagnostics_log_level string
|
||||
param log_retention int
|
||||
|
||||
param func_storage_resource_id string
|
||||
param fuzz_storage_resource_id string
|
||||
|
||||
param keyvault_name string
|
||||
|
||||
@secure()
|
||||
param client_secret string
|
||||
|
||||
param monitor_account_name string
|
||||
|
||||
param linux_fx_version string
|
||||
param functions_worker_runtime string
|
||||
param functions_extension_version string
|
||||
|
||||
var telemetry = 'd7a73cf4-5a1a-4030-85e1-e5b25867e45a'
|
||||
|
||||
resource function 'Microsoft.Web/sites@2021-03-01' = {
|
||||
name: name
|
||||
@ -123,31 +96,4 @@ resource funcLogs 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||
parent: function
|
||||
}
|
||||
|
||||
resource pythonFunctionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||
name: 'appsettings'
|
||||
parent: function
|
||||
properties: {
|
||||
'FUNCTIONS_EXTENSION_VERSION': functions_extension_version
|
||||
'FUNCTIONS_WORKER_RUNTIME': functions_worker_runtime
|
||||
'FUNCTIONS_WORKER_PROCESS_COUNT': '1'
|
||||
'APPINSIGHTS_INSTRUMENTATIONKEY': app_insights_key
|
||||
'APPINSIGHTS_APPID': app_insights_app_id
|
||||
'ONEFUZZ_TELEMETRY': telemetry
|
||||
'AzureWebJobsStorage': func_sas_url
|
||||
'MULTI_TENANT_DOMAIN': multi_tenant_domain
|
||||
'AzureWebJobsDisableHomepage': 'true'
|
||||
'AzureSignalRConnectionString': signal_r_connection_string
|
||||
'AzureSignalRServiceTransportType': 'Transient'
|
||||
'ONEFUZZ_INSTANCE_NAME': instance_name
|
||||
'ONEFUZZ_INSTANCE': 'https://${name}.azurewebsites.net'
|
||||
'ONEFUZZ_RESOURCE_GROUP': resourceGroup().id
|
||||
'ONEFUZZ_DATA_STORAGE': fuzz_storage_resource_id
|
||||
'ONEFUZZ_FUNC_STORAGE': func_storage_resource_id
|
||||
'ONEFUZZ_MONITOR': monitor_account_name
|
||||
'ONEFUZZ_KEYVAULT': keyvault_name
|
||||
'ONEFUZZ_OWNER': owner
|
||||
'ONEFUZZ_CLIENT_SECRET': client_secret
|
||||
}
|
||||
}
|
||||
|
||||
output principalId string = reference(function.id, function.apiVersion, 'Full').identity.principalId
|
||||
|
@ -138,6 +138,7 @@ class Client:
|
||||
client_id: Optional[str],
|
||||
client_secret: Optional[str],
|
||||
app_zip: str,
|
||||
app_net_zip: str,
|
||||
tools: str,
|
||||
instance_specific: str,
|
||||
third_party: str,
|
||||
@ -159,6 +160,7 @@ class Client:
|
||||
self.owner = owner
|
||||
self.nsg_config = nsg_config
|
||||
self.app_zip = app_zip
|
||||
self.app_net_zip = app_net_zip
|
||||
self.tools = tools
|
||||
self.instance_specific = instance_specific
|
||||
self.third_party = third_party
|
||||
@ -1026,6 +1028,43 @@ class Client:
|
||||
if error is not None:
|
||||
raise error
|
||||
|
||||
def deploy_dotnet_app(self) -> None:
|
||||
logger.info("deploying function app %s ", self.app_net_zip)
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
with zipfile.ZipFile(self.app_net_zip, "r") as zip_ref:
|
||||
func = shutil.which("func")
|
||||
assert func is not None
|
||||
|
||||
zip_ref.extractall(tmpdirname)
|
||||
error: Optional[subprocess.CalledProcessError] = None
|
||||
max_tries = 5
|
||||
for i in range(max_tries):
|
||||
try:
|
||||
subprocess.check_output(
|
||||
[
|
||||
func,
|
||||
"azure",
|
||||
"functionapp",
|
||||
"publish",
|
||||
self.application_name + "-net",
|
||||
"--no-build",
|
||||
],
|
||||
env=dict(os.environ, CLI_DEBUG="1"),
|
||||
cwd=tmpdirname,
|
||||
)
|
||||
return
|
||||
except subprocess.CalledProcessError as err:
|
||||
error = err
|
||||
if i + 1 < max_tries:
|
||||
logger.debug("func failure error: %s", err)
|
||||
logger.warning(
|
||||
"function failed to deploy, waiting 60 "
|
||||
"seconds and trying again"
|
||||
)
|
||||
time.sleep(60)
|
||||
if error is not None:
|
||||
raise error
|
||||
|
||||
def update_registration(self) -> None:
|
||||
if not self.create_registration:
|
||||
return
|
||||
@ -1115,6 +1154,12 @@ def main() -> None:
|
||||
default="api-service.zip",
|
||||
help="(default: %(default)s)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--app-net-zip",
|
||||
type=arg_file,
|
||||
default="api-service-net.zip",
|
||||
help="(default: %(default)s)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tools", type=arg_dir, default="tools", help="(default: %(default)s)"
|
||||
)
|
||||
@ -1192,6 +1237,11 @@ def main() -> None:
|
||||
nargs="*",
|
||||
help="Set additional AAD tenants beyond the tenant the app is deployed in",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dotnet_deploy",
|
||||
action="store_true",
|
||||
help="deploys the dotnet version of the app along with the python version",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@ -1208,6 +1258,7 @@ def main() -> None:
|
||||
client_id=args.client_id,
|
||||
client_secret=args.client_secret,
|
||||
app_zip=args.app_zip,
|
||||
app_net_zip=args.app_net_zip,
|
||||
tools=args.tools,
|
||||
instance_specific=args.instance_specific,
|
||||
third_party=args.third_party,
|
||||
@ -1238,6 +1289,12 @@ def main() -> None:
|
||||
)
|
||||
states = rbac_only_states
|
||||
else:
|
||||
if args.dotnet_deploy:
|
||||
logger.info("deploying dotnet and python services for Azure functions")
|
||||
after_python = full_deployment_states.index(("api", Client.deploy_app)) + 1
|
||||
full_deployment_states.insert(
|
||||
after_python, ("dotnet-api", Client.deploy_dotnet_app)
|
||||
)
|
||||
states = full_deployment_states
|
||||
|
||||
if args.start_at != states[0][0]:
|
||||
|
Reference in New Issue
Block a user