Azure / bicep

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

Ability to pass raw function/expression to dependsOn? #9392

Closed AtOMiCNebula closed 1 year ago

AtOMiCNebula commented 1 year ago

Is your feature request related to a problem? Please describe. I have an ARM template with (among other things) some complex-ish expressions in its dependsOn array that I cannot figure out how to replicate in Bicep. The decompiler seems to half-heartedly process these by generating the expressions into a bicep dependsOn list as expected, but the resulting template has BCP034 compile errors (The enclosing array expected an item of type "module[] | (resource | module) | resource[]", but the provided item was of type "string").

I cannot post the exact template here, but I am a Microsoft employee and can share it internally; happy to share that link over Teams. For now, here's a heavily abbreviated idea of what I'm doing:

{
  "variables": {
    "managedImages": [
      {
        "name": "L1Image",
        "baseImage": "...",
        "baseImageIsManagedImage": false
      },
      {
        "name": "L2Image",
        "baseImage": "L1Image",
        "baseImageIsManagedImage": true
      }
    ]
  },
  "resources": [
    {
      "copy": {
        "name": "managedImages_copy",
        "count": "[length(variables('managedImages'))]"
      },
      "type": "Microsoft.InternalType/thatIsntPubliclyInteresting",
      "apiVersion": "2020-01-01",
      "name": "[variables('managedImages')[copyIndex()].name]",
      // ...
      "dependsOn": [
        "[if(variables('managedImages')[copyIndex()].baseImageIsManagedImage, resourceId('Microsoft.InternalType/thatIsntPubliclyInteresting', variables('managedImages')[copyIndex()].name), resourceId('Microsoft.Storage/storageAccounts', 'someDummyResource'))]"
      ]
    }
  ]
}

Basically, the copy-expansion of L1Image will depend on some dummy resource I don't care about (because ARM won't let me pass an empty string), and L2Image will depend on L1Image. In my real template, I have more entries than this, but this demonstrates roughly what we're going for.

Describe the solution you'd like I'd like a way to pass my own string expression to resource, or something of the sort. Failing that, I'd like the decompiler to actually fail the operation instead of generating incorrect code and not send me down a rathole thinking that was a valid direction (which after a number of hours, appears to not be the case).

stephaniezyen commented 1 year ago

I'll reach out to you over teams for a repro! The Bicep decompiler is a best-effort process, so decompiling ARM Templates dependencies will not always work well turning into Bicep resource dependencies. The best way to turn this resource declaration loop into Bicep code is to run the loop in series, so there wouldn't be a need to assign a dependency of the second Image on the first.

Thanks for sharing this issue though, we can think about a way to fail the operation or have an error message designed for this situation.

stephaniezyen commented 1 year ago

Reached out last week and talked through the issue here. A simple workaround is to deploy the resources in series to create an implicit dependency without having to specify a dependency in the code. However, looks like the ARM Template file was more complicated than can easily be worked with, so user decided to wait until decompile is stronger before moving ARM Templates to Bicep.