Set Diagnostic Setting for Application Insights - azure

I have created a diagnostic setting for a Log Analytics Workspace.
I'd also like to create and automate a diagnostic setting for workspace-based in Application Insights.
However, I am not sure if that makes sense.
I have created a diagnostic setting as followed:
resource appDiagnostics 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
name: appSettingName
scope: applicationInsights
properties: {
storageAccountId: storageAccountId
logs: [
{
category: 'Metrics'
enabled: true
}
{
category: 'Dependencies'
enabled: true
}
{
category: 'Exceptions'
enabled: true
}
{
category: 'PageViews'
enabled: true
}
{
category: 'PerformanceCounters'
enabled: true
}
{
category: 'Requests'
enabled: true
}
{
category: 'SystemEvents'
enabled: true
}
{
category: 'Traces'
enabled: true
}
]
metrics: [
{
category: 'AllMetrics'
enabled: true
}
]
}
}
However, I always get an error that my log categories are not valid. Is it because the data is double?

If you look at Azure Monitor Logs references, you will see that all log names have the App prefix so you should be able to do something like that:
var logTypes = [
'AppMetrics'
'AppDependencies'
'AppExceptions'
'AppPageViews'
'AppPerformanceCounters'
'AppRequests'
'AppSystemEvents'
'AppTraces'
'AppAvailabilityResults'
'AppBrowserTimings'
'AppEvents'
]
resource appDiagnostics 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
name: appSettingName
scope: applicationInsights
properties: {
storageAccountId: storageAccountId
logs: [for logType in logTypes: {
category: logType
enabled: true
}]
metrics: [
{
category: 'AllMetrics'
enabled: true
}
]
}
}

I also got the same error when I executed in my environment.
First of all, if you are trying to enable diagnostic settings(components) for any resource (Eg: Application Insights), Create a new workspace-based application insights and add that resource in the code with the existing keyword as shown below.
resource component 'Microsoft.Insights/components#2020-02-02' existing = {
name: 'new'
}
Application Insights:
Refer MsDoc.
And
Verify the list of supported categories as #Thomas has also given, check the prefix and modify accordingly.
I've taken your code and made a few changes and enabled diagnostic settings for application insights successfully.
param workspaceId string
resource storageAccount 'Microsoft.Storage/storageAccounts#2021-09-01' existing = {
name: 'newstoragejahnavi'
}
resource component 'Microsoft.Insights/components#2020-02-02' existing = {
name: 'new'
}
resource appdiagnostics 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
name: 'newsetting'
scope: component
properties: {
storageAccountId: storageAccount.id
workspaceId: workspaceId
logs: [
{
category: 'AppDependencies'
categoryGroup: ''
Retentiondays: 'xx'
enabled: true
}
{
category: 'AppExceptions'
categoryGroup: ''
Retentiondays: 'xx'
enabled: true
}
{
category: 'AppPageViews'
categoryGroup: ''
Retentiondays: 'xx'
enabled: true
}
{
category: 'AppPerformanceCounters'
categoryGroup: ''
Retentiondays: 'xx'
enabled: true
}
{
category: 'AppRequests'
categoryGroup: ''
Retentiondays: 'xx'
enabled: true
}
{
category: 'AppSystemEvents'
categoryGroup: ''
Retentiondays: 'xx'
enabled: true
}
{
category: 'AppTraces'
categoryGroup: ''
Retentiondays: 'xx'
enabled: true
}
]
metrics: [
{
category: 'Allmetrics'
enabled: true
}
]
}
}
Deployment succeeded:
Output:

Related

I am trying to deploy a Logic-App with a Service-Bus Deploy to azure app using Bicep template

I am trying to deploy a bicep template to create a logic app and service bus using VS Code. But When I am trying to deploy the Bicep to azure portal
I am getting bad request error
enter image description here
Here is my Bicep look like
param prefix string
param location string = resourceGroup().location
param sendGridApiKey string
resource serviceBus 'Microsoft.ServiceBus/namespaces#2021-11-01' existing = {
name: '${prefix}sb'
}
resource serviceBusConnection 'Microsoft.Web/connections#2016-06-01' = {
name: '${prefix}sbconn'
location: location
properties: {
displayName: '${prefix}sb'
api: {
id: '${subscription().id}/providers/Microsoft.Web/locations/${location}/managedApis/servicebus'
}
parameterValueSet: {
name: 'managedIdentityAuth'
values: {
namespaceEndpoint: {
value: 'sb://${serviceBus.name}.servicebus.windows.net'
}
}
}
}
}
resource sendGridConnection 'Microsoft.Web/connections#2016-06-01' = {
name: '${prefix}sndgrdconn'
location: location
properties: {
displayName: '${prefix}sndgrdconn'
api: {
id: '${subscription().id}/providers/Microsoft.Web/locations/${location}/managedApis/sendgrid'
}
parameterValues: {
apiKey: sendGridApiKey
}
}
}
resource logicAppEmailSend 'Microsoft.Logic/workflows#2019-05-01' = {
name: '${prefix}logic-EmailSend'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
state: 'Enabled'
definition: {
'$schema': 'https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#'
contentVersion: '1.0.0.0'
parameters: {
'$connections': {
defaultValue: {}
type: 'Object'
}
}
}
}
}
I have tried a lot but didn't find the error
thanks in advance.
I have modified a bit of code in the given code so it's working, and I have deployed the bicep file using VS Code to Azure
{subscription().id}/providers/Microsoft.Web/locations/{location}/servicebus
I have changed the above path to
{subscription().id}/providers/Microsoft.Web/locations/{location}/managedApis/servicebus
Thanks to #mattruma for Bicep template
param prefix string
param location string = resourceGroup().location
param sendGridApiKey string
resource serviceBus 'Microsoft.ServiceBus/namespaces#2021-11-01' existing = {
name: '${prefix}sb'
}
resource serviceBusConnection 'Microsoft.Web/connections#2016-06-01' = {
name: '${prefix}sbconn'
location: location
properties: {
displayName: '${prefix}sb'
api:
{
id: '${subscription().id}/providers/Microsoft.Web/locations/${location}/managedApis/servicebus'
}
parameterValueSet:
{
name: 'managedIdentityAuth'
values:
{
namespaceEndpoint:
{
value: 'sb://${serviceBus.name}.servicebus.windows.net'
}
}
}
}
}
resource logicAppEmailSend 'Microsoft.Logic/workflows#2019-05-01' = {
name: '${prefix}logic-EmailSend'
location: location
identity: {
type: 'SystemAssigned'
}
properties:
{
state: 'Enabled'
definition:
{
'$schema': 'https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#'
contentVersion: '1.0.0.0'
parameters:
{
'$connections': {
defaultValue: { }
type: 'Object'
}
}
triggers:
{
'When_a_message_is_received_in_a_queue_(auto-complete)': {
recurrence:
{
frequency: 'Minute'
interval: 3
}
evaluatedRecurrence:
{
frequency: 'Minute'
interval: 3
}
type: 'ApiConnection'
inputs:
{
host:
{
connection:
{
name: '#parameters(\'$connections\')[\'servicebus\'][\'connectionId\']'
}
}
method: 'get'
path: '/#{encodeURIComponent(encodeURIComponent(\'emailsend\'))}/messages/head'
queries:
{
queueType: 'Main'
}
}
}
}
actions:
{
'Dead-letter_the_message_in_a_queue': {
runAfter:
{
Send_email: [
'Failed'
'TimedOut'
]
}
type: 'ApiConnection'
inputs:
{
host:
{
connection:
{
name: '#parameters(\'$connections\')[\'servicebus\'][\'connectionId\']'
}
}
method: 'post'
path: '/#{encodeURIComponent(encodeURIComponent(\'emailsend\'))}/messages/deadletter'
queries:
{
deadLetterErrorDescription: ''
deadLetterReason: ''
lockToken: '#triggerBody()?[\'LockToken\']'
sessionId: '#triggerBody()?[\'SessionId\']'
}
}
}
Parse_message:
{
runAfter: { }
type: 'ParseJson'
inputs:
{
content: '#base64ToString(triggerBody()?[\'ContentData\'])'
schema:
{
properties:
{
body:
{
type: 'string'
}
subject:
{
type: 'string'
}
to:
{
type: 'string'
}
}
type: 'object'
}
}
}
Send_email:
{
runAfter:
{
Parse_message: [
'Succeeded'
]
}
type: 'ApiConnection'
inputs:
{
body:
{
from: 'someone#somewhere.com'
fromname: 'Someone'
ishtml: true
subject: '#body(\'Parse_message\')?[\'subject\']'
text: '<p>#{body(\'Parse_message\')?[\'body\']}</p>'
to: '#body(\'Parse_message\')?[\'to\']'
}
host:
{
connection:
{
name: '#parameters(\'$connections\')[\'sendgrid\'][\'connectionId\']'
}
}
method: 'post'
path: '/v4/mail/send'
}
}
}
outputs: { }
}
parameters:
{
'$connections': {
value:
{
servicebus:
{
connectionId: serviceBusConnection.id
connectionName: serviceBusConnection.name
connectionProperties: {
authentication:
{
type: 'ManagedServiceIdentity'
}
}
id: '${subscription().id}/providers/Microsoft.Web/locations/${location}/managedApis/servicebus'
}
}
}
}
}
}
After successfully deploying to azure portal
Click on Goto resource group it will redirect to below page

How to reference System Assigned Identity in Bicep when deploying Key Vault Access Policy

For a project I want to deploy three related resources to Azure through Bicep templates: 1) App Service with System Assigned Managed Identity, 2) Key Vault and 3) Access policy for the App Service (step 1) to the Key Vault (step 2).
The AppService deployment outputs the principalId of the System Assigned Identity which is then later on used when deploying the KeyVaultAccessPolicy.
However, when I run the AZ CLI (az deployment sub create --location WestEurope --template-file ./main.bicep --parameters ./parameters/parameters-dev.json)
to deploy this to Azure I get the following error:
'The language expression property 'outputs' doesn't exist, available properties are 'templateHash, parameters, mode, provisioningState, timestamp, duration, correlationId, providers, dependencies, outputResources'.
Does anyone have an idea why referencing the principalId of the App Service does not work here? Many thanks for any help.
Modules and main.bicep:
main.bicep
module appService 'modules/appService.bicep' = {
name: 'deployAppService'
scope: resourceGroup(appServiceResourceGroup)
params: {
name: appServiceName
location: appServiceLocation
alwaysOn: appServiceAlwaysOn
apimIpAddress: appServiceApimIpAddress
appServicePlanResourceGroup: appServicePlanResourceGroup
appServicePlanName: appServicePlanName
}
}
module keyVault 'modules/keyVault.bicep' = {
name: 'deployKeyVault'
scope: resourceGroup(appServiceResourceGroup)
params: {
name: keyVaultName
dependsOn: [ appService ]
location: appServiceLocation
}
}
module keyVaultAccessPolicy 'modules/keyVaultAccessPolicy.bicep' = {
name: 'deployKeyVaultAccessPolicy'
scope: resourceGroup(appServiceResourceGroup)
params: {
name: '${appServiceName}-ap'
dependsOn: [ keyVault ]
objectId: appService.outputs.appServiceManagedIdentity
}
}
appService.bicep
resource appService 'Microsoft.Web/sites#2020-12-01' = {
name: name
location: location
kind: 'app'
identity: {
type: 'SystemAssigned'
}
properties: {
serverFarmId: '${subscription().id}/resourceGroups/${appServicePlanResourceGroup}/providers/Microsoft.Web/serverfarms/${appServicePlanName}'
enabled: true
}
}
output appServiceManagedIdentity string = appService.identity.principalId
keyVault.bicep
resource keyVault 'Microsoft.KeyVault/vaults#2022-07-01' = {
name: name
location: location
dependsOn: dependsOn
properties: {
enabledForDeployment: true
enabledForTemplateDeployment: true
enabledForDiskEncryption: true
tenantId: subscription().tenantId
accessPolicies: []
sku: {
name: 'standard'
family: 'A'
}
}
}
keyVaultAccessPolicy.bicep
resource keyVaultAccessPolicy 'Microsoft.KeyVault/vaults/accessPolicies#2022-07-01' = {
name: name
dependsOn: dependsOn
properties: {
accessPolicies: [
{
tenantId: subscription().tenantId
objectId: objectId
permissions: {
secrets: [
'get'
]
}
}
]
}
}
Already found the answer:
I missed that modules already contain an dependsOn property and so there is no need to pass the dependencies as param.
The KeyVaultAccessPolicy's name did not contain a reference to the parent resource (KeyVault), see name: '${keyVaultName}/add' below
See working modules and main.bicep below:
main.bicep
module appService 'modules/appService.bicep' = {
name: 'deployAppService'
scope: resourceGroup(appServiceResourceGroup)
params: {
name: appServiceName
location: appServiceLocation
alwaysOn: appServiceAlwaysOn
apimIpAddress: appServiceApimIpAddress
appServicePlanResourceGroup: appServicePlanResourceGroup
appServicePlanName: appServicePlanName
}
}
module keyVault 'modules/keyVault.bicep' = {
scope: resourceGroup(appServiceResourceGroup)
name: 'keyVaultDeploy'
params: {
location: appServiceLocation
name: keyVaultName
}
}
module keyVaultAccessPolicy 'modules/keyVaultAccessPolicy.bicep' = {
scope: resourceGroup(appServiceResourceGroup)
name: 'keyVaultAccessPolicyDeploy'
dependsOn: [
keyVault
]
params: {
keyVaultName: keyVaultName
objectId: appService.outputs.appServiceManagedIdentity
}
}
appService.bicep
resource appService 'Microsoft.Web/sites#2020-12-01' = {
name: name
location: location
kind: 'app'
identity: {
type: 'SystemAssigned'
}
properties: {
// left out
}
}
output appServiceManagedIdentity string = appService.identity.principalId
keyVault.bicep
resource keyVault 'Microsoft.KeyVault/vaults#2022-07-01' = {
name: name
location: location
properties: {
enabledForDeployment: true
enabledForTemplateDeployment: true
enabledForDiskEncryption: true
tenantId: subscription().tenantId
accessPolicies: []
sku: {
name: 'standard'
family: 'A'
}
}
}
keyVaultAccessPolicy.bicep
resource keyVaultAccessPolicy 'Microsoft.KeyVault/vaults/accessPolicies#2022-07-01' = {
name: '${keyVaultName}/add'
properties: {
accessPolicies: [
{
tenantId: subscription().tenantId
objectId: objectId
permissions: {
secrets: [
'get'
]
}
}
]
}
}
Just for a heads up you don't need to pass these stuffs with parameters.
Just use the existing tag with the scope it will be easier to get datafrom any resource.
https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/existing-resource#different-scope

Azure function app's signalr_extension is not populated to use in signalR upstreams when creating a function app by Bicep

I created an Azure Function App by Bicep and tried to get the signalr_extension's value to use in the "upstream" configuration section of a serverless Azure SignalR Service. This is how I try to obtain this value in Bicep:
var signalRKey = listKeys(resourceId('Microsoft.Web/sites/host', funcAppName, 'default'), '2022-03-01').systemkeys.signalr_extension
This is how I configure the signalR service's upstream:
urlTemplate: 'https://${funcAppName}.azurewebsites.net/runtime/webhooks/signalr?code=${signalRKey}'
Running the bicep templates leads to the failure below:
Encountered an error (ServiceUnavailable) from host runtime.
When I remove the {signalRKey} from urlTemplate and replace it with a fictitious hard-coded value, the signalR is provisioned successfully.
The other thing that I noticed was that the singalr_extension key value was not populated after the function app was provisioned.
What am I missing in this exercise?
This feature is not available and feasible in App Service Plans. The signalr_extension must be populated manually after deploying the function app and signalR.
The signalr_extension is only created once you've deployed your function app with a SignalRTrigger function.
You can generate this key upfront if you're deploying the Function App and signalR service at the same time:
param functionAppName string
// Create the function app key for signalR
resource signalRKey 'Microsoft.Web/sites/host/systemkeys#2021-03-01' = {
name: '${functionAppName}/default/signalr_extension'
properties: {
name: 'signalr_extension'
}
}
The ARM API to generate function keys is just pointing to the function app API so it could take some time before it become available (see issue on github).
I managed to get this working consistently by deploying the systemkey and signalr using module.
Also for function app running on linux, the AzureWebJobsStorage setting is mandatory.
functionapp-systemkey.bicep module:
param functionAppName string
param keyName string
resource signalRKey 'Microsoft.Web/sites/host/systemkeys#2021-03-01' = {
name: '${functionAppName}/default/${keyName}'
properties: {
name: keyName
}
}
signalr.bicep module:
param location string = resourceGroup().location
param signalRName string
param functionAppName string
resource signalR 'Microsoft.SignalRService/signalR#2022-02-01' = {
name: signalRName
location: location
sku: {
name: 'Free_F1'
tier: 'Free'
capacity: 1
}
properties: {
features: [
{
flag: 'ServiceMode'
value: 'Serverless'
}
{
flag: 'EnableConnectivityLogs'
value: 'true'
}
]
cors: {
allowedOrigins: [
'*'
]
}
tls: {
clientCertEnabled: false
}
upstream: {
templates: [
{
hubPattern: '*'
eventPattern: '*'
categoryPattern: '*'
auth: {
type: 'None'
}
urlTemplate: 'https://${signalRName}.azurewebsites.net/runtime/webhooks/signalr?code=${listKeys(resourceId('Microsoft.Web/sites/host', functionAppName, 'default'), '2022-03-01').systemkeys.signalr_extension}'
}
]
}
}
}
main.bicep:
param location string = resourceGroup().location
param storageName string
param appServicePlanName string
param functionAppName string
param signalRName string
resource storage 'Microsoft.Storage/storageAccounts#2021-09-01' = {
name: storageName
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
properties: {
supportsHttpsTrafficOnly: true
minimumTlsVersion: 'TLS1_2'
}
}
resource appServicePlan 'Microsoft.Web/serverfarms#2021-03-01' = {
name: appServicePlanName
location: location
sku: {
name: 'Y1'
tier: 'Dynamic'
size: 'Y1'
family: 'Y'
capacity: 0
}
kind: 'functionapp'
properties: {
perSiteScaling: false
elasticScaleEnabled: false
maximumElasticWorkerCount: 1
isSpot: false
reserved: true
isXenon: false
targetWorkerCount: 0
targetWorkerSizeId: 0
zoneRedundant: false
}
}
resource functionApp 'Microsoft.Web/sites#2021-03-01' = {
name: functionAppName
location: location
kind: 'functionapp,linux'
properties: {
serverFarmId: appServicePlan.id
clientAffinityEnabled: false
clientCertEnabled: false
httpsOnly: true
siteConfig:{
linuxFxVersion: 'DOTNET|6.0'
use32BitWorkerProcess: true
ftpsState: 'FtpsOnly'
cors: {
allowedOrigins: [
'https://portal.azure.com'
]
supportCredentials: false
}
minTlsVersion: '1.2'
appSettings: [
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'dotnet'
}
{
name: 'AzureWebJobsStorage'
value: 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${listKeys(storage.id, '2019-06-01').keys[0].value};EndpointSuffix=core.windows.net;'
}
]
}
}
}
var signalrKeyName = 'signalr_extension'
module signalrKey 'modules/functionapp-systemkey.bicep' = {
name: '${functionAppName}-systemkey-${signalrKeyName}'
params: {
functionAppName: functionApp.name
keyName: signalrKeyName
}
}
module signalr 'modules/signalr.bicep' = {
name: signalRName
params: {
location: location
functionAppName: functionApp.name
signalRName: signalRName
}
dependsOn:[
signalrKey
]
}

How to populate Azure SignalR Service's upstream code in Bicep

I have a Bicep template to create an Azure SignalR Service per the following script. How can I obtain the upstream's code value within the bicep template and populate the urlTemplate's code value based on it? (the keyword TBD exhibits the exact spot in the following code.)
targetScope = 'resourceGroup'
param location string = resourceGroup().location
param signalRName string
resource signalR 'Microsoft.SignalRService/signalR#2022-02-01' = {
name: signalRName
location: location
kind: 'SignalR'
sku: {
name: 'Free_F1'
tier: 'Free'
capacity: 1
}
properties: {
features: [
{
flag: 'ServiceMode'
value: 'Serverless'
}
{
flag: 'EnableConnectivityLogs'
value: 'true'
}
{
flag: 'EnableMessagingLogs'
value: 'true'
}
{
flag: 'EnableLiveTrace'
value: 'true'
}
]
liveTraceConfiguration: {
enabled: 'true'
categories: [
{
name: 'ConnectivityLogs'
enabled: 'true'
}
{
name: 'MessagingLogs'
enabled: 'true'
}
{
name: 'HttpRequestLogs'
enabled: 'true'
}
]
}
cors: {
allowedOrigins: [
'*'
]
}
upstream: {
templates: [
{
hubPattern: '*'
eventPattern: '*'
categoryPattern: '*'
auth: {
type: 'None'
}
urlTemplate: 'https://${signalRName}.azurewebsites.net/runtime/webhooks/signalr?code=TBD'
}
]
}
}
}
I'm assuming that you are using a function app that has the same name as your signalR service.
Looking at the documentation:
The url always looks like that <Function_App_URL>/runtime/webhooks/signalr?code=<API_KEY>
the API_KEY is a function app systemkey called signalr_extension.
So you should be able to retrieve the key and use it like that:
var signalRKey = listKeys(resourceId('Microsoft.Web/sites/host', signalRName, 'default'), '2022-03-01').systemkeys.signalr_extension
resource signalR 'Microsoft.SignalRService/signalR#2022-02-01' = {
name: signalRName
...
properties: {
...
upstream: {
templates: [
{
...
urlTemplate: 'https://${signalRName}.azurewebsites.net/runtime/webhooks/signalr?code=${signalRKey}'
}
]
}
}
}

child resources in nested resource in Bicep

I am looking for solution where I can create multiple storage accounts and create child resources like blob for each storage accounts using loops in Bicep.I was able to deploy multiple storage accounts but not getting good examples or documentation on how to create child resources for iterated resources in bicep
#allowed([
'CACN'
'CAEA'
'USE2'
'USCN'
])
param regionCode string
param mandatoryTags object
param sku object = {
name: 'Standard_LRS'
tier: 'Standard'
}
param identity object = {
type: 'SystemAssigned'
}
#allowed([
'None'
'Logging'
'Metrics'
'AzureServices'
])
param bypass string = 'AzureServices'
// array of storage account names
param storageAccounts array
// variables
var kind = 'StorageV2'
var varHTTPSOnly = true
var varEnableNFSv3 = false
var varAllowBlobPublicAccess = false
var tlsVersion = 'TLS1_2'
var enableADLSgen2 = false
resource storageAccountResources 'Microsoft.Storage/storageAccounts#2021-02-01' = [for storageName in storageAccounts: {
name: storageName
location: resourceGroup().location
kind: kind
sku: sku
tags: mandatoryTags
identity: identity
properties: {
accessTier: 'Hot'
supportsHttpsTrafficOnly: varHTTPSOnly
isHnsEnabled: enableADLSgen2
minimumTlsVersion: tlsVersion
isNfsV3Enabled: varEnableNFSv3
allowBlobPublicAccess: varAllowBlobPublicAccess
// network security controls
networkAcls: {
bypass: bypass
defaultAction: 'Deny'
resourceAccessRules: []
virtualNetworkRules: []
ipRules: []
}
routingPreference: {
routingChoice: 'MicrosoftRouting'
publishMicrosoftEndpoints: false
publishInternetEndpoints: false
}
encryption: {
services: {
blob: {
enabled: true
keyType: 'Account'
}
file: {
enabled: true
keyType: 'Account'
}
table: {
enabled: true
keyType: 'Account'
}
queue: {
enabled: true
keyType: 'Account'
}
}
keySource: 'Microsoft.Storage'
}
}
}]
output stgOutput array = [for (name, i) in storageAccounts: {
name: storageAccounts[i].name
}]
resource ${storageName}_default 'Microsoft.Storage/storageAccounts/blobServices#2021-04-01' = {
name: 'default'
properties: {
changeFeed: {
enabled: false
}
restorePolicy : {
enabled: false
}
containerDeleteRetentionPolicy: {
enabled: true
days: 7
}
cors: {
corsRules: []
}
deleteRetentionPolicy: {
enabled: true
days: 7
}
isVersioningEnabled: true
}
}
Looking at the documentation (Iteration for a child resource), you should be able to use an iterator :
resource blobServices 'Microsoft.Storage/storageAccounts/blobServices#2021-04-01' = [for i in range(0, length(storageAccounts)): {
name: '${storageAccountResources[i].name}/default'
properties: {
changeFeed: {
enabled: false
}
restorePolicy: {
enabled: false
}
containerDeleteRetentionPolicy: {
enabled: true
days: 7
}
cors: {
corsRules: []
}
deleteRetentionPolicy: {
enabled: true
days: 7
}
isVersioningEnabled: true
}
}]
For complex arrays, you can use this syntax as well:
resource blobServices 'Microsoft.Storage/storageAccounts/blobServices#2021-04-01' = [for (storageAccount, i) in storageAccounts: {
name: '${storageAccountResources[i].name}/default'
properties: {
changeFeed: {
enabled: storageAccount.changeFeed
}
restorePolicy: {
enabled: storageAccount.restorePolicy
}
...
}
}]

Resources