Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ Run this command to provision the function app, with any required Azure resource
azd up
```

By default, this sample prompts to enable a virtual network for enhanced security. If you want to deploy without a virtual network without prompting, you can configure `VNET_ENABLED` to `false` before running `azd up`:

```bash
azd env set VNET_ENABLED false
azd up
```

You're prompted to supply these required deployment parameters:

| Parameter | Description |
Expand Down
4 changes: 2 additions & 2 deletions azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

name: functions-quickstart-javascript-azd
metadata:
template: functions-quickstart-javascript-azd@0.0.2-beta
template: functions-quickstart-javascript-azd@1.0.1
services:
processor:
api:
project: .
language: js
host: function
109 changes: 109 additions & 0 deletions infra/app/api.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
param name string
@description('Primary location for all resources & Flex Consumption Function App')
param location string = resourceGroup().location
param tags object = {}
param applicationInsightsName string = ''
param appServicePlanId string
param appSettings object = {}
param runtimeName string
param runtimeVersion string
param serviceName string = 'api'
param storageAccountName string
param deploymentStorageContainerName string
param virtualNetworkSubnetId string = ''
param instanceMemoryMB int = 2048
param maximumInstanceCount int = 100
param identityId string = ''
param identityClientId string = ''
param enableBlob bool = true
param enableQueue bool = false
param enableTable bool = false
param enableFile bool = false

@allowed(['SystemAssigned', 'UserAssigned'])
param identityType string = 'UserAssigned'

var applicationInsightsIdentity = 'ClientId=${identityClientId};Authorization=AAD'
var kind = 'functionapp,linux'

// Create base application settings
var baseAppSettings = {
// Only include required credential settings unconditionally
AzureWebJobsStorage__credential: 'managedidentity'
AzureWebJobsStorage__clientId: identityClientId

// Application Insights settings are always included
APPLICATIONINSIGHTS_AUTHENTICATION_STRING: applicationInsightsIdentity
APPLICATIONINSIGHTS_CONNECTION_STRING: applicationInsights.properties.ConnectionString
}

// Dynamically build storage endpoint settings based on feature flags
var blobSettings = enableBlob ? { AzureWebJobsStorage__blobServiceUri: stg.properties.primaryEndpoints.blob } : {}
var queueSettings = enableQueue ? { AzureWebJobsStorage__queueServiceUri: stg.properties.primaryEndpoints.queue } : {}
var tableSettings = enableTable ? { AzureWebJobsStorage__tableServiceUri: stg.properties.primaryEndpoints.table } : {}
var fileSettings = enableFile ? { AzureWebJobsStorage__fileServiceUri: stg.properties.primaryEndpoints.file } : {}

// Merge all app settings
var allAppSettings = union(
appSettings,
blobSettings,
queueSettings,
tableSettings,
fileSettings,
baseAppSettings
)

resource stg 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
name: storageAccountName
}

resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = if (!empty(applicationInsightsName)) {
name: applicationInsightsName
}

// Create a Flex Consumption Function App to host the API
module api 'br/public:avm/res/web/site:0.15.1' = {
name: '${serviceName}-flex-consumption'
params: {
kind: kind
name: name
location: location
tags: union(tags, { 'azd-service-name': serviceName })
serverFarmResourceId: appServicePlanId
managedIdentities: {
systemAssigned: identityType == 'SystemAssigned'
userAssignedResourceIds: [
'${identityId}'
]
}
functionAppConfig: {
deployment: {
storage: {
type: 'blobContainer'
value: '${stg.properties.primaryEndpoints.blob}${deploymentStorageContainerName}'
authentication: {
type: identityType == 'SystemAssigned' ? 'SystemAssignedIdentity' : 'UserAssignedIdentity'
userAssignedIdentityResourceId: identityType == 'UserAssigned' ? identityId : ''
}
}
}
scaleAndConcurrency: {
instanceMemoryMB: instanceMemoryMB
maximumInstanceCount: maximumInstanceCount
}
runtime: {
name: runtimeName
version: runtimeVersion
}
}
siteConfig: {
alwaysOn: false
}
virtualNetworkSubnetId: !empty(virtualNetworkSubnetId) ? virtualNetworkSubnetId : null
appSettingsKeyValuePairs: allAppSettings
}
}

output SERVICE_API_NAME string = api.outputs.name
// Ensure output is always string, handle potential null from module output if SystemAssigned is not used
output SERVICE_API_IDENTITY_PRINCIPAL_ID string = identityType == 'SystemAssigned' ? api.outputs.?systemAssignedMIPrincipalId ?? '' : ''
44 changes: 0 additions & 44 deletions infra/app/processor.bicep

This file was deleted.

110 changes: 110 additions & 0 deletions infra/app/rbac.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
param storageAccountName string
param appInsightsName string
param managedIdentityPrincipalId string // Principal ID for the Managed Identity
param userIdentityPrincipalId string = '' // Principal ID for the User Identity
param allowUserIdentityPrincipal bool = false // Flag to enable user identity role assignments
param enableBlob bool = true
param enableQueue bool = false
param enableTable bool = false

// Define Role Definition IDs internally
var storageRoleDefinitionId = 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b' //Storage Blob Data Owner role
var queueRoleDefinitionId = '974c5e8b-45b9-4653-ba55-5f855dd0fb88' // Storage Queue Data Contributor role
var tableRoleDefinitionId = '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3' // Storage Table Data Contributor role
var monitoringRoleDefinitionId = '3913510d-42f4-4e42-8a64-420c390055eb' // Monitoring Metrics Publisher role ID

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
name: storageAccountName
}

resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = {
name: appInsightsName
}

// Role assignment for Storage Account (Blob) - Managed Identity
resource storageRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableBlob) {
name: guid(storageAccount.id, managedIdentityPrincipalId, storageRoleDefinitionId) // Use managed identity ID
scope: storageAccount
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageRoleDefinitionId)
principalId: managedIdentityPrincipalId // Use managed identity ID
principalType: 'ServicePrincipal' // Managed Identity is a Service Principal
}
}

// Role assignment for Storage Account (Blob) - User Identity
resource storageRoleAssignment_User 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableBlob && allowUserIdentityPrincipal && !empty(userIdentityPrincipalId)) {
name: guid(storageAccount.id, userIdentityPrincipalId, storageRoleDefinitionId)
scope: storageAccount
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageRoleDefinitionId)
principalId: userIdentityPrincipalId // Use user identity ID
principalType: 'User' // User Identity is a User Principal
}
}

// Role assignment for Storage Account (Queue) - Managed Identity
resource queueRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableQueue) {
name: guid(storageAccount.id, managedIdentityPrincipalId, queueRoleDefinitionId) // Use managed identity ID
scope: storageAccount
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', queueRoleDefinitionId)
principalId: managedIdentityPrincipalId // Use managed identity ID
principalType: 'ServicePrincipal' // Managed Identity is a Service Principal
}
}

// Role assignment for Storage Account (Queue) - User Identity
resource queueRoleAssignment_User 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableQueue && allowUserIdentityPrincipal && !empty(userIdentityPrincipalId)) {
name: guid(storageAccount.id, userIdentityPrincipalId, queueRoleDefinitionId)
scope: storageAccount
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', queueRoleDefinitionId)
principalId: userIdentityPrincipalId // Use user identity ID
principalType: 'User' // User Identity is a User Principal
}
}

// Role assignment for Storage Account (Table) - Managed Identity
resource tableRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableTable) {
name: guid(storageAccount.id, managedIdentityPrincipalId, tableRoleDefinitionId) // Use managed identity ID
scope: storageAccount
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', tableRoleDefinitionId)
principalId: managedIdentityPrincipalId // Use managed identity ID
principalType: 'ServicePrincipal' // Managed Identity is a Service Principal
}
}

// Role assignment for Storage Account (Table) - User Identity
resource tableRoleAssignment_User 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (enableTable && allowUserIdentityPrincipal && !empty(userIdentityPrincipalId)) {
name: guid(storageAccount.id, userIdentityPrincipalId, tableRoleDefinitionId)
scope: storageAccount
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', tableRoleDefinitionId)
principalId: userIdentityPrincipalId // Use user identity ID
principalType: 'User' // User Identity is a User Principal
}
}

// Role assignment for Application Insights - Managed Identity
resource appInsightsRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(applicationInsights.id, managedIdentityPrincipalId, monitoringRoleDefinitionId) // Use managed identity ID
scope: applicationInsights
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', monitoringRoleDefinitionId)
principalId: managedIdentityPrincipalId // Use managed identity ID
principalType: 'ServicePrincipal' // Managed Identity is a Service Principal
}
}

// Role assignment for Application Insights - User Identity
resource appInsightsRoleAssignment_User 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (allowUserIdentityPrincipal && !empty(userIdentityPrincipalId)) {
name: guid(applicationInsights.id, userIdentityPrincipalId, monitoringRoleDefinitionId)
scope: applicationInsights
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', monitoringRoleDefinitionId)
principalId: userIdentityPrincipalId // Use user identity ID
principalType: 'User' // User Identity is a User Principal
}
}
20 changes: 0 additions & 20 deletions infra/app/storage-Access.bicep

This file was deleted.

Loading