Skip to content

05 - Infrastructure as Code (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

Consumption plan basics

Consumption (Y1) is serverless with scale-to-zero, up to 200 instances, 1.5 GB memory per instance, and a default 5-minute timeout (max 10 minutes).

What You'll Build

You will deploy a repeatable Consumption infrastructure stack with Bicep and validate successful resource provisioning.

Infrastructure Context

Plan: Consumption (Y1) | Network: Public internet only | VNet: ❌ Not supported

Bicep deploys all resources into a single resource group with public internet access only.

flowchart TD
    BICEP["Bicep Template\ninfra/consumption/main.bicep"] -->|"az deployment group create"| RG[Resource Group]
    RG --> PLAN["App Service Plan\nY1 Dynamic"]
    RG --> ST["Storage Account"]
    RG --> FA["Function App\nLinux Node.js 20"]
    RG --> AI["Application Insights"]
    FA --> PLAN
    FA --> ST
    FA --> AI

    style BICEP fill:#f39c12,color:#fff
    style FA fill:#0078d4,color:#fff
CLI element Explanation
Command(s) az deployment group create"\| RG[Resource
Key flags None
Variables None
Expected result Azure CLI returns provisioning details; confirm the resource name and successful provisioning state before continuing.
flowchart TD
    A[Review Bicep template] --> B["az deployment group create"]
    B --> C[Verify provisioning]
    C --> D[Publish code]
CLI element Explanation
Command(s) az deployment group create"]
Key flags None
Variables None
Expected result Azure CLI returns provisioning details; confirm the resource name and successful provisioning state before continuing.

Steps

Step 1 - Set variables (if not already set)

export RG="rg-func-node-consumption-demo"
export LOCATION="koreacentral"

Step 2 - Review the Bicep template

The production template is at infra/consumption/main.bicep. Below is a minimal example showing the key resources for Consumption (Y1):

param location string = resourceGroup().location
param appName string
param storageName string
var planName = '${appName}-plan'

resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageName
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
}

resource plan 'Microsoft.Web/serverfarms@2024-04-01' = {
  name: planName
  location: location
  sku: {
    name: 'Y1'
    tier: 'Dynamic'
  }
  properties: {
    reserved: true
  }
}

resource functionApp 'Microsoft.Web/sites@2024-04-01' = {
  name: appName
  location: location
  kind: 'functionapp,linux'
  properties: {
    serverFarmId: plan.id
    httpsOnly: true
    siteConfig: {
      linuxFxVersion: 'NODE|20'
      appSettings: [
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'node'
        }
        {
          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: toLower('${appName}-content')
        }
      ]
    }
  }
}

Step 3 - Deploy the template

az deployment group create \
  --resource-group "$RG" \
  --template-file infra/consumption/main.bicep \
  --parameters baseName=ndcons0410
CLI element Explanation
Command(s) az deployment group create
Key flags --resource-group, --template-file, --parameters
Variables $RG
Expected result Azure CLI returns provisioning details; confirm the resource name and successful provisioning state before continuing.

baseName length constraint

The Bicep template appends storage to the baseName parameter to create the storage account name. Storage account names are limited to 24 characters. Keep baseName to ~17 characters or fewer to avoid exceeding this limit. For example, ndcons0410 produces ndcons0410storage (17 chars) which is valid.

Step 4 - Verify provisioning

az deployment group show \
  --resource-group "$RG" \
  --name main \
  --query "properties.provisioningState" \
  --output tsv
CLI element Explanation
Command(s) az deployment group show
Key flags --resource-group, --name, --query, --output
Variables $RG
Expected result Azure CLI returns provisioning details; confirm the resource name and successful provisioning state before continuing.

Step 5 - Publish code to the Bicep-deployed app

# Get the function app name from Bicep outputs
BICEP_APP=$(az deployment group show \
  --resource-group "$RG" \
  --name main \
  --query "properties.outputs.functionAppName.value" \
  --output tsv)

cd apps/nodejs && func azure functionapp publish "$BICEP_APP"
CLI element Explanation
Command(s) az deployment group show
Key flags --resource-group, --name, --query, --output
Variables $RG, $BICEP_APP
Expected result Azure CLI returns provisioning details; confirm the resource name and successful provisioning state before continuing.

Step 6 - Review Consumption-specific notes

  • Use --consumption-plan-location for app creation and expect cold starts under idle periods.
  • Use long-form CLI flags for maintainable runbooks.
  • Keep FUNCTIONS_WORKER_RUNTIME=node across all environments.

Verification

Deployment output shows Succeeded:

{
  "id": "/subscriptions/<subscription-id>/resourceGroups/rg-func-node-consumption-demo/providers/Microsoft.Resources/deployments/main",
  "name": "main",
  "properties": {
    "provisioningState": "Succeeded",
    "mode": "Incremental",
    "outputs": {
      "functionAppName": {
        "type": "String",
        "value": "ndcons0410-func"
      },
      "functionAppUrl": {
        "type": "String",
        "value": "https://ndcons0410-func.azurewebsites.net"
      }
    }
  }
}

Next Steps

Next: 06 - CI/CD

See Also

Sources