Removing Remaining App Function References from Deployment Code. (#2682)

* Removing Remaining App Function References from Deployment Code.

* Update src/deployment/deploy.py

Co-authored-by: Adam <103067949+AdamL-Microsoft@users.noreply.github.com>

* Consolidating.

* Updating function  handles.

* Removing copy.

* Fixing.

* Formatting.

* Fixing array calls.

* Adding json settings back.

* Formatting.

Co-authored-by: Adam <103067949+AdamL-Microsoft@users.noreply.github.com>
This commit is contained in:
Noah McGregor Harper
2022-12-15 20:03:42 -08:00
committed by GitHub
parent 0fb8bc4a86
commit 349604f03a
3 changed files with 12 additions and 249 deletions

View File

@ -117,19 +117,6 @@ resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
]
}
}
{
objectId: netFunction.outputs.principalId
tenantId: tenantId
permissions: {
secrets: [
'get'
'list'
'set'
'delete'
]
}
}
]
tenantId: tenantId
}
@ -192,21 +179,6 @@ resource roleAssignments 'Microsoft.Authorization/roleAssignments@2020-10-01-pre
]
}]
// try to make role assignments to deploy as late as possible in order to have principalId ready
resource roleAssignmentsNet 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for r in roleAssignmentsParams: {
name: guid('${resourceGroup().id}${r.suffix}-1f-net')
properties: {
roleDefinitionId: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/${r.role}'
principalId: netFunction.outputs.principalId
}
dependsOn: [
eventGrid
keyVault
serverFarm
featureFlags
]
}]
// 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')
@ -250,27 +222,6 @@ module function 'bicep-templates/function.bicep' = {
}
}
module netFunction 'bicep-templates/function.bicep' = {
name: 'netFunction'
params: {
linux_fx_version: 'DOTNET-ISOLATED|7.0'
name: '${name}-net'
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: serverFarm.outputs.id
use_windows: true
enable_remote_debugging: enable_remote_debugging
}
}
module functionSettings 'bicep-templates/function-settings.bicep' = {
name: 'functionSettings'
params: {
@ -291,118 +242,12 @@ module functionSettings 'bicep-templates/function-settings.bicep' = {
multi_tenant_domain: multi_tenant_domain
enable_profiler: enable_profiler
app_config_endpoint: featureFlags.outputs.AppConfigEndpoint
functions_disabled: '0'
agent_function_names: [
'AgentCanSchedule' //0
'AgentCommands' //1
'AgentEvents' //2
'AgentRegistration' //3
'Containers' //4
'Download' //5
'Info' //6
'InstanceConfig' //7
'Jobs' //8
'JobTemplates' //9
'JobTemplatesManage' //10
'Negotiate' //11
'Node' //12
'NodeAddSshKey' //13
'Notifications' //14
'Pool' //15
'Proxy' //16
'QueueFileChanges' //17
'QueueNodeHeartbeat' //18
'QueueProxyUpdate' //19
'QueueSignalrEvents' //20
'QueueTaskHeartbeat' //21
'QueueUpdates' //22
'QueueWebhooks' //23
'ReproVms' //24
'Scaleset' //25
'Tasks' //26
'TimerDaily' //27
'TimerProxy' //28
'TimerRepro' //29
'TimerRetention' //30
'TimerTasks' //31
'TimerWorkers' //32
'Tools' //33
'Webhooks' //34
'WebhooksLogs' //35
'WebhooksPing' //36
]
}
dependsOn: [
function
]
}
module netFunctionSettings 'bicep-templates/function-settings.bicep' = {
name: 'netFunctionSettings'
params: {
owner: owner
name: '${name}-net'
functions_worker_runtime: 'dotnet-isolated'
functions_extension_version: '~4'
instance_name: name
app_insights_app_id: operationalInsights.outputs.appInsightsAppId
app_insights_key: operationalInsights.outputs.appInsightsInstrumentationKey
client_secret: clientSecret
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
monitor_account_name: operationalInsights.outputs.monitorAccountName
multi_tenant_domain: multi_tenant_domain
enable_profiler: enable_profiler
app_config_endpoint: featureFlags.outputs.AppConfigEndpoint
functions_disabled: '1'
agent_function_names: [
'AgentCanSchedule' //0
'AgentCommands' //1
'AgentEvents' //2
'AgentRegistration' //3
'Containers' //4
'Download' //5
'Info' //6
'InstanceConfig' //7
'Jobs' //8
'JobTemplates' //9
'JobTemplatesManage' //10
'Negotiate' //11
'Node' //12
'NodeAddSshKey' //13
'Notifications' //14
'Pool' //15
'Proxy' //16
'QueueFileChanges' //17
'QueueNodeHeartbeat' //18
'QueueProxyUpdate' //19
'QueueSignalrEvents' //20
'QueueTaskHeartbeat' //21
'QueueUpdates' //22
'QueueWebhooks' //23
'ReproVms' //24
'Scaleset' //25
'Tasks' //26
'TimerDaily' //27
'TimerProxy' //28
'TimerRepro' //29
'TimerRetention' //30
'TimerTasks' //31
'TimerWorkers' //32
'Tools' //33
'Webhooks' //34
'WebhookLogs' //35
'WebhookPing' //36
]
}
dependsOn: [
netFunction
]
}
output fuzz_storage string = storage.outputs.FuzzId
output fuzz_name string = storage.outputs.FuzzName
output fuzz_key string = storage.outputs.FuzzKey

View File

@ -28,27 +28,14 @@ param monitor_account_name string
param functions_worker_runtime string
param functions_extension_version string
param agent_function_names array
param functions_disabled string
param enable_profiler bool
var disabledFunctionName = 'disabledFunctions-${name}'
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
allFunctions: agent_function_names
}
}
var enable_profilers = enable_profiler ? {
APPINSIGHTS_PROFILERFEATURE_VERSION : '1.0.0'
DiagnosticServices_EXTENSION_VERSION: '~3'
@ -79,5 +66,5 @@ resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
ONEFUZZ_KEYVAULT: keyvault_name
ONEFUZZ_OWNER: owner
ONEFUZZ_CLIENT_SECRET: client_secret
}, disabledFunctions.outputs.appSettings, enable_profilers)
}, enable_profilers)
}

View File

@ -99,8 +99,6 @@ UPPERCASE_NAME_ERROR = (
"specifying for this argument and retry."
)
DOTNET_APPLICATION_SUFFIX = "-net"
logger = logging.getLogger("deploy")
@ -301,49 +299,25 @@ class Client:
"cli_password", object_id, self.get_subscription_id()
)
def get_instance_urls(self) -> List[str]:
def get_instance_url(self) -> str:
# The url to access the instance
# This also represents the legacy identifier_uris of the application
# registration
if self.multi_tenant_domain:
return [
"https://%s/%s" % (self.multi_tenant_domain, name)
for name in [
self.application_name,
self.application_name + DOTNET_APPLICATION_SUFFIX,
]
]
return "https://%s/%s" % (self.multi_tenant_domain, self.application_name)
else:
return [
"https://%s.azurewebsites.net" % name
for name in [
self.application_name,
self.application_name + DOTNET_APPLICATION_SUFFIX,
]
]
return "https://%s.azurewebsites.net" % self.application_name
def get_identifier_urls(self) -> List[str]:
def get_identifier_url(self) -> str:
# This is used to identify the application registration via the
# identifier_uris field. Depending on the environment this value needs
# to be from an approved domain The format of this value is derived
# from the default value proposed by azure when creating an application
# registration api://{guid}/...
if self.multi_tenant_domain:
return [
"api://%s/%s" % (self.multi_tenant_domain, name)
for name in [
self.application_name,
self.application_name + DOTNET_APPLICATION_SUFFIX,
]
]
return "api://%s/%s" % (self.multi_tenant_domain, self.application_name)
else:
return [
"api://%s.azurewebsites.net" % name
for name in [
self.application_name,
self.application_name + DOTNET_APPLICATION_SUFFIX,
]
]
return "api://%s.azurewebsites.net" % self.application_name
def get_signin_audience(self) -> str:
# https://docs.microsoft.com/en-us/azure/active-directory/develop/supported-accounts-validation
@ -514,7 +488,7 @@ class Client:
# find any identifier URIs that need updating
identifier_uris: List[str] = app["identifierUris"]
updated_identifier_uris = list(
set(identifier_uris) | set(self.get_identifier_urls())
set(identifier_uris) | set([self.get_identifier_url()])
)
if len(updated_identifier_uris) > len(identifier_uris):
update_properties["identifierUris"] = updated_identifier_uris
@ -561,7 +535,7 @@ class Client:
params = {
"displayName": self.application_name,
"identifierUris": self.get_identifier_urls(),
"identifierUris": [self.get_identifier_url()],
"signInAudience": self.get_signin_audience(),
"appRoles": app_roles,
"api": {
@ -583,10 +557,7 @@ class Client:
"enableAccessTokenIssuance": False,
"enableIdTokenIssuance": True,
},
"redirectUris": [
f"{url}/.auth/login/aad/callback"
for url in self.get_instance_urls()
],
"redirectUris": [f"{self.get_instance_url()}/.auth/login/aad/callback"],
},
"requiredResourceAccess": [
{
@ -662,8 +633,8 @@ class Client:
"%Y-%m-%dT%H:%M:%SZ"
)
app_func_audiences = self.get_identifier_urls().copy()
app_func_audiences.extend(self.get_instance_urls())
app_func_audiences = [self.get_identifier_url()]
app_func_audiences.extend([self.get_instance_url()])
if self.multi_tenant_domain:
# clear the value in the Issuer Url field:
@ -1135,45 +1106,6 @@ class Client:
if error is not None:
raise error
def deploy_dotnet_app(self) -> None:
logger.info("deploying function app %s ", self.app_zip)
with tempfile.TemporaryDirectory() as tmpdirname:
with zipfile.ZipFile(self.app_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 + DOTNET_APPLICATION_SUFFIX,
"--no-build",
"--dotnet-version",
"7.0",
],
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
@ -1241,7 +1173,6 @@ def main() -> None:
("instance-specific-setup", Client.upload_instance_setup),
("third-party", Client.upload_third_party),
("api", Client.deploy_app),
("dotnet-api", Client.deploy_dotnet_app),
("export_appinsights", Client.add_log_export),
("update_registration", Client.update_registration),
]