-
Notifications
You must be signed in to change notification settings - Fork 40
Open
Labels
Description
Describe the bug
I have a number of templates which load configuration from a json file.
Template Analyzer produces this error for templates which use this pattern
(However, given the ambiguity of the exception, it's hard to tell if the issue is the usage of json content or not)
Exception details:
Microsoft.Azure.Templates.Analyzer.Core.TemplateAnalyzerException: Error compiling Bicep template
---> System.Exception: Bicep issues found:
Expected the "]" character at this location.
This declaration type is not recognized. Specify a metadata, parameter, variable, resource, or output declaration.
at Microsoft.Azure.Templates.Analyzer.BicepProcessor.BicepTemplateProcessor.ConvertBicepToJson(String bicepPath)
at Microsoft.Azure.Templates.Analyzer.Core.TemplateAnalyzer.AnalyzeTemplate(String template, String templateFilePath, String parameters)
--- End of inner exception stack trace ---
at Microsoft.Azure.Templates.Analyzer.Core.TemplateAnalyzer.AnalyzeTemplate(String template, String templateFilePath, String parameters)
at Microsoft.Azure.Templates.Analyzer.Cli.CommandLineParser.AnalyzeTemplate(TemplateAndParams templateAndParameters)
Expected behavior
No error; template is analyzed
Reproduction Steps
config.json (referenced from cosmos.bicep - check relative path)
{
// Defines the environment-independent settings for each service.
// ... truncated ...
"environments": {
"development": {
// container properties:
// {
// "name":"cosmos container name", (REQUIRED)
// "partitionKey":"/partitionKeyPath", (REQUIRED)
// "ttl": 100, // default: -1 (none)
// "indexing": "lazy", // consistent, lazy or none (default: consistent)
// "uniqueKeys": [] // default: none
// "permissions": [] // default: none
// }
"cosmos": {
"enabled": true,
"RUs": 1000, // minimum: 1000 (shared by all containers)
"containers": [ // max: 25 containers
{
"name": "items", // stored procedure(s) added in infra/environment/cosmos-container.bicep
"partitionKey": "/p",
"indexing": "consistent",
"uniqueKeys": [ "/vg", "/v", "/t", "/tv" ],
"permissions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeStoredProcedure", // writes are via stored procedure
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery", // query only (no direct item access)
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/replace"
]
},
{
"name": "changefeed",
"partitionKey": "/id",
"indexing": "consistent",
"permissions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*", // item writes/deletes allowed
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery"
]
},
{
"name": "orleans",
"partitionKey": "/ClusterId",
"indexing": "consistent",
"indexIncludes": [ "/*" ],
"indexExcludes": [ "/Address/*", "/Port/*", "/Generation/*", "/Hostname/*", "/SiloName/*", "/\"SuspectingSilos\"/*", "/\"SuspectingTimes\"/*", "/StartTime/*", "/IAmAliveTime/*" ],
"permissions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*", // item writes/deletes allowed
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery"
]
},
{
"name": "grains",
"partitionKey": "/PartitionKey",
"indexing": "consistent",
"indexIncludes": [ "/*" ],
"indexExcludes": [ "/\"State\"/*", "/\"_etag\"/?", "/StartAt/*", "/Period/*" ],
"permissions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*", // item writes/deletes allowed
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery"
]
}
]
}
}
}
}
cosmos.bicep:
param now string = utcNow()
param location string
param sublocations array
param databaseName string
param tags object
// Resource names
@maxLength(44)
param cosmosName string
@description('The default consistency level of the Cosmos DB account.')
@allowed([
'Eventual'
'ConsistentPrefix'
'Session'
'BoundedStaleness'
'Strong'
])
param defaultConsistencyLevel string = 'Session'
@description('Max stale requests. Required for BoundedStaleness. Valid ranges, Single Region: 10 to 2147483647. Multi Region: 100000 to 2147483647.')
@minValue(10)
@maxValue(2147483647)
param maxStalenessPrefix int = 100000
@description('Max lag time (minutes). Required for BoundedStaleness. Valid ranges, Single Region: 5 to 84600. Multi Region: 300 to 86400.')
@minValue(5)
@maxValue(86400)
param maxIntervalInSeconds int = 300
@description('Enable system managed failover for regions')
param systemManagedFailover bool = true
param environment string
// Configuration
var config = loadJsonContent('./../config.json')
var envConfig = config.environments[environment]
var cosmosConfig = envConfig.cosmos
var RUs = contains(cosmosConfig, 'RUs') ? cosmosConfig.RUs : 1000
var containers = contains(cosmosConfig, 'containers') ? cosmosConfig.containers : []
// New resources
var consistencyPolicy = {
Eventual: {
defaultConsistencyLevel: 'Eventual'
}
ConsistentPrefix: {
defaultConsistencyLevel: 'ConsistentPrefix'
}
Session: {
defaultConsistencyLevel: 'Session'
}
BoundedStaleness: {
defaultConsistencyLevel: 'BoundedStaleness'
maxStalenessPrefix: maxStalenessPrefix
maxIntervalInSeconds: maxIntervalInSeconds
}
Strong: {
defaultConsistencyLevel: 'Strong'
}
}
var locations = [
{
locationName: location
failoverPriority: 0
isZoneRedundant: false
}
]
var sublocationsList = [for sublocation in sublocations: {
locationName: sublocation
failoverPriority: 1
isZoneRedundant: false
}
]
var allLocations = union(locations, sublocationsList)
resource account 'Microsoft.DocumentDB/databaseAccounts@2022-11-15-preview' = { // old version to avail of burst feature - went to GA May 2023: TODO: update version when added to a non-preview version
name: toLower(cosmosName)
kind: 'GlobalDocumentDB'
location: location
properties: {
consistencyPolicy: consistencyPolicy[defaultConsistencyLevel]
locations: allLocations
databaseAccountOfferType: 'Standard'
enableAutomaticFailover: systemManagedFailover
enableMultipleWriteLocations: true
disableKeyBasedMetadataWriteAccess: true // only data readon/write operations are allowed when connected using an account key
publicNetworkAccess: 'Disabled'
minimalTlsVersion: 'Tls12'
disableLocalAuth: true
enableBurstCapacity: true
backupPolicy: {
type:'Periodic'
periodicModeProperties: {
backupRetentionIntervalInHours: 168 // 1 week retention
backupIntervalInMinutes: 60 // hourly backup
backupStorageRedundancy: 'Zone'
}
}
}
tags: tags
}
resource database 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2022-05-15' = {
parent: account
name: databaseName
properties: {
resource: {
id: databaseName
}
options: {
throughput: RUs // database-shared throughput
}
}
}
@batchSize(1)
module containersModule 'cosmos-container.bicep' = [for container in containers: {
name: 'env-mod-cosmos-container-${container.name}-${now}'
params: {
accountName: account.name
containerName: container.name
databaseName: database.name // creates an implicit dependency on the database
partitionKeys: [container.partitionKey]
defaultTtl: contains(container, 'ttl') ? container.ttl : -1
indexingMode: contains(container, 'indexing') ? container.indexing : 'consistent'
uniqueKeys: contains(container, 'uniqueKeys') ? container.uniqueKeys : []
indexExcludes: contains(container, 'indexExcludes') ? container.indexExcludes : []
indexIncludes: contains(container, 'indexIncludes') ? container.indexIncludes : []
}
}]
output accountName string = account.name
output accountId string = account.id
cosmos-container.bicep (referenced from cosmos.bicep)
param accountName string
param databaseName string
param containerName string
@allowed(['consistent', 'lazy', 'none'])
param indexingMode string = 'consistent'
param indexIncludes array = ['/*']
param indexExcludes array = ['/_etag/?']
@description('string array of paths which (combined) form a unique key')
param uniqueKeys array = []
param defaultTtl int = -1
param partitionKeys array
resource account 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = {
name: accountName
}
resource database 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases@2023-04-15' existing = {
parent: account
name: databaseName
}
resource container 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2022-05-15' = {
parent: database
name: containerName
properties: {
resource: {
conflictResolutionPolicy: {
mode: 'LastWriterWins'
}
id: containerName
partitionKey: {
paths: partitionKeys
kind: 'Hash'
}
indexingPolicy: {
indexingMode: indexingMode
includedPaths: [for path in indexIncludes: { path: path}]
excludedPaths: [for path in indexExcludes: { path: path}]
}
defaultTtl: defaultTtl
uniqueKeyPolicy: {
uniqueKeys: length(uniqueKeys) > 0 ? [
{
paths: uniqueKeys
}
] : []
}
}
}
}
Environment
No response
