Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Prepare Azure environments for new workloads—subscriptions, networking, identity, and landing zones
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/functions/bicep.md
1# Functions Bicep Patterns — REFERENCE ONLY23> ⛔ **DO NOT COPY THIS CODE DIRECTLY**4>5> This file contains **reference patterns** for understanding Azure Functions Bicep structure.6> **You MUST use the composition algorithm** to generate infrastructure:7>8> 1. Load `templates/selection.md` to choose the correct base template9> 2. Follow `templates/recipes/composition.md` for the exact algorithm10> 3. Use `functions_template_get` MCP tool to list and fetch templates and write `functionFiles[]` + `projectFiles[]` directly — NEVER hand-write Bicep/Terraform and use `azd init -t <template>`/`func init`/`func new` as fallback when composing multiple recipes and required templates are not found11>12> Hand-writing Bicep from these patterns will result in missing RBAC, incorrect managed identity configuration, and security vulnerabilities.1314## Flex Consumption (Recommended)1516**Use Flex Consumption for new deployments with managed identity (no connection strings).**1718```bicep19resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {20name: '${resourcePrefix}func${uniqueHash}'21location: location22sku: { name: 'Standard_LRS' }23kind: 'StorageV2'24properties: {25minimumTlsVersion: 'TLS1_2'26allowBlobPublicAccess: false27allowSharedKeyAccess: false // Enforce managed identity28}29}3031resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01' = {32parent: storageAccount33name: 'default'34}3536resource deploymentContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {37parent: blobService38name: 'deploymentpackage'39}4041resource appInsights 'Microsoft.Insights/components@2020-02-02' = {42name: 'appi-${uniqueHash}'43location: location44kind: 'web'45properties: {46Application_Type: 'web'47}48}4950resource functionAppPlan 'Microsoft.Web/serverfarms@2024-04-01' = {51name: 'plan-${uniqueHash}'52location: location53sku: {54name: 'FC1'55tier: 'FlexConsumption'56}57properties: {58reserved: true59}60}6162resource functionApp 'Microsoft.Web/sites@2024-04-01' = {63name: '${resourcePrefix}-${serviceName}-${uniqueHash}'64location: location65kind: 'functionapp,linux'66identity: {67type: 'SystemAssigned'68}69properties: {70serverFarmId: functionAppPlan.id71httpsOnly: true72functionAppConfig: {73deployment: {74storage: {75type: 'blobContainer'76value: '${storageAccount.properties.primaryEndpoints.blob}deploymentpackage'77authentication: {78type: 'SystemAssignedIdentity'79}80}81}82scaleAndConcurrency: {83maximumInstanceCount: 10084instanceMemoryMB: 204885}86runtime: {87name: 'python' // or 'node', 'dotnet-isolated'88version: '<version>' // Query latest GA: https://learn.microsoft.com/en-us/azure/azure-functions/supported-languages89}90}91siteConfig: {92appSettings: [93{94name: 'AzureWebJobsStorage__blobServiceUri'95value: storageAccount.properties.primaryEndpoints.blob96}97{98name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'99value: appInsights.properties.ConnectionString100}101{102name: 'FUNCTIONS_EXTENSION_VERSION'103value: '~4'104}105{106name: 'FUNCTIONS_WORKER_RUNTIME'107value: 'python'108}109]110}111}112}113114// Grant Function App access to Storage for runtime115resource storageRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {116name: guid(storageAccount.id, functionApp.id, 'Storage Blob Data Owner')117scope: storageAccount118properties: {119roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')120principalId: functionApp.identity.principalId121principalType: 'ServicePrincipal'122}123}124```125126> 💡 **Key Points:**127>128> - Use `AzureWebJobsStorage__blobServiceUri` instead of connection string129> - Set `allowSharedKeyAccess: false` for enhanced security130> - Use `SystemAssignedIdentity` for deployment authentication131> - Grant `Storage Blob Data Owner` role for full access to blobs, queues, and tables132133## Consumption Plan (Legacy)134135> ⛔ **DO NOT USE** — Y1/Dynamic SKU is deprecated for new deployments.136> **ALWAYS use Flex Consumption (FC1)** for all new Azure Functions.137> The Y1 example below is only for reference when migrating legacy apps.138139**⚠️ Not recommended for new deployments. Use Flex Consumption instead.**140141> 💡 **OS and Slots Matter for Consumption:**142>143> - **Linux Consumption** (`kind: 'functionapp,linux'`, `reserved: true`): Does **not** support deployment slots.144> - **Windows Consumption** (`kind: 'functionapp'`, no `reserved`): Supports **1 staging slot** (2 total including production).145> If a user specifically needs Windows Consumption with a slot, that is supported — use the Windows pattern below.146> For new apps needing slots, prefer **Elastic Premium (EP1)** for better performance and no cold-start issues.147148### Linux Consumption (no slot support)149150```bicep151resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {152name: '${resourcePrefix}func${uniqueHash}'153location: location154sku: { name: 'Standard_LRS' }155kind: 'StorageV2'156}157158resource functionAppPlan 'Microsoft.Web/serverfarms@2022-09-01' = {159name: '${resourcePrefix}-funcplan-${uniqueHash}'160location: location161sku: { name: 'Y1', tier: 'Dynamic' }162properties: { reserved: true }163}164165resource functionApp 'Microsoft.Web/sites@2022-09-01' = {166name: '${resourcePrefix}-${serviceName}-${uniqueHash}'167location: location168kind: 'functionapp,linux'169identity: { type: 'SystemAssigned' }170properties: {171serverFarmId: functionAppPlan.id172httpsOnly: true173siteConfig: {174linuxFxVersion: 'Node|20'175appSettings: [176{ name: 'AzureWebJobsStorage', value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value}' }177{ name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' }178{ name: 'FUNCTIONS_WORKER_RUNTIME', value: 'node' }179{ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING', value: appInsights.properties.ConnectionString }180]181}182}183}184```185186### Windows Consumption (supports 1 staging slot)187188> ⚠️ **Windows Consumption is not recommended for new projects** — consider Flex Consumption or Elastic Premium.189> Use this pattern only for existing Windows apps or when Windows-specific features are required.190191```bicep192resource functionAppPlan 'Microsoft.Web/serverfarms@2022-09-01' = {193name: '${resourcePrefix}-funcplan-${uniqueHash}'194location: location195sku: { name: 'Y1', tier: 'Dynamic' }196// No 'reserved: true' for Windows197}198199resource functionApp 'Microsoft.Web/sites@2022-09-01' = {200name: '${resourcePrefix}-${serviceName}-${uniqueHash}'201location: location202kind: 'functionapp' // Windows (no 'linux' suffix)203identity: { type: 'SystemAssigned' }204properties: {205serverFarmId: functionAppPlan.id206httpsOnly: true207siteConfig: {208appSettings: [209{ name: 'WEBSITE_NODE_DEFAULT_VERSION', value: '~20' }210{ name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' }211{ name: 'FUNCTIONS_WORKER_RUNTIME', value: 'node' }212{ name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING', value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value}' }213{ name: 'WEBSITE_CONTENTSHARE', value: '${toLower(serviceName)}-prod' }214{ name: 'AzureWebJobsStorage', value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value}' }215{ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING', value: applicationInsights.properties.ConnectionString }216]217}218}219}220221// 1 staging slot is supported on Windows Consumption222resource stagingSlot 'Microsoft.Web/sites/slots@2022-09-01' = {223parent: functionApp224name: 'staging'225location: location226kind: 'functionapp'227properties: {228serverFarmId: functionAppPlan.id229siteConfig: {230appSettings: [231{ name: 'WEBSITE_NODE_DEFAULT_VERSION', value: '~20' }232{ name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' }233{ name: 'FUNCTIONS_WORKER_RUNTIME', value: 'node' }234{ name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING', value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value}' }235{ name: 'WEBSITE_CONTENTSHARE', value: '${toLower(serviceName)}-staging' } // MUST differ from production236{ name: 'AzureWebJobsStorage', value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value}' }237{ name: 'APPLICATIONINSIGHTS_CONNECTION_STRING', value: applicationInsights.properties.ConnectionString }238]239}240}241}242243// Sticky settings — do not swap WEBSITE_CONTENTSHARE between slots244resource slotConfigNames 'Microsoft.Web/sites/config@2022-09-01' = {245parent: functionApp246name: 'slotConfigNames'247properties: {248appSettingNames: [249'WEBSITE_CONTENTSHARE'250'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'251]252}253}254```255256## Service Bus Integration (Managed Identity)257258```bicep259resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' existing = {260name: serviceBusNamespaceName261}262263resource functionApp 'Microsoft.Web/sites@2024-04-01' = {264// ... (Function App definition from above)265properties: {266// ... (other properties)267siteConfig: {268appSettings: [269// Storage with managed identity270{271name: 'AzureWebJobsStorage__blobServiceUri'272value: storageAccount.properties.primaryEndpoints.blob273}274// Service Bus with managed identity275{276name: 'SERVICEBUS__fullyQualifiedNamespace'277value: '${serviceBusNamespace.name}.servicebus.windows.net'278}279{280name: 'SERVICEBUS_QUEUE_NAME'281value: serviceBusQueueName282}283// Other settings...284]285}286}287}288289// Grant Service Bus Data Receiver role for triggers290resource serviceBusReceiverRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {291name: guid(serviceBusNamespace.id, functionApp.id, 'Azure Service Bus Data Receiver')292scope: serviceBusNamespace293properties: {294roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0')295principalId: functionApp.identity.principalId296principalType: 'ServicePrincipal'297}298}299300// Grant Service Bus Data Sender role (if function sends messages)301resource serviceBusSenderRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {302name: guid(serviceBusNamespace.id, functionApp.id, 'Azure Service Bus Data Sender')303scope: serviceBusNamespace304properties: {305roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39')306principalId: functionApp.identity.principalId307principalType: 'ServicePrincipal'308}309}310```311312> 💡 **Key Points:**313>314> - Use `SERVICEBUS__fullyQualifiedNamespace` (double underscore) for managed identity315> - Grant `Service Bus Data Receiver` role for reading messages316> - Grant `Service Bus Data Sender` role for sending messages (if needed)317> - Role assignments automatically enable connection via managed identity318319## Premium Plan (No Cold Starts)320321```bicep322resource functionAppPlan 'Microsoft.Web/serverfarms@2022-09-01' = {323name: '${resourcePrefix}-funcplan-${uniqueHash}'324location: location325sku: { name: 'EP1', tier: 'ElasticPremium' }326properties: {327reserved: true328minimumElasticInstanceCount: 1329}330}331```332333## Functions on Azure Container Apps (Aspire)334335> ⚠️ **Important for .NET Aspire:** When deploying Azure Functions to Azure Container Apps with identity-based storage, you must configure `AzureWebJobsSecretStorageType=Files`.336337See [aspire-containerapps.md](aspire-containerapps.md) for complete guidance on Functions running on Azure Container Apps and configuration examples.338