Azure / bicep

Bicep is a declarative language for describing and deploying Azure resources
MIT License
3.22k stars 746 forks source link

Stringifying an array of objects results in an error when its value is passed to another module #6167

Open maartenkools opened 2 years ago

maartenkools commented 2 years ago

Bicep version 0.4.1272

Describe the bug Stringifying a locally defined array of objects results in an error about '{' being unexpected. Providing the array through a module does work.

To Reproduce Steps to reproduce the behavior:

var myArray = [
  {
    id: '117'
    name: 'John'
  }
]

// The module takes a string parameter called 'value'
module tst 'modules/sample-module.bicep' = {
  name: 'tst'
  params: {
    value: string(myArray)
  }
}

Error is:

{'code': 'InvalidTemplate', 'message': 'Deployment template language expression evaluation failed: \'The language expression \'{"id":"117","name":"John"}\' is not valid: the string character \'{\' at position \'0\' is not expected.\'. Please see https://aka.ms/arm-template-expressions for usage details.', 'additionalInfo': [{'type': 'TemplateViolation', 'info': {'lineNumber': 0, 'linePosition': 0, 'path': ''}}]}

However, if myArray is part of the output from another module, it does work as expected. So as a workaround I have a, pretty much, empty module returning an array of objects.

Additional context I'm trying to store an array of JSON objects in an App Configuration resource with the application/json content-type.

alex-frankel commented 2 years ago

Tested offline and the below code should work as a workaround:

// The module takes a string parameter called 'value'
module tst 'scratch-mod.bicep' = {
  name: 'tst'
  params: {
    value: ' ${string(myArray)}'
  }
}

This is related to service-side expression evaluation bug. When you converted the array into a string, the first and last characters are [ and ], which is considered an ARM Template expression, even though that is not what you are trying to express.

cc @majastrz as FYI

maartenkools commented 2 years ago

Tested offline and the below code should work as a workaround:

// The module takes a string parameter called 'value'
module tst 'scratch-mod.bicep' = {
  name: 'tst'
  params: {
    value: ' ${string(myArray)}'
  }
}

This is related to service-side expression evaluation bug. When you converted the array into a string, the first and last characters are [ and ], which is considered an ARM Template expression, even though that is not what you are trying to express.

cc @majastrz as FYI

That's a better workaround than using a module to provide the array. Important to note that the space in front is important, otherwise it leads to parse errors

Rod-Sychev commented 2 months ago

@alex-frankel Any ETA on the fix? BTW your workaround from the 9-March-2022 does not work when used in the resource:

param secrets array
param tags object
param keyVaultName string

resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
  name: keyVaultName
}

resource kvsecrets 'Microsoft.KeyVault/vaults/secrets@2023-07-01'  = [for secret in secrets: {
  parent: keyVault
  name: secret.name
  tags: tags
  properties: {
    value: ' ${string(secret.value)}'
    attributes: {
      enabled: true
    }
  }
}]