Closed jurjenoskam closed 8 months ago
There are a couple quirks of the ARM platform that you're running in to.
The first is that dependsOn
is more of an ordering directive than it is a precondition: a resource that depends on another will not start deploying until the depended upon resource has successfully finished deploying, but resources can only depend on resources deployed in the same template. Bicep allows you to declare this dependency because some but not all versions of ARM templates allow you to declare existing
resources (on which you can declare a dependency). If Bicep is targeting an earlier version of the ARM template language, then the dependency is dropped.
The second is that existing
resources are only fetched if their properties are accessed. (This is true regardless of the ARM template version targeted.) There is some more discussion/detail on why that is the case in #10097.
This is by design and explained further in the above comment
Bicep version Bicep CLI version 0.24.24 (5646341b0c)
Describe the bug (This is somewhat related to #2716, but is about a different use case and scenario.)
Some, but not all, references to existing resources will work just fine even if the referred-to resource doesn't exist at all:
This template will work for any value of sqlServerName (or more precisely: any value that meets the naming restrictions for SQL Server resources).
This is a problem because I'm trying to do something like this (pseudocode), which silently doesn't work:
My expectation is that
scriptToRunOnSqlServer
does not deploy ifsqlServer
does not exist. In reality the deploymentScript does deploy.Worse, it will also fail an case of an implicit dependency, e.g. when the deployment script resource does not have the explicit
dependsOn
but includessqlServer.name
somewhere in its definition. That will just run the deployment script as if there's a server with that name, even though it doesn't exist at all.Further background Looking at the resulting ARM, it turns out that there are two types of references to existing resources, and they behave differently:
[variables('sqlServerName')]
(in the first example template above). This type of reference will work even when the referred-to resource does not even exist.reference()
function. This type of reference will fail if the referred-to resource does not exist.This difference is completely invisible in the Bicep template (other than that you can only use references of the first type in certain locations, but that's beside the point here) . Only at deployment time the difference has an effect. This is undocumented and unintuitive. Things would be much more consistent if a dependency (either explicit or implicit) on an
existing
resource always results areference()
to the target resource.