Skip to content

Commit

Permalink
App Service - add dotnet-isolated runtime support (#15969)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackofallops authored Mar 23, 2022
1 parent 0ef20db commit 7380ab7
Show file tree
Hide file tree
Showing 14 changed files with 346 additions and 70 deletions.
125 changes: 91 additions & 34 deletions internal/services/appservice/helpers/function_app_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,21 +984,23 @@ func SiteConfigSchemaWindowsFunctionAppComputed() *pluginsdk.Schema {

type ApplicationStackLinuxFunctionApp struct {
// Note - Function Apps differ to Web Apps here. They do not use the named properties in the SiteConfig block and exclusively use the app_settings map
DotNetVersion string `tfschema:"dotnet_version"` // Supported values `3.1`. Version 6 is in preview on Windows Only
NodeVersion string `tfschema:"node_version"` // Supported values `12LTS`, `14LTS`
PythonVersion string `tfschema:"python_version"` // Supported values `3.9`, `3.8`, `3.7`
PowerShellCoreVersion string `tfschema:"powershell_core_version"` // Supported values are `7.0`
JavaVersion string `tfschema:"java_version"` // Supported values `8`, `11`
CustomHandler bool `tfschema:"use_custom_runtime"` // Supported values `true`
Docker []ApplicationStackDocker `tfschema:"docker"` // Needs ElasticPremium or Basic (B1) Standard (S 1-3) or Premium(PxV2 or PxV3) LINUX Service Plan
DotNetVersion string `tfschema:"dotnet_version"` // Supported values `3.1`, `6`.
DotNetIsolated bool `tfschema:"use_dotnet_isolated_runtime"` // Supported values `true` for `dotnet-isolated`, `false` otherwise
NodeVersion string `tfschema:"node_version"` // Supported values `12LTS`, `14LTS`
PythonVersion string `tfschema:"python_version"` // Supported values `3.9`, `3.8`, `3.7`
PowerShellCoreVersion string `tfschema:"powershell_core_version"` // Supported values are `7.0`
JavaVersion string `tfschema:"java_version"` // Supported values `8`, `11`
CustomHandler bool `tfschema:"use_custom_runtime"` // Supported values `true`
Docker []ApplicationStackDocker `tfschema:"docker"` // Needs ElasticPremium or Basic (B1) Standard (S 1-3) or Premium(PxV2 or PxV3) LINUX Service Plan
}

type ApplicationStackWindowsFunctionApp struct {
DotNetVersion string `tfschema:"dotnet_version"` // Supported values `3.1`. Version 6 is in preview on Windows Only
NodeVersion string `tfschema:"node_version"` // Supported values `12LTS`, `14LTS`
JavaVersion string `tfschema:"java_version"` // Supported values `8`, `11`
PowerShellCoreVersion string `tfschema:"powershell_core_version"` // Supported values are `7.0`
CustomHandler bool `tfschema:"use_custom_runtime"` // Supported values `true`
DotNetVersion string `tfschema:"dotnet_version"` // Supported values `3.1`. Version 6 is in preview on Windows Only
DotNetIsolated bool `tfschema:"use_dotnet_isolated_runtime"` // Supported values `true` for `dotnet-isolated`, `false` otherwise
NodeVersion string `tfschema:"node_version"` // Supported values `12LTS`, `14LTS`
JavaVersion string `tfschema:"java_version"` // Supported values `8`, `11`
PowerShellCoreVersion string `tfschema:"powershell_core_version"` // Supported values are `7.0`
CustomHandler bool `tfschema:"use_custom_runtime"` // Supported values `true`
}

type ApplicationStackDocker struct {
Expand All @@ -1021,7 +1023,7 @@ func linuxFunctionAppStackSchema() *pluginsdk.Schema {
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"3.1",
"6",
"6.0",
}, false),
ExactlyOneOf: []string{
"site_config.0.application_stack.0.dotnet_version",
Expand All @@ -1032,7 +1034,22 @@ func linuxFunctionAppStackSchema() *pluginsdk.Schema {
"site_config.0.application_stack.0.docker",
"site_config.0.application_stack.0.use_custom_runtime",
},
Description: "The version of .Net. Possible values are `3.1` and `6`",
Description: "The version of .Net. Possible values are `3.1` and `6.0`",
},

"use_dotnet_isolated_runtime": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: false,
ConflictsWith: []string{
"site_config.0.application_stack.0.python_version",
"site_config.0.application_stack.0.java_version",
"site_config.0.application_stack.0.node_version",
"site_config.0.application_stack.0.powershell_core_version",
"site_config.0.application_stack.0.docker",
"site_config.0.application_stack.0.use_custom_runtime",
},
Description: "Should the DotNet process use an isolated runtime. Defaults to `false`.",
},

"python_version": {
Expand Down Expand Up @@ -1195,6 +1212,11 @@ func linuxFunctionAppStackSchemaComputed() *pluginsdk.Schema {
Computed: true,
},

"use_dotnet_isolated_runtime": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"python_version": {
Type: pluginsdk.TypeString,
Computed: true,
Expand Down Expand Up @@ -1281,6 +1303,19 @@ func windowsFunctionAppStackSchema() *pluginsdk.Schema {
Description: "The version of .Net. Possible values are `3.1` and `6`",
},

"use_dotnet_isolated_runtime": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: false,
ConflictsWith: []string{
"site_config.0.application_stack.0.java_version",
"site_config.0.application_stack.0.node_version",
"site_config.0.application_stack.0.powershell_core_version",
"site_config.0.application_stack.0.use_custom_runtime",
},
Description: "Should the DotNet process use an isolated runtime. Defaults to `false`.",
},

"node_version": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -1360,6 +1395,11 @@ func windowsFunctionAppStackSchemaComputed() *pluginsdk.Schema {
Computed: true,
},

"use_dotnet_isolated_runtime": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"node_version": {
Type: pluginsdk.TypeString,
Computed: true,
Expand Down Expand Up @@ -1515,11 +1555,19 @@ func ExpandSiteConfigLinuxFunctionApp(siteConfig []SiteConfigLinuxFunctionApp, e
if len(linuxSiteConfig.ApplicationStack) > 0 {
linuxAppStack := linuxSiteConfig.ApplicationStack[0]
if linuxAppStack.DotNetVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
linuxSiteConfig.LinuxFxVersion = fmt.Sprintf("DOTNET|%s", linuxAppStack.DotNetVersion)
if linuxAppStack.DotNetIsolated {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet-isolated"),
})
linuxSiteConfig.LinuxFxVersion = fmt.Sprintf("DOTNET-ISOLATED|%s", linuxAppStack.DotNetVersion)
} else {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
linuxSiteConfig.LinuxFxVersion = fmt.Sprintf("DOTNET|%s", linuxAppStack.DotNetVersion)
}
}

if linuxAppStack.NodeVersion != "" {
Expand Down Expand Up @@ -1773,44 +1821,53 @@ func ExpandSiteConfigWindowsFunctionApp(siteConfig []SiteConfigWindowsFunctionAp

if metadata.ResourceData.HasChange("site_config.0.application_stack") && len(windowsSiteConfig.ApplicationStack) > 0 {
if len(windowsSiteConfig.ApplicationStack) > 0 {
linuxAppStack := windowsSiteConfig.ApplicationStack[0]
if linuxAppStack.DotNetVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("DOTNET|%s", linuxAppStack.DotNetVersion)
windowsAppStack := windowsSiteConfig.ApplicationStack[0]
if windowsAppStack.DotNetVersion != "" {
if windowsAppStack.DotNetIsolated {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet-isolated"),
})
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("DOTNET-ISOLATED|%s", windowsAppStack.DotNetVersion)

} else {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("DOTNET|%s", windowsAppStack.DotNetVersion)
}
}

if linuxAppStack.NodeVersion != "" {
if windowsAppStack.NodeVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("node"),
})
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("WEBSITE_NODE_DEFAULT_VERSION"),
Value: utils.String(linuxAppStack.NodeVersion),
Value: utils.String(windowsAppStack.NodeVersion),
})
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("Node|%s", linuxAppStack.NodeVersion)
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("Node|%s", windowsAppStack.NodeVersion)
}

if linuxAppStack.JavaVersion != "" {
if windowsAppStack.JavaVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("java"),
})
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("Java|%s", linuxAppStack.JavaVersion)
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("Java|%s", windowsAppStack.JavaVersion)
}

if linuxAppStack.PowerShellCoreVersion != "" {
if windowsAppStack.PowerShellCoreVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("powershell"),
})
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("PowerShell|%s", linuxAppStack.PowerShellCoreVersion)
windowsSiteConfig.WindowsFxVersion = fmt.Sprintf("PowerShell|%s", windowsAppStack.PowerShellCoreVersion)
}

if linuxAppStack.CustomHandler {
if windowsAppStack.CustomHandler {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("custom"),
Expand Down
57 changes: 37 additions & 20 deletions internal/services/appservice/helpers/function_app_slot_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,44 +727,53 @@ func ExpandSiteConfigWindowsFunctionAppSlot(siteConfig []SiteConfigWindowsFuncti

if metadata.ResourceData.HasChange("site_config.0.application_stack") && len(windowsSlotSiteConfig.ApplicationStack) > 0 {
if len(windowsSlotSiteConfig.ApplicationStack) > 0 {
linuxAppStack := windowsSlotSiteConfig.ApplicationStack[0]
if linuxAppStack.DotNetVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("DOTNET|%s", linuxAppStack.DotNetVersion)
windowsAppStack := windowsSlotSiteConfig.ApplicationStack[0]
if windowsAppStack.DotNetVersion != "" {
if windowsAppStack.DotNetIsolated {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet-isolated"),
})
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("DOTNET-ISOLATED|%s", windowsAppStack.DotNetVersion)

} else {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("DOTNET|%s", windowsAppStack.DotNetVersion)
}
}

if linuxAppStack.NodeVersion != "" {
if windowsAppStack.NodeVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("node"),
})
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("WEBSITE_NODE_DEFAULT_VERSION"),
Value: utils.String(linuxAppStack.NodeVersion),
Value: utils.String(windowsAppStack.NodeVersion),
})
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("Node|%s", linuxAppStack.NodeVersion)
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("Node|%s", windowsAppStack.NodeVersion)
}

if linuxAppStack.JavaVersion != "" {
if windowsAppStack.JavaVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("java"),
})
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("Java|%s", linuxAppStack.JavaVersion)
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("Java|%s", windowsAppStack.JavaVersion)
}

if linuxAppStack.PowerShellCoreVersion != "" {
if windowsAppStack.PowerShellCoreVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("powershell"),
})
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("PowerShell|%s", linuxAppStack.PowerShellCoreVersion)
windowsSlotSiteConfig.WindowsFxVersion = fmt.Sprintf("PowerShell|%s", windowsAppStack.PowerShellCoreVersion)
}

if linuxAppStack.CustomHandler {
if windowsAppStack.CustomHandler {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("custom"),
Expand Down Expand Up @@ -1024,11 +1033,19 @@ func ExpandSiteConfigLinuxFunctionAppSlot(siteConfig []SiteConfigLinuxFunctionAp
if len(linuxSlotSiteConfig.ApplicationStack) > 0 {
linuxAppStack := linuxSlotSiteConfig.ApplicationStack[0]
if linuxAppStack.DotNetVersion != "" {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
linuxSlotSiteConfig.LinuxFxVersion = fmt.Sprintf("DOTNET|%s", linuxAppStack.DotNetVersion)
if linuxAppStack.DotNetIsolated {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet-isolated"),
})
linuxSlotSiteConfig.LinuxFxVersion = fmt.Sprintf("DOTNET-ISOLATED|%s", linuxAppStack.DotNetVersion)
} else {
appSettings = append(appSettings, web.NameValuePair{
Name: utils.String("FUNCTIONS_WORKER_RUNTIME"),
Value: utils.String("dotnet"),
})
linuxSlotSiteConfig.LinuxFxVersion = fmt.Sprintf("DOTNET|%s", linuxAppStack.DotNetVersion)
}
}

if linuxAppStack.NodeVersion != "" {
Expand Down
38 changes: 31 additions & 7 deletions internal/services/appservice/helpers/fx_strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,31 @@ func EncodeFunctionAppLinuxFxVersion(input []ApplicationStackLinuxFunctionApp) *
var appType, appString string
switch {
case appStack.NodeVersion != "":
appType = "Node"
appType = "NODE"
appString = appStack.NodeVersion

case appStack.DotNetVersion != "":
appType = "DotNet"
if appStack.DotNetIsolated {
appType = "DOTNET-ISOLATED"
} else {
appType = "DOTNET"
}
appString = appStack.DotNetVersion

case appStack.PythonVersion != "":
appType = "Python"
appType = "PYTHON"
appString = appStack.PythonVersion

case appStack.JavaVersion != "":
appType = "Java"
appType = "JAVA"
appString = appStack.JavaVersion

case appStack.PowerShellCoreVersion != "":
appType = "PowerShell"
appType = "POWERSHELL"
appString = appStack.PowerShellCoreVersion

case len(appStack.Docker) > 0 && appStack.Docker[0].ImageName != "":
appType = "Docker"
appType = "DOCKER"
dockerCfg := appStack.Docker[0]
if dockerCfg.RegistryURL != "" {
appString = fmt.Sprintf("%s/%s:%s", strings.Trim(dockerCfg.RegistryURL, "/"), dockerCfg.ImageName, dockerCfg.ImageTag)
Expand Down Expand Up @@ -106,6 +115,10 @@ func DecodeFunctionAppLinuxFxVersion(input string) ([]ApplicationStackLinuxFunct
appStack := ApplicationStackLinuxFunctionApp{DotNetVersion: parts[1]}
result = append(result, appStack)

case "dotnet-isolated":
appStack := ApplicationStackLinuxFunctionApp{DotNetVersion: parts[1], DotNetIsolated: true}
result = append(result, appStack)

case "node":
appStack := ApplicationStackLinuxFunctionApp{NodeVersion: parts[1]}
result = append(result, appStack)
Expand Down Expand Up @@ -166,12 +179,19 @@ func EncodeFunctionAppWindowsFxVersion(input []ApplicationStackWindowsFunctionAp
case appStack.NodeVersion != "":
appType = "Node"
appString = appStack.NodeVersion

case appStack.DotNetVersion != "":
appType = "DotNet"
if appStack.DotNetIsolated {
appType = "DotNet-Isolated"
} else {
appType = "DotNet"
}
appString = appStack.DotNetVersion

case appStack.JavaVersion != "":
appType = "Java"
appString = appStack.JavaVersion

case appStack.PowerShellCoreVersion != "":
appType = "PowerShell"
appString = appStack.PowerShellCoreVersion
Expand All @@ -198,6 +218,10 @@ func DecodeFunctionAppWindowsFxVersion(input string) ([]ApplicationStackWindowsF
appStack := ApplicationStackWindowsFunctionApp{DotNetVersion: parts[1]}
result = append(result, appStack)

case "dotnet-isolated":
appStack := ApplicationStackWindowsFunctionApp{DotNetVersion: parts[1], DotNetIsolated: true}
result = append(result, appStack)

case "node":
appStack := ApplicationStackWindowsFunctionApp{NodeVersion: parts[1]}
result = append(result, appStack)
Expand Down
1 change: 1 addition & 0 deletions internal/services/appservice/helpers/web_app_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@ func linuxApplicationStackSchema() *pluginsdk.Schema {
"2.1",
"3.1",
"5.0",
"6.0",
}, false),
ConflictsWith: []string{
"site_config.0.application_stack.0.php_version",
Expand Down
Loading

0 comments on commit 7380ab7

Please sign in to comment.