05 - Infrastructure as Code (Premium)¶
Describe your .NET Function App platform using Bicep so provisioning is deterministic and easy to review.
Prerequisites¶
| Tool | Version | Purpose |
|---|---|---|
| .NET SDK | 8.0 (LTS) | Build and run isolated worker functions |
| Azure Functions Core Tools | v4 | Start local host and publish artifacts |
| Azure CLI | 2.61+ | Provision Azure resources and inspect app state |
Premium plan basics
Premium (EP1) keeps at least one warm instance, supports VNet integration, private endpoints, and deployment slots. No cold-start penalty, with up to 100 instances and no execution timeout.
What You'll Build¶
You will define a complete Premium environment in Bicep (storage account, EP1 plan, and Linux Function App for .NET 8 isolated worker), apply required host storage and content share settings, and deploy from your own template.
flowchart TD
A[Bicep template] --> B[az deployment group create]
B --> C[Function App + EP1 Plan + Storage]
C --> D["Build + publish from output dir"] Steps¶
Step 1 - Create a Bicep template for your .NET Function App¶
param location string = resourceGroup().location
param baseName string
var storageName = toLower(replace('${baseName}storage', '-', ''))
var planName = '${baseName}-plan'
var appName = '${baseName}-func'
var contentShareName = toLower(replace('${baseName}-content', '-', ''))
Step 2 - Define Function App runtime settings¶
resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
}
resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: planName
location: location
kind: 'linux'
sku: {
name: 'EP1'
tier: 'ElasticPremium'
}
properties: {
reserved: true
}
}
resource functionApp 'Microsoft.Web/sites@2023-12-01' = {
name: appName
location: location
kind: 'functionapp,linux'
properties: {
serverFarmId: plan.id
httpsOnly: true
siteConfig: {
linuxFxVersion: 'DOTNET-ISOLATED|8.0'
appSettings: [
{ name: 'FUNCTIONS_EXTENSION_VERSION'; value: '~4' }
{ name: 'FUNCTIONS_WORKER_RUNTIME'; value: 'dotnet-isolated' }
{ name: 'AzureWebJobsStorage'; value: 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${listKeys(storage.id, storage.apiVersion).keys[0].value};EndpointSuffix=${environment().suffixes.storage}' }
{ name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'; value: 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${listKeys(storage.id, storage.apiVersion).keys[0].value};EndpointSuffix=${environment().suffixes.storage}' }
{ name: 'WEBSITE_CONTENTSHARE'; value: contentShareName }
]
}
}
}
Premium-specific Bicep settings
sku.name: 'EP1'withtier: 'ElasticPremium'creates a Premium plan with warm instances.linuxFxVersion: 'DOTNET-ISOLATED|8.0'sets the .NET 8 isolated worker runtime.WEBSITE_CONTENTAZUREFILECONNECTIONSTRINGandWEBSITE_CONTENTSHAREare required for Premium plan (uses Azure Files for content storage).
Step 3 - Deploy infrastructure¶
az deployment group create \
--resource-group "$RG" \
--template-file main.bicep \
--parameters baseName="$BASE_NAME"
Step 4 - Deploy application artifact¶
After infrastructure is provisioned, build and publish from the output directory:
cd apps/dotnet
dotnet publish --configuration Release --output ./publish
cd publish
func azure functionapp publish "$APP_NAME" --dotnet-isolated
Must pass --dotnet-isolated flag
When publishing from the compiled output directory, Core Tools cannot detect the project language. Always pass --dotnet-isolated to specify the worker runtime explicitly. Without this flag, the publish may succeed but functions will not be indexed correctly.
Step 5 - Validate infrastructure deployment¶
az deployment group show \
--resource-group "$RG" \
--name main \
--query "properties.provisioningState" \
--output tsv
az functionapp show \
--name "$APP_NAME" \
--resource-group "$RG" \
--output table
Verification¶
Infrastructure deployment output:
ProvisioningState Timestamp
----------------- --------------------------
Succeeded 2026-04-09T18:00:00.000Z
Function app status:
Name State ResourceGroup DefaultHostName
------------------------- ------- ------------------------- ------------------------------------------
func-dnetprem-04100301 Running rg-func-dotnet-prem-demo func-dnetprem-04100301.azurewebsites.net
Next Steps¶
Next: 06 - CI/CD
See Also¶
- Tutorial Overview & Plan Chooser
- .NET Language Guide
- Platform: Hosting Plans
- Operations: Deployment
- Recipes Index