A guide to migrate to Azure Functions Flex Consumption plan hosting. Contains specific steps for secure, identity based, C# Functions with VNet integration. With continuous deployment via Azure DevOps.
A fully working Bicep sample is available at Azure Functions Flex Consumption Samples.
Many app settings and properties are moved to a different place in an Flex Consumption plan or simply depreciated entirely, for a complete overview, see Flex Consumption plan deprecations.
A big change is the introduction of the properties.functionAppConfig
element in Microsoft.Web/sites
, available from versions @2023-12-01
and up.
Of course, the most obvious change is the SKU, on Microsoft.Web/serverfarms@2023-12-01
, the kind
and sku
will look like this:
kind: 'functionapp'
sku: {
tier: 'FlexConsumption'
name: 'FC1'
}
If coming from a premium plan, make sure to remove most properties from the serverfarms
resource, you will end up with just this simple configuration:
properties: {
reserved: true
}
Scaling now is set on the sites
resource, instead of the serverfarms
resource, it might look like this inside the properties
element:
@maxValue(1000)
param maximumInstanceCount int = 100
@allowed([2048, 4096])
param instanceMemoryMB int = 2048
...
functionAppConfig: {
scaleAndConcurrency: {
maximumInstanceCount: maximumInstanceCount
instanceMemoryMB: instanceMemoryMB
}
}
To specify C# properties;
- change app setting
FUNCTIONS_WORKER_RUNTIME_VERSION
=8.0
to resource settingproperties.functionAppConfig.runtime.version
=8.0
. - change app setting
FUNCTIONS_WORKER_RUNTIME
=dotnet-isolated
to resource settingproperties.functionAppConfig.runtime.name
=dotnet-isolated
. - delete
properties.siteConfig.netFrameworkVersion
=v8.0
- if on an old linux plan; delete
properties.siteConfig.LinuxFxVersion
=DOTNET-ISOLATED|8.0
. - if on an old windows plan; delete
properties.siteConfig.windowsFxVersion
=DOTNET-ISOLATED|8.0
.
If coming from an identity-based connection for AzureWebJobsStorage
(host), this still works with identities, but requires a different setup:
- delete app setting
AzureWebJobsStorage__blobServiceUri
- delete app setting
AzureWebJobsStorage__queueServiceUri
- delete app setting
AzureWebJobsStorage__tableServiceUri
- add app setting
AzureWebJobsStorage__accountName
and point to the storage account name of the backend storage. - add
authentication.type
property on the deployment element, as specified under Deployment, this will make sure the connection to the backend uses a managed identity.
If using VNet integration:
- remove the
WEBSITE_VNET_ROUTE_ALL
app setting - remove
properties.vnetImagePullEnabled
- remove
properties.vnetRouteAllEnabled
- remove
properties.vnetContentShareEnabled
- remove
properties.vnetBackupRestoreEnabled
- remove the
Microsoft.Web/sites/networkConfig
resource entirely, it might have looked like this:
resource networkConfig 'Microsoft.Web/sites/networkConfig@2023-01-01' = {
parent: functionApp
name: 'virtualNetwork'
properties: {
subnetResourceId: appServicePlanSubnetId
swiftSupported: true
}
}
- add
properties.virtualNetworkSubnetId
=appServicePlanSubnetId
toMicrosoft.Web/sites
- change delegation of the subnet, so for the resource
Microsoft.Network/virtualNetworks/subnets
;properties.delegations.properties.serviceName
used to beMicrosoft.Web/serverFarms
, now it isMicrosoft.App/environments
. - register the
Microsoft.App
resource provider on subscription level.
If coming from a secure VNet integrated connection for AzureWebJobsStorage
(host), this still works with VNet integration, but requires a different setup:
- delete app setting
WEBSITE_CONTENTOVERVNET
That's all there is to it! You can isolate your storage account completely with private endpoints, and block all public access.
To deploy a C# app, or any other language app, it's completely different to what you are used to, zip deploy isn't what it used to be anymore. You will still zip, but the internal logic will unzip itself. The app will manage all deployments in a storage account using a container. In a Premium plan, managing deployments used to be within a file share:
- delete app setting
WEBSITE_RUN_FROM_PACKAGE
. - if coming from a premium plan: delete app setting
WEBSITE_CONTENTSHARE
. - add a
deployment
element to yourproperties.functionAppConfig
element, it might look like this:
deployment: {
storage: {
type: 'blobContainer'
value: '${storage.properties.primaryEndpoints.blob}${deploymentStorageContainerName}'
authentication: {
type: 'SystemAssignedIdentity'
}
}
}
This setup, with
authentication.type
=SystemAssignedIdentity
, assumes the Function App has data permissions on thedeploymentStorageContainerName
.
- add a deployment container to your backend storage account, and use as specified in the
deploymentStorageContainerName
variable, it might look like this on aMicrosoft.Storage/storageAccounts/blobServices@2023-04-01
resource:
resource container 'containers' = [
for container in containers: {
name: container.name
properties: {
publicAccess: 'None'
}
}
]
To deploy your actual code inside an Azure DevOps environment, deploy steps will be very similar.
Deployment makes use of the Azure Functions Deploy task, with some small changes:
- add the
isFlexConsumption
input and set totrue
. - leave the
deploymentMethod
input at default valueauto
(or omit this setting), instead ofzipDeploy
orrunFromPackage
. - leave the
deployToSlotOrASE
input at default valuefalse
(or omit this setting), instead oftrue
. - set the
appType
tofunctionAppLinux
.
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.