05 - Infrastructure as Code (Flex Consumption)¶
Deploy repeatable infrastructure with Bicep and parameterized environments.
Prerequisites¶
| Tool | Version | Purpose |
|---|---|---|
| Node.js | 20+ | Local runtime and package execution |
| Azure Functions Core Tools | v4 | Local host and publishing |
| Azure CLI | 2.61+ | Azure resource provisioning and management |
Flex Consumption plan basics
Flex Consumption (FC1) supports VNet integration, identity-based storage, per-function scaling, and remote build workflows.
What You'll Build¶
You will deploy the complete Flex Consumption infrastructure stack from Bicep, including storage, hosting plan, managed identity, and Linux Function App resources.
Infrastructure Context
Plan: Flex Consumption (FC1) | Network: VNet integration with private endpoints
The production Bicep template at infra/flex-consumption/main.bicep includes full VNet integration, private endpoints, and DNS zones.
flowchart TD
BICEP["Bicep Template\ninfra/flex-consumption/main.bicep"] -->|"az deployment group create"| RG[Resource Group]
RG --> MI["User-Assigned\nManaged Identity"]
RG --> PLAN["App Service Plan\nFC1 FlexConsumption"]
RG --> ST["Storage Account\n(no shared key)"]
RG --> FA["Function App\nLinux Node.js 20"]
RG --> VNET["VNet + Subnets\n+ Private Endpoints"]
FA --> PLAN
FA -->|MI auth| ST
FA --> VNET
style BICEP fill:#f39c12,color:#fff
style FA fill:#0078d4,color:#fff flowchart LR
A[Review Bicep template] --> B["az deployment group create"]
B --> C[Verify provisioning] Steps¶
Step 1 - Set variables (if not already set)¶
Step 2 - Review the Bicep template¶
The production template is at infra/flex-consumption/main.bicep. Below is a simplified example showing key Flex Consumption resources:
param location string = resourceGroup().location
param baseName string
var functionAppName = '${baseName}-func'
var storageAccountName = toLower(replace('${baseName}storage', '-', ''))
var appServicePlanName = '${baseName}-plan'
var managedIdentityName = '${baseName}-identity'
var deploymentContainerName = 'deployment-packages'
resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: storageAccountName
location: location
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
properties: {
allowSharedKeyAccess: false
}
}
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: managedIdentityName
location: location
}
resource plan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: appServicePlanName
location: location
sku: {
name: 'FC1'
tier: 'FlexConsumption'
}
properties: {
reserved: true
}
}
resource functionApp 'Microsoft.Web/sites@2024-04-01' = {
name: functionAppName
location: location
kind: 'functionapp,linux'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${managedIdentity.id}': {}
}
}
properties: {
serverFarmId: plan.id
httpsOnly: true
functionAppConfig: {
runtime: {
name: 'node'
version: '20'
}
scaleAndConcurrency: {
maximumInstanceCount: 100
instanceMemoryMB: 2048
}
deployment: {
storage: {
type: 'blobContainer'
value: 'https://${storage.name}.blob.${environment().suffixes.storage}/${deploymentContainerName}'
authentication: {
type: 'UserAssignedIdentity'
userAssignedIdentityResourceId: managedIdentity.id
}
}
}
}
}
}
Flex Consumption vs Consumption Bicep differences
- Uses
FC1/FlexConsumptionSKU instead ofY1/Dynamic - Uses
functionAppConfigblock (notsiteConfig.appSettings) for runtime, scaling, and deployment - Supports
allowSharedKeyAccess: falseon storage (identity-based auth) - Uses blob container for deployment instead of Azure Files
Step 3 - Deploy template¶
az deployment group create \
--resource-group "$RG" \
--template-file infra/flex-consumption/main.bicep \
--parameters baseName=ndflex0410
Step 4 - Verify deployment state¶
az deployment group show \
--resource-group "$RG" \
--name main \
--query "properties.provisioningState" \
--output tsv
Step 5 - Review Flex Consumption-specific notes¶
- The repository template includes full VNet integration with private endpoints and DNS zones. The simplified snippet above omits networking for clarity.
- Flex Consumption routes all traffic through the integrated VNet by default once
virtualNetworkSubnetIdis configured. - Use long-form CLI flags for maintainable runbooks.
Verification¶
Deployment output shows Succeeded:
{
"name": "main",
"properties": {
"provisioningState": "Succeeded",
"mode": "Incremental",
"timestamp": "2026-04-10T00:30:36.0000000Z"
}
}
Next Steps¶
Next: 06 - CI/CD
See Also¶
- Tutorial Overview & Plan Chooser
- Node.js Language Guide
- Platform: Hosting Plans
- Operations: Deployment
- Recipes Index