targetScope = 'subscription'
@minLength(1)
@maxLength(64)
@description('Name of the the environment which is used to generate a short unique hash used in all resources.')
param environmentName string
@minLength(1)
@description('Primary location for all resources')
@allowed(['australiaeast', 'eastasia', 'eastus', 'eastus2', 'northeurope', 'southcentralus', 'southeastasia', 'swedencentral', 'uksouth', 'westus2', 'eastus2euap'])
@metadata({
azd: {
type: 'location'
}
})
param location string
param processorServiceName string = ''
param processorUserAssignedIdentityName string = ''
param applicationInsightsName string = ''
param appServicePlanName string = ''
param logAnalyticsName string = ''
param resourceGroupName string = ''
param storageAccountName string = ''
param vNetName string = ''
param disableLocalAuth bool = true
var abbrs = loadJsonContent('./abbreviations.json')
var resourceToken = toLower(uniqueString(subscription().id, environmentName, location))
var tags = { 'azd-env-name': environmentName }
// Organize resources in a resource group
resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: !empty(resourceGroupName) ? resourceGroupName : '${abbrs.resourcesResourceGroups}${environmentName}'
location: location
tags: tags
}
// User assigned managed identity to be used by the Function App to reach storage and service bus
module processorUserAssignedIdentity './core/identity/userAssignedIdentity.bicep' = {
name: 'processorUserAssignedIdentity'
scope: rg
params: {
location: location
tags: tags
identityName: !empty(processorUserAssignedIdentityName) ? processorUserAssignedIdentityName : '${abbrs.managedIdentityUserAssignedIdentities}processor-${resourceToken}'
}
}
// The application backend
module processor './app/processor.bicep' = {
name: 'processor'
scope: rg
params: {
name: !empty(processorServiceName) ? processorServiceName : '${abbrs.webSitesFunctions}processor-${resourceToken}'
location: location
tags: tags
applicationInsightsName: monitoring.outputs.applicationInsightsName
appServicePlanId: appServicePlan.outputs.id
runtimeName: 'node'
runtimeVersion: '20'
storageAccountName: storage.outputs.name
identityId: processorUserAssignedIdentity.outputs.identityId
identityClientId: processorUserAssignedIdentity.outputs.identityClientId
appSettings: {
}
virtualNetworkSubnetId: serviceVirtualNetwork.outputs.appSubnetID
}
}
// Backing storage for Azure functions processor
module storage './core/storage/storage-account.bicep' = {
name: 'storage'
scope: rg
params: {
name: !empty(storageAccountName) ? storageAccountName : '${abbrs.storageStorageAccounts}${resourceToken}'
location: location
tags: tags
containers: [{name: 'deploymentpackage'}]
publicNetworkAccess: 'Disabled'
}
}
var StorageBlobDataOwner = 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b'
var StorageQueueDataContributor = '974c5e8b-45b9-4653-ba55-5f855dd0fb88'
// Allow access from api to blob storage using a managed identity
module blobRoleAssignmentApi 'app/storage-Access.bicep' = {
name: 'blobRoleAssignmentapi'
scope: rg
params: {
storageAccountName: storage.outputs.name
roleDefinitionID: StorageBlobDataOwner
principalID: processorUserAssignedIdentity.outputs.identityPrincipalId
}
}
// Allow access from api to queue storage using a managed identity
module queueRoleAssignmentApi 'app/storage-Access.bicep' = {
name: 'queueRoleAssignmentapi'
scope: rg
params: {
storageAccountName: storage.outputs.name
roleDefinitionID: StorageQueueDataContributor
principalID: processorUserAssignedIdentity.outputs.identityPrincipalId
}
}
module appServicePlan './core/host/appserviceplan.bicep' = {
name: 'appserviceplan'
scope: rg
params: {
name: !empty(appServicePlanName) ? appServicePlanName : '${abbrs.webServerFarms}${resourceToken}'
location: location
tags: tags
sku: {
name: 'FC1'
tier: 'FlexConsumption'
}
}
}
// Virtual Network & private endpoint
module serviceVirtualNetwork 'app/vnet.bicep' = {
name: 'serviceVirtualNetwork'
scope: rg
params: {
location: location
tags: tags
vNetName: !empty(vNetName) ? vNetName : '${abbrs.networkVirtualNetworks}${resourceToken}'
}
}
module servicePrivateEndpoint 'app/storage-PrivateEndpoint.bicep' = {
name: 'servicePrivateEndpoint'
scope: rg
params: {
location: location
tags: tags
virtualNetworkName: !empty(vNetName) ? vNetName : '${abbrs.networkVirtualNetworks}${resourceToken}'
subnetName: serviceVirtualNetwork.outputs.peSubnetName
resourceName: storage.outputs.name
}
}
// Monitor application with Azure Monitor
module monitoring './core/monitor/monitoring.bicep' = {
name: 'monitoring'
scope: rg
params: {
location: location
tags: tags
logAnalyticsName: !empty(logAnalyticsName) ? logAnalyticsName : '${abbrs.operationalInsightsWorkspaces}${resourceToken}'
applicationInsightsName: !empty(applicationInsightsName) ? applicationInsightsName : '${abbrs.insightsComponents}${resourceToken}'
disableLocalAuth: disableLocalAuth
}
}
var monitoringRoleDefinitionId = '3913510d-42f4-4e42-8a64-420c390055eb' // Monitoring Metrics Publisher role ID
// Allow access from processor to application insights using a managed identity
module appInsightsRoleAssignmentApi './core/monitor/appinsights-access.bicep' = {
name: 'appInsightsRoleAssignmentPRocessor'
scope: rg
params: {
appInsightsName: monitoring.outputs.applicationInsightsName
roleDefinitionID: monitoringRoleDefinitionId
principalID: processorUserAssignedIdentity.outputs.identityPrincipalId
}
}
// App outputs
output APPLICATIONINSIGHTS_CONNECTION_STRING string = monitoring.outputs.applicationInsightsConnectionString
output AZURE_LOCATION string = location
output AZURE_TENANT_ID string = tenant().tenantId
output SERVICE_PROCESSOR_NAME string = processor.outputs.SERVICE_PROCESSOR_NAME
output AZURE_FUNCTION_NAME string = processor.outputs.SERVICE_PROCESSOR_NAME