mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-15 03:18:07 +00:00
enable running dot-net function on Windows to allow attaching remote debugger (#2344)
* enable running dot-net function on Windows to allow attaching remote debugger * rename from 'use_windows' to 'host_dotnet_on_windows' * instructions * reformat deploy.py Co-authored-by: stas <statis@microsoft.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,3 +10,6 @@
|
|||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
/.ionide/symbolCache.db
|
/.ionide/symbolCache.db
|
||||||
|
|
||||||
|
/src/ApiService/ApiService/Properties/PublishProfiles/*
|
||||||
|
/src/ApiService/ApiService/Properties/ServiceDependencies/*
|
||||||
|
5
docs/how-to/remote-debugging-dotnet.md
Normal file
5
docs/how-to/remote-debugging-dotnet.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## How to setup remote debugging of dotnet Azure Functions on new deployments
|
||||||
|
|
||||||
|
1) when running `deploy.py` use `--host_dotnet_on_windows` flag as part of the command line. This will deploy `dotnet` Azure Function on Windows Server Farm, which supports functinoality for remote debugging of `dotnet` code.
|
||||||
|
|
||||||
|
2) Follow instructions on how to connect Visual Studio 2022 to newly deployed Azure Function: [https://docs.microsoft.com/en-us/azure/azure-functions/functions-develop-vs?tabs=in-process#remote-debugging](https://docs.microsoft.com/en-us/azure/azure-functions/functions-develop-vs?tabs=in-process#remote-debugging)
|
@ -9,6 +9,7 @@ param signedExpiry string
|
|||||||
param app_func_issuer string
|
param app_func_issuer string
|
||||||
param app_func_audiences array
|
param app_func_audiences array
|
||||||
param multi_tenant_domain string
|
param multi_tenant_domain string
|
||||||
|
param enable_remote_debugging bool = false
|
||||||
|
|
||||||
param location string = resourceGroup().location
|
param location string = resourceGroup().location
|
||||||
|
|
||||||
@ -78,14 +79,29 @@ module operationalInsights 'bicep-templates/operational-insights.bicep' = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module serverFarms 'bicep-templates/server-farms.bicep' = {
|
module linuxServerFarm 'bicep-templates/server-farms.bicep' = {
|
||||||
name: 'server-farms'
|
name: 'linux-server-farm'
|
||||||
params: {
|
params: {
|
||||||
server_farm_name: name
|
server_farm_name: name
|
||||||
owner: owner
|
owner: owner
|
||||||
location: location
|
location: location
|
||||||
|
use_windows: false
|
||||||
|
create: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module dotNetServerFarm 'bicep-templates/server-farms.bicep' = {
|
||||||
|
name: (enable_remote_debugging) ? 'windows-server-farm' : 'same-linux-server-farm'
|
||||||
|
params: {
|
||||||
|
server_farm_name: (enable_remote_debugging) ? '${name}-net' : name
|
||||||
|
owner: owner
|
||||||
|
location: location
|
||||||
|
use_windows: enable_remote_debugging
|
||||||
|
create: enable_remote_debugging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var keyVaultName = 'of-kv-${uniqueString(resourceGroup().id)}'
|
var keyVaultName = 'of-kv-${uniqueString(resourceGroup().id)}'
|
||||||
resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
|
resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
|
||||||
name: keyVaultName
|
name: keyVaultName
|
||||||
@ -152,13 +168,33 @@ module autoscaleSettings 'bicep-templates/autoscale-settings.bicep' = {
|
|||||||
name: 'autoscaleSettings'
|
name: 'autoscaleSettings'
|
||||||
params: {
|
params: {
|
||||||
location: location
|
location: location
|
||||||
server_farm_id: serverFarms.outputs.id
|
server_farm_id: linuxServerFarm.outputs.id
|
||||||
owner: owner
|
owner: owner
|
||||||
workspaceId: operationalInsights.outputs.workspaceId
|
workspaceId: operationalInsights.outputs.workspaceId
|
||||||
logRetention: log_retention
|
logRetention: log_retention
|
||||||
|
autoscale_name: 'onefuzz-autoscale-${uniqueString(resourceGroup().id)}'
|
||||||
|
create_new: true
|
||||||
|
function_diagnostics_settings_name: 'functionDiagnosticSettings'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module autoscaleSettingsNet 'bicep-templates/autoscale-settings.bicep' = {
|
||||||
|
name: 'autoscaleSettingsNet'
|
||||||
|
params: {
|
||||||
|
location: location
|
||||||
|
server_farm_id: dotNetServerFarm.outputs.id
|
||||||
|
owner: owner
|
||||||
|
workspaceId: operationalInsights.outputs.workspaceId
|
||||||
|
logRetention: log_retention
|
||||||
|
autoscale_name: (enable_remote_debugging) ? 'onefuzz-autoscale-${uniqueString(resourceGroup().id)}-net' : 'onefuzz-autoscale-${uniqueString(resourceGroup().id)}'
|
||||||
|
create_new: enable_remote_debugging
|
||||||
|
function_diagnostics_settings_name: (enable_remote_debugging) ? 'functionDiagnosticSettings' : 'functionDiagnosticsSettingsNet'
|
||||||
|
}
|
||||||
|
dependsOn: [
|
||||||
|
autoscaleSettings
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
module eventGrid 'bicep-templates/event-grid.bicep' = {
|
module eventGrid 'bicep-templates/event-grid.bicep' = {
|
||||||
name: 'event-grid'
|
name: 'event-grid'
|
||||||
params:{
|
params:{
|
||||||
@ -182,7 +218,7 @@ resource roleAssigmentsPy 'Microsoft.Authorization/roleAssignments@2020-10-01-pr
|
|||||||
dependsOn: [
|
dependsOn: [
|
||||||
eventGrid
|
eventGrid
|
||||||
keyVault
|
keyVault
|
||||||
serverFarms
|
linuxServerFarm
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@ -196,7 +232,7 @@ resource roleAssigmentsNet 'Microsoft.Authorization/roleAssignments@2020-10-01-p
|
|||||||
dependsOn: [
|
dependsOn: [
|
||||||
eventGrid
|
eventGrid
|
||||||
keyVault
|
keyVault
|
||||||
serverFarms
|
dotNetServerFarm
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@ -211,7 +247,8 @@ resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10
|
|||||||
dependsOn: [
|
dependsOn: [
|
||||||
eventGrid
|
eventGrid
|
||||||
keyVault
|
keyVault
|
||||||
serverFarms
|
linuxServerFarm
|
||||||
|
dotNetServerFarm
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,8 +267,10 @@ module pythonFunction 'bicep-templates/function.bicep' = {
|
|||||||
location: location
|
location: location
|
||||||
log_retention: log_retention
|
log_retention: log_retention
|
||||||
owner: owner
|
owner: owner
|
||||||
server_farm_id: serverFarms.outputs.id
|
server_farm_id: linuxServerFarm.outputs.id
|
||||||
client_id: clientId
|
client_id: clientId
|
||||||
|
use_windows: false
|
||||||
|
enable_remote_debugging: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +288,10 @@ module netFunction 'bicep-templates/function.bicep' = {
|
|||||||
location: location
|
location: location
|
||||||
log_retention: log_retention
|
log_retention: log_retention
|
||||||
owner: owner
|
owner: owner
|
||||||
server_farm_id: serverFarms.outputs.id
|
server_farm_id: dotNetServerFarm.outputs.id
|
||||||
|
|
||||||
|
use_windows: enable_remote_debugging
|
||||||
|
enable_remote_debugging: enable_remote_debugging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,3 +434,5 @@ output func_key string = storage.outputs.FuncKey
|
|||||||
|
|
||||||
output scaleset_identity string = scaleset_identity
|
output scaleset_identity string = scaleset_identity
|
||||||
output tenant_id string = tenantId
|
output tenant_id string = tenantId
|
||||||
|
|
||||||
|
output enable_remote_debugging bool = enable_remote_debugging
|
||||||
|
@ -3,12 +3,14 @@ param server_farm_id string
|
|||||||
param owner string
|
param owner string
|
||||||
param workspaceId string
|
param workspaceId string
|
||||||
param logRetention int
|
param logRetention int
|
||||||
|
param autoscale_name string
|
||||||
|
param function_diagnostics_settings_name string
|
||||||
|
param create_new bool
|
||||||
|
|
||||||
var autoscale_name = 'onefuzz-autoscale-${uniqueString(resourceGroup().id)}'
|
|
||||||
|
|
||||||
resource autoscaleSettings 'Microsoft.Insights/autoscalesettings@2015-04-01' = {
|
resource autoscaleSettings 'Microsoft.Insights/autoscalesettings@2015-04-01' = if (create_new) {
|
||||||
name: autoscale_name
|
name: autoscale_name
|
||||||
location: location
|
location: location
|
||||||
properties: {
|
properties: {
|
||||||
name: autoscale_name
|
name: autoscale_name
|
||||||
enabled: true
|
enabled: true
|
||||||
@ -70,8 +72,8 @@ resource autoscaleSettings 'Microsoft.Insights/autoscalesettings@2015-04-01' = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource functionDiagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
|
resource functionDiagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (create_new) {
|
||||||
name: 'functionDiagnosticSettings'
|
name: function_diagnostics_settings_name
|
||||||
scope: autoscaleSettings
|
scope: autoscaleSettings
|
||||||
properties: {
|
properties: {
|
||||||
logs: [
|
logs: [
|
||||||
|
@ -6,6 +6,8 @@ param server_farm_id string
|
|||||||
param client_id string
|
param client_id string
|
||||||
param app_func_issuer string
|
param app_func_issuer string
|
||||||
param app_func_audiences array
|
param app_func_audiences array
|
||||||
|
param use_windows bool
|
||||||
|
param enable_remote_debugging bool
|
||||||
|
|
||||||
@secure()
|
@secure()
|
||||||
param app_logs_sas_url string
|
param app_logs_sas_url string
|
||||||
@ -22,31 +24,43 @@ param log_retention int
|
|||||||
param linux_fx_version string
|
param linux_fx_version string
|
||||||
|
|
||||||
|
|
||||||
|
var siteconfig = (use_windows) ? {
|
||||||
|
} : {
|
||||||
|
linuxFxVersion: linux_fx_version
|
||||||
|
}
|
||||||
|
|
||||||
|
var commonSiteConfig = {
|
||||||
|
alwaysOn: true
|
||||||
|
defaultDocuments: []
|
||||||
|
httpLoggingEnabled: true
|
||||||
|
logsDirectorySizeLimit: 100
|
||||||
|
detailedErrorLoggingEnabled: true
|
||||||
|
http20Enabled: true
|
||||||
|
ftpsState: 'Disabled'
|
||||||
|
}
|
||||||
|
|
||||||
|
var extraProperties = (use_windows && enable_remote_debugging) ? {
|
||||||
|
netFrameworkVersion: 'v6.0'
|
||||||
|
remoteDebuggingEnabled: true
|
||||||
|
remoteDebuggingVersion: 'VS2022'
|
||||||
|
} : {}
|
||||||
|
|
||||||
resource function 'Microsoft.Web/sites@2021-03-01' = {
|
resource function 'Microsoft.Web/sites@2021-03-01' = {
|
||||||
name: name
|
name: name
|
||||||
location: location
|
location: location
|
||||||
kind: 'functionapp,linux'
|
kind: (use_windows) ? 'functionapp' : 'functionapp,linux'
|
||||||
tags: {
|
tags: {
|
||||||
'OWNER': owner
|
OWNER: owner
|
||||||
}
|
}
|
||||||
identity: {
|
identity: {
|
||||||
type: 'SystemAssigned'
|
type: 'SystemAssigned'
|
||||||
}
|
}
|
||||||
properties: {
|
properties: union({
|
||||||
siteConfig: {
|
siteConfig: union(siteconfig, commonSiteConfig)
|
||||||
linuxFxVersion: linux_fx_version
|
|
||||||
alwaysOn: true
|
|
||||||
defaultDocuments: []
|
|
||||||
httpLoggingEnabled: true
|
|
||||||
logsDirectorySizeLimit: 100
|
|
||||||
detailedErrorLoggingEnabled: true
|
|
||||||
http20Enabled: true
|
|
||||||
ftpsState: 'Disabled'
|
|
||||||
}
|
|
||||||
httpsOnly: true
|
httpsOnly: true
|
||||||
serverFarmId: server_farm_id
|
serverFarmId: server_farm_id
|
||||||
clientAffinityEnabled: true
|
clientAffinityEnabled: true
|
||||||
}
|
}, extraProperties)
|
||||||
}
|
}
|
||||||
|
|
||||||
resource funcAuthSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
resource funcAuthSettings 'Microsoft.Web/sites/config@2021-03-01' = {
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
param server_farm_name string
|
param server_farm_name string
|
||||||
param owner string
|
param owner string
|
||||||
param location string
|
param location string
|
||||||
|
param use_windows bool
|
||||||
|
param create bool
|
||||||
|
|
||||||
resource serverFarms 'Microsoft.Web/serverfarms@2021-03-01' = {
|
var kind = (use_windows) ? 'app' : 'linux'
|
||||||
|
|
||||||
|
resource serverFarms 'Microsoft.Web/serverfarms@2022-03-01' = if (create) {
|
||||||
name: server_farm_name
|
name: server_farm_name
|
||||||
location: location
|
location: location
|
||||||
kind: 'linux'
|
kind: kind
|
||||||
properties: {
|
properties: {
|
||||||
reserved: true
|
// reserved must be set to true for Linux server farm, otherwise it is false
|
||||||
|
reserved: !use_windows
|
||||||
}
|
}
|
||||||
sku: {
|
sku: {
|
||||||
name: 'P2v2'
|
name: 'P2v2'
|
||||||
@ -21,3 +26,4 @@ resource serverFarms 'Microsoft.Web/serverfarms@2021-03-01' = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
output id string = serverFarms.id
|
output id string = serverFarms.id
|
||||||
|
output kind string = kind
|
||||||
|
@ -163,6 +163,7 @@ class Client:
|
|||||||
use_dotnet_agent_functions: bool,
|
use_dotnet_agent_functions: bool,
|
||||||
cli_app_id: str,
|
cli_app_id: str,
|
||||||
auto_create_cli_app: bool,
|
auto_create_cli_app: bool,
|
||||||
|
host_dotnet_on_windows: bool,
|
||||||
):
|
):
|
||||||
self.subscription_id = subscription_id
|
self.subscription_id = subscription_id
|
||||||
self.resource_group = resource_group
|
self.resource_group = resource_group
|
||||||
@ -197,6 +198,7 @@ class Client:
|
|||||||
self.use_dotnet_agent_functions = use_dotnet_agent_functions
|
self.use_dotnet_agent_functions = use_dotnet_agent_functions
|
||||||
self.cli_app_id = cli_app_id
|
self.cli_app_id = cli_app_id
|
||||||
self.auto_create_cli_app = auto_create_cli_app
|
self.auto_create_cli_app = auto_create_cli_app
|
||||||
|
self.host_dotnet_on_windows = host_dotnet_on_windows
|
||||||
|
|
||||||
self.cli_config: Dict[str, Union[str, UUID]] = {
|
self.cli_config: Dict[str, Union[str, UUID]] = {
|
||||||
"client_id": self.cli_app_id,
|
"client_id": self.cli_app_id,
|
||||||
@ -630,6 +632,11 @@ class Client:
|
|||||||
app_func_issuer = "https://sts.windows.net/%s/" % tenant_oid
|
app_func_issuer = "https://sts.windows.net/%s/" % tenant_oid
|
||||||
multi_tenant_domain = {"value": ""}
|
multi_tenant_domain = {"value": ""}
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"template parameter enable_remote_debugging is set to: %s",
|
||||||
|
self.host_dotnet_on_windows,
|
||||||
|
)
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"app_func_audiences": {"value": app_func_audiences},
|
"app_func_audiences": {"value": app_func_audiences},
|
||||||
"name": {"value": self.application_name},
|
"name": {"value": self.application_name},
|
||||||
@ -641,6 +648,7 @@ class Client:
|
|||||||
"multi_tenant_domain": multi_tenant_domain,
|
"multi_tenant_domain": multi_tenant_domain,
|
||||||
"workbookData": {"value": self.workbook_data},
|
"workbookData": {"value": self.workbook_data},
|
||||||
"use_dotnet_agent_functions": {"value": self.use_dotnet_agent_functions},
|
"use_dotnet_agent_functions": {"value": self.use_dotnet_agent_functions},
|
||||||
|
"enable_remote_debugging": {"value": self.host_dotnet_on_windows},
|
||||||
}
|
}
|
||||||
deployment = Deployment(
|
deployment = Deployment(
|
||||||
properties=DeploymentProperties(
|
properties=DeploymentProperties(
|
||||||
@ -1409,6 +1417,11 @@ def main() -> None:
|
|||||||
help="Create a new CLI App Registration if the default app or custom "
|
help="Create a new CLI App Registration if the default app or custom "
|
||||||
"app is not found. ",
|
"app is not found. ",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--host_dotnet_on_windows",
|
||||||
|
action="store_true",
|
||||||
|
help="Use windows runtime for hosting dotnet Azure Function",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if shutil.which("func") is None:
|
if shutil.which("func") is None:
|
||||||
@ -1442,6 +1455,7 @@ def main() -> None:
|
|||||||
use_dotnet_agent_functions=args.use_dotnet_agent_functions,
|
use_dotnet_agent_functions=args.use_dotnet_agent_functions,
|
||||||
cli_app_id=args.cli_app_id,
|
cli_app_id=args.cli_app_id,
|
||||||
auto_create_cli_app=args.auto_create_cli_app,
|
auto_create_cli_app=args.auto_create_cli_app,
|
||||||
|
host_dotnet_on_windows=args.host_dotnet_on_windows,
|
||||||
)
|
)
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
level = logging.DEBUG
|
level = logging.DEBUG
|
||||||
|
Reference in New Issue
Block a user