// Provisions the Azure resources this exercise needs: a storage account, a Flex Consumption hosting // plan, and a Function App with its system-assigned managed identity already enabled. Deploy this // template into a resource group you've already created or selected. // // Every resource name is derived from uniqueString(resourceGroup().id), so the template produces the // same globally unique names every time you deploy it into the same resource group. That makes // redeploying into the same resource group idempotent. @description('The Azure region for the deployment. Defaults to the resource group\'s own region.') param location string = resourceGroup().location var resourceToken = uniqueString(resourceGroup().id) var storageAccountName = 'steqp${resourceToken}' var hostingPlanName = 'plan-eqp-${resourceToken}' var functionAppName = 'func-eqp-${resourceToken}' var deploymentContainerName = 'app-package-${take(functionAppName, 32)}-${take(resourceToken, 7)}' resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = { name: storageAccountName location: location sku: { name: 'Standard_LRS' } kind: 'StorageV2' properties: { minimumTlsVersion: 'TLS1_2' supportsHttpsTrafficOnly: true allowBlobPublicAccess: false allowSharedKeyAccess: false networkAcls: { defaultAction: 'Allow' bypass: 'AzureServices' } } } resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2023-05-01' = { parent: storageAccount name: 'default' } resource deploymentContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = { parent: blobService name: deploymentContainerName } resource hostingPlan 'Microsoft.Web/serverfarms@2024-04-01' = { name: hostingPlanName location: location kind: 'functionapp' 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: 'SystemAssigned' } properties: { serverFarmId: hostingPlan.id httpsOnly: true functionAppConfig: { deployment: { storage: { type: 'blobContainer' value: '${storageAccount.properties.primaryEndpoints.blob}${deploymentContainerName}' authentication: { type: 'SystemAssignedIdentity' } } } scaleAndConcurrency: { maximumInstanceCount: 40 instanceMemoryMB: 2048 } runtime: { name: 'dotnet-isolated' version: '8.0' } } siteConfig: { appSettings: [ { name: 'AzureWebJobsStorage__accountName' value: storageAccountName } ] } } dependsOn: [ deploymentContainer ] } // Lets the function app's managed identity read and write blobs in the storage account, which it needs // for host bookkeeping, package deployment, and the timer trigger's schedule checkpoint. resource storageBlobDataOwnerAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(storageAccount.id, functionApp.id, 'StorageBlobDataOwner') scope: storageAccount properties: { roleDefinitionId: subscriptionResourceId( 'Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b' ) principalId: functionApp.identity.principalId principalType: 'ServicePrincipal' } } output functionAppName string = functionApp.name output functionAppDefaultHostName string = functionApp.properties.defaultHostName output functionAppPrincipalId string = functionApp.identity.principalId output storageAccountName string = storageAccountName