Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What-If doesn't show difference whith user-defined data type & optional property #375

Open
TiTi opened this issue Aug 7, 2024 · 1 comment

Comments

@TiTi
Copy link

TiTi commented Aug 7, 2024

dedicated issue because not quite the same as #157

i found another weird case of wrong what-if with user-defined data type & optional property

Caller:

type vmInfosType = {
  name: string
  size: string
  hasSql: bool?
}

@description('Virtual machines to create')
param vmInfos vmInfosType

module vmModule '../azure-virtual-machine/vm.bicep' = {
  name: 'vm1'
  params: {
    location: location
    tags: tags
    name: vmInfos.name
    size: vmInfos.size
    // ...
    hasSql: vmInfos.hasSql
  }
}

Like so, the whatif result is empty!! No changes!

if you then replace the parameter hasSql like so when calling the module:
hasSql: vmInfos.?hasSql

Then the what-if works as expected. 🤯 Crazy!

So make sure to use "?" anywhere you have an optionnal property!!

The difference in the generated arm json:
what-if fails:

          "hasSql": {
            "value": "[variables('vmInfos').hasSql]"
          },

what-if works:

          "hasSql": {
            "value": "[tryGet(variables('vmInfos'), 'hasSql')]"
          },

i tested with current bicep version : Bicep CLI version 0.29.47 (132ade51bc)

Originally posted by @TiTi in #157 (comment)

@jeskew
Copy link
Member

jeskew commented Aug 26, 2024

That is a confusing user experience! This will be addressed by the work we're doing to address #157, though you're right that this isn't quite the same issue.

What's going on behind the scenes is that the mechanism used by What-If to enumerate resources in modules can't easily distinguish between an expression that will fail at runtime vs an expression that will fail until runtime. The latter is what #157 is tracking and covers cases like dereferencing properties of resources created earlier in the deployment.

For the case you describe, the [variables('vmInfos').hasSql] expression is failing because there is no .hasSql property. This will fail when the template is deployed, but what-if isn't sure if the expression failed because it is invalid or because it won't be evaluable until the deployment is under way. As a result, what-if 'short-circuits' the entire module (as described in #157). The [tryGet(variables('vmInfos'), 'hasSql')] expression will evaluate to null rather than raising an error, allowing what-if to proceed evaluating the nested module.

When the work currently under way for #157 is completed, the call to What-If will fail with the same error message that would have caused the deployment to fail later on. Rather than short-circuiting, you would get an accurate assessment that the deployment is not valid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants