-
Notifications
You must be signed in to change notification settings - Fork 774
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
Deployment should fail for existing
resources that do not exist, even when the reference()
call is not required for transpile
#10097
Comments
I will close it because I found the documentation under "troubleshooting", but good to keep for visibility. |
@mtessier84 , what documentation did you find ? Can you post the link? I also need to fail the deployment if the resource doesn't exist, but didn't find how yet. |
Sorry I was not clear. I could not find any documentation that says that the intended behavior is that it should fail the deployment. The documentation that I found and shared in the original post is under "Troubleshooting". I dont have a solution for this. I could be reported as a feature request instead of a bug |
I think the deployment will fail when at least when that resource is referenced somewhere (beyond the initial declaration). Otherwise, maybe we do not make the underlying reference() call? |
The following code does not fail if the storage account does not exist.
There are cases when I wish the deployment would fail in such scenarios. |
I see now -- thank you for sharing this example. This is in fact a case where we won't even attempt to reference the storage account because the storage account name can be calculated without it. Here is what the compiled Template looks like for that sample: {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.15.164.21910",
"templateHash": "8213433503989717287"
}
},
"parameters": {
"Location": {
"type": "string"
},
"StorageAccountName": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"apiVersion": "2023-01-31",
"name": "[format('MID{0}', parameters('StorageAccountName'))]",
"location": "[parameters('Location')]"
}
]
} I will re-open the issue. |
existing
resources that do not exist, even when the reference()
call is not required for transpile
@mtessier84 if you have an param plan string = 'StorageAccounts'
targetScope = 'subscription'
resource PRICING 'Microsoft.Security/pricings@2022-03-01' existing = {
name: plan
}
output storage string = PRICING.id // <-- output referencing existing resource "outputs": {
"storage": {
"type": "string",
"value": "[subscriptionResourceId('Microsoft.Security/pricings', parameters('plan'))]"
}
} There is a current linter rule, that should pickup unused resources (when you don't reference it). "no-unused-existing-resources": {
"level": "warning"
} |
Thank you Ben, I think that would be a good workaround for my case! |
Thank you @mtessier84 Given we have the linter rule (to catch this) and an appropriate way to handle the requirement I will "close as - by design". |
I'm not sure I follow the resolution. My understanding there's a desire to fail the deployment if the If so, then a workaround could be to reference a non-compile-time property like so: targetScope = 'subscription'
param plan string = 'StorageAccounts'
resource PRICING 'Microsoft.Security/pricings@2022-03-01' existing = {
name: plan
}
output storage object = PRICING.properties // <-- output referencing existing resource If that workaround is good enough, we can keep the issue closed, but I wonder if we should somehow emit a dummy |
@alex-frankel got it yes, without the would still need an explicit reference for this to work in bicep. resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
name: 'doesnotexist'
}
output storage object = reference(storage.id)
<edit, let me test this out some more> |
re-opening, since above does not cover the initial ask. Thanks @alex-frankel |
seems like this maybe related to below, in functionality. |
Looping back on the
resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
name: 'doesnotexist'
}
output storage object = reference(storage.id, storage.apiVersion) correctly fails if resource does not exist
resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
name: 'storageaccountexists'
}
output storage object = reference(storage.id, storage.apiVersion) correctly deploys, if resources exists |
Okay I found the inconsistency on the behavior ... worth adding ... relating to param vNETName string = 'doesnotexist'
resource VNET 'Microsoft.Network/virtualNetworks@2022-09-01' existing = {
name: vNETName
}
output vnetid string = VNET.id {
"experimentalFeaturesEnabled": {
// "extensibility": false
"symbolicNameCodegen": false
} with
|
@jeskew I was meaning to ask if above was expected behavior? |
@brwilkinson The symbolic name template behavior is expected, though I'll have to tag in @anthony-c-martin as to whether this is an intentional behavioral difference between symbolic name and "classic" templates. FWIW, though, that the symbolic name template behavior is I would expect from the Bicep syntax. The "classic" template behavior makes sense, but only if you know how |
Thank you @jeskew I am okay either way, although I will mention 4 things:
|
I think changing this behaviour if we introduce symbolic templates as a "default" can be a big breaking change. sometimes we use existing resources to construct an id (no |
@jeskew you mentioned below, I was wondering that also relates to this or was it a separate issue?
|
@brwilkinson The fix in w16 only addresses what ARM does when there is more than one declared resource targeting the same resource ID but only one is active due to conditions. That manifested as a behavioral difference for templates that used a pattern like the following (which would not cause any issues in a non-symbolic name template): param redeploy bool
resource alreadyThere 'provider/kind@version' existing = if (!redeploy) {
...
}
resource new 'provider/kind@version' = if (redeploy) {
...
} This issue is specifically for unreachable/nonexistent |
The consensus of a team discussion was that there shouldn't be any divergence between the behavior of a symbolic name template and a template not using symbolic name syntax. The ARM runtime should be updated to allow existing resources that don't exist so long as no If we do add a mechanism to make sure an existing resource actually does exist, it should work regardless of whether the template was compiled with symbolic name codegen enabled. |
Bicep version
v0.14.85
Describe the bug
The documentation says:
If you attempt to reference a resource that doesn't exist, you get the NotFound error and your deployment fails. Check the name and scope of the resource you're trying to reference. Link
This is not true. The deployment will not fail if only referring to the name or id of the referenced existing resource. In this case, Bicep does not "resolve" the resource from Azure Resource Manager because Bicep can construct the resource id and get the name from the resource existing block without having to fetch the properties from Azure.
To Reproduce
Steps to reproduce the behavior:
Additional context
The resource existing block should allow enforcing validation or documentation should be updated to explain better the behavior.
The text was updated successfully, but these errors were encountered: