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

Check if resource exists #4023

Open
lordlinus opened this issue Aug 13, 2021 · 94 comments
Open

Check if resource exists #4023

lordlinus opened this issue Aug 13, 2021 · 94 comments
Assignees
Milestone

Comments

@lordlinus
Copy link

feature request
currently creating AKS cluster using Microsoft.MachineLearningServices/workspaces/computes is not idempotent and will error if the link already exists. Currently there is no convenient way to check if the resource already exists and would like to understand the best way to handle this scenario in Bicep

Docs Link: https://docs.microsoft.com/en-us/azure/machine-learning/how-to-create-attach-kubernetes?tabs=python#limitations

Describe the solution you'd like
Convenient way to check if the resource exists and skip certain action ( in this case dont try to establish link) . This could be achieved using a deployment script az cli to see if the resource exists, but looks heavy for a simple check

@lordlinus lordlinus added the enhancement New feature or request label Aug 13, 2021
@ghost ghost added the Needs: Triage 🔍 label Aug 13, 2021
@lordlinus lordlinus changed the title Check if resource exists for non Check if resource exists Aug 13, 2021
@bengavin
Copy link

This would be a great feature, certain things (like KeyVault secrets) end up getting constantly overwritten with a 'new' value when things like an externally managed secret value are involved. I'd like to be able to create the secret if it's not there, and otherwise just leave it as-is. The 'existing' function doesn't seem to help here, as it just bombs out if you try to use it in this way, stating that the resource doesn't exist.

@alex-frankel
Copy link
Collaborator

In theory, due to the idempotent nature of ARM Template/Bicep deployments, you shouldn't need to know if it is new or existing. The AKS issue is definitely a service-side bug. I will send this to them.

@bengavin -- this should be true for the keyvault secret as well. As long as the secret value is the same, the update would be a NoOp. What issue is the update causing?

@bengavin
Copy link

@alex-frankel My specific issue is that I need to know the secret exists, I don't want to actually control the value of the secret in the bicep template. I've worked around this by just passing in the list of existing secrets into the template and conditioning the creation on the input parameter vs. the resource itself.

For background, these secrets are for things that likely need rotation by operations staff and they are referenced by web apps, function apps, etc. The goal of the template is to get the secrets setup, with 'tbd' values and linked with the appropriate resources to avoid typos and such. The operations folks can go in and supply the appropriate secret values into KeyVault and have them picked up automatically by the applications. Then, when code changes occur, those secret values are NOT overwritten with 'tbd' values again, since my desired state represents 'exists' vs. 'has this value'.

In my case, introducing another level of indirection by having the secrets looked up during deployment of the template (via KeyVault reference parameter) adds another 'step' into the rotation of secret values that feels unnecessary. I don't want my operations folks to need to update a 'deployment' key vault and then trigger a re-deployment to get the new secret value pushed into the application level key vault.

That said, if this is the wrong approach, I'd be happy to hear that and understand why :)

@miqm
Copy link
Collaborator

miqm commented Sep 6, 2021

+1 on this. I'd also like to have a function on ARM/bicep to check if particular resourceId exists.

My use case is that I'd like to create a blue-green deployment of container instance and manipulate private DNS entry to switch to opposite configuration after the deployment. the DNS entry would also indicate which one is currently in use. However, on first deployment, I need to do a fallback (DNS entry will not exist). I could do this with tags, but DNS would be more accurate.

@alex-frankel alex-frankel added Needs: Triage 🔍 discussion This is a discussion issue and not a change proposal. and removed awaiting response labels Sep 9, 2021
@pabelanger
Copy link

Just hitting this now, with key vaults. I think I'm going to test running a pre-run deployment script and probe the keyvault API to see if a vault is in soft delete state or not. If so, then bump the name from kv-test-001 to kv-test-002.

@minhdn90
Copy link

+1. We need this too. Deploying Synapse workspace with encryption requires knowing if one already exists to control Key Vault access policy

@jakelevinez
Copy link

Would love this - our use case is deploying a VM and putting the admin password into a keyvault - if the VM already exists we don't want to overwrite the value in the vault as it isn't actually applied to the VM.

@WhitWaldo
Copy link

WhitWaldo commented Oct 19, 2021

In theory, due to the idempotent nature of ARM Template/Bicep deployments, you shouldn't need to know if it is new or existing. The AKS issue is definitely a service-side bug. I will send this to them.

@bengavin -- this should be true for the keyvault secret as well. As long as the secret value is the same, the update would be a NoOp. What issue is the update causing?

If one attempts to recreate a role assignment with the same properties, it yields an error "Tenant ID, application ID, principal ID, and scope are not allowed to be updated. (Code:RoleAssignmentUpdateNotPermitted)." Given they use an idempotent GUID based on these unchanged values, it would be ideal to have some mechanism by which to check whether the role assignment already exists before attempting to set it again, knowing that attempting to set an existing such role will fail the deployment.

@jakelevinez
Copy link

@WhitWaldo I have an open ticket with MS about that particular case with roleassignments - even with the same GUID the deployment will fail if you don't wait long enough between deplyments (on the order of days). If you wait a few days between deployments, it does work.

@alex-frankel I can speak to the secret issue - you can't have it deploy the same secret value, because if you can generate that value again, you've in some way hardcoded your value into your template. Proper secret generation would use something like the newGuid() function which won't allow you to create the same secret value, for obvious security reasons.

@brwilkinson
Copy link
Collaborator

@jakelevinez

I just noticed your comment, you can likely avoid the error by adding the property 'principalType'

It is documented here:
https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-template#new-service-principal

image

@jlevine-aba
Copy link

@brwilkinson Unfortunately it looks like in my case we are already doing ServicePrincipal and on a relatively recent preview API version, must be something different affecting us.

@brwilkinson
Copy link
Collaborator

@jlevine-aba okay, well worth a try, hopefully support can sort you out then.

only other tip to slow deployments down to buy you some time is to put batchsize(1) on your module loops. That may give the assignments enough time to replicate since they go in series... hard to say without all of the details, however support should be able to provide guidance.

@mdarefull
Copy link

Joining this thread this time also because of KeyVault. My issue is that the KeyVault resource requires the access policies array to be provided, which means that if I deploy the resource, all my access policies are overridden. Only deploying KeyVault if it doesn't exist feels like the lesser evil although far from ideal.

I understand that in theory, ARMs should be idempotent, but in practice, many resources are not. I think this team should be pragmatic and add support to this feature to make adoption easier. I'm confident we'll see fewer and fewer issues in the future as the industry matures more, but we are quite not there yet.

@miqm
Copy link
Collaborator

miqm commented Nov 9, 2021

@alex-frankel just another case that we NEED to check if a resource exists. For using aks and application gateway ingress controller.
The thing is that if we do first time deployment we might need to put some default routes at the beginning. Then, when we deploy pods to AKS and AGIC is enabled, it will override AGW configuration to whatever is set in pods. Since AGW routes, listeners, etc are not resources but properties, next deployment of our template will clear the configuration made by AGIC making our services in AKS loose it’s ingress connectivity. So we need to either deploy AGW manually and keep it outside ARM or have a condition to check if we have the AGW already created.
Also, if we can determine that resource exists, we can call a module on that condition to get the current configuration and do a merge with some additional routes we want to add to not disturb things added by AGIC.

@brwilkinson
Copy link
Collaborator

@miqm I think this one would be better if the backend Rules were actually a standalone property that would allow you to not overwrite these settings, which would be similar to the NATRules on a Load balancer or the App Configuration settings on a Web Site. linking to the open issue on this as well #2316

@olafloogman
Copy link

There's a way to accomplish this by using deployment scripts. I've created a Bicep module to check whether a resource exists, which can be found here: https://github.com/olafloogman/BicepModules/blob/main/resource-exists.bicep

There's the additional overhead of needing to run the script in a container instance, but according to MS docs:
Deployment script execution is an idempotent operation. If none of the deploymentScripts resource properties (including the inline script) are changed, the script doesn't execute when you redeploy the template.

@miqm
Copy link
Collaborator

miqm commented May 11, 2023

Yet another example of bad API / necessity for resourceExists - API-Management custom domain certificates: They are configurable on both properties of API-M cluster and on child resources where child resources have more options.

@miqm
Copy link
Collaborator

miqm commented Jul 10, 2023

Adding new example of why we need this function: RedisCache AAD authorization cannot be set during initial deployment:

{
"code":"BadRequest",
"message":"Cannot enable AAD with cache creation flow.
 RequestID=41b07270-aa64-4390-8d1a-c8f3e3112de1"
}

🤷🏻
here's bicep template example that fails:

resource redisCache 'Microsoft.Cache/redis@2023-05-01-preview' = {
  name: redisName
  location: location
  properties: {
    sku: {
        name: 'Basic'
        family: 'C'
        capacity: 0
    }
    minimumTlsVersion: '1.2'
    enableNonSslPort: false
    publicNetworkAccess: 'Disabled'
    redisVersion: '6.0'
    redisConfiguration: {
      maxclients: '256'
      'maxmemory-reserved': '30'
      'maxfragmentationmemory-reserved': '30'
      'maxmemory-policy': 'volatile-lru'
      'maxmemory-delta': '30'
      'aad-enabled': 'true'
    }
  }
}

Although this is a preview API I doubt it'll change before GA or anytime later.

@Kaloszer
Copy link

Kaloszer commented Aug 9, 2023

+1, just hit the VNET case

@sureshchhatwani12
Copy link

sureshchhatwani12 commented Sep 5, 2023

I also use case in which we would like to deploy certain parts of infrastructure or all. In case of all it would mean that we would need to create resource group if not exists else should skip the step for which I think we should get functions to check whether the resource exists based on tag or something. I did some workaround and have used deployment script and tag such isResourceExistsOrNot to boolean.

Reference: https://ochzhen.com/blog/check-if-resource-exists-azure-bicep

But we would really like an ideal solution from the bicep team as ARM maintain infra state itself not like terraform where we are required to configure a backend to store the infra state.

@DanStor
Copy link

DanStor commented Sep 11, 2023

Another +1 for the VNET case, which we have also just hit

@miqm
Copy link
Collaborator

miqm commented Oct 3, 2023

Another case - Kubernetes agent pools - when you create a new agent pool you need to provide count property, even if agent pool has autoscaling enabled. Later, if you deploy same code and in the meantime autoscaler scaled up - setting lower count (i.e. you had count set to minCount) will deallocate machines making interruptions in your workload.

@romanrabodzei
Copy link

+1 case. I have 2 applications and have a solution that has a connector for these 2 apps. but I'd like to deploy the connector if only one of the apps was deployed. More details left here #12262

@jbtcode
Copy link

jbtcode commented Oct 26, 2023

Another case in SQL Server resource update failed with error code AadOnlyAuthenticationIsEnabled #1436. When creating a sqlserver resource, the administratorPassword is mandatory, but if the azureADOnlyAuthentication is set, any subsequent deployment will fail if the password parameter is set. So need to find out if this is a "new" or "update" deployment.

The idea of the deployments being idempotent is great, but there seem to be plenty of examples where the underlying APIs do not respect that.

Having to run a script before the deployment, or using a deploymentScript are just workarounds, implementing a way to check for existence of a resource (or be able to "catch" the error from the existing keyword) would help us create the idempotent Bicep scripts.

@abatishchev
Copy link

+1, here's my scenario:

I want to use reference() on VMSS auto-scale settings and adjust the VMSS template accordingly if the auto-scale settings resource already exists, and create it with default value if it does not yet (a region buildout scenario)

@WithHolm
Copy link

My suggestion on the issue that was closed is a simple "exists?". This way you either get the existing resource or a null, like parameters are already handled.

@zebslc
Copy link

zebslc commented Mar 1, 2024

Another use case is B2C. Once I have set up a b2c environment, I can't create another (which is correct). Unfortunately bicep doesn't work that out automatically so I have to hack it with the powershell scripts to work out whether it does. This basic exists requirement has been around now for a couple of years. Is it even on the roadmap yet?

I would also love bicep to automatically revive a soft deleted key-vault rather than erroring that it can't create a new one.

If I have an environment that I tear down when it's no longer needed and then recreate and keyvault was in the original setup, it fails because I have to hard delete or restore it manually

@alex-frankel
Copy link
Collaborator

We are considering building support for this as part of the next semester of work. Will know more by the end of March.

@zebslc
Copy link

zebslc commented Mar 6, 2024

Surely you must already have this internally to be able to work out whether to replace or create a new item so it should just be a case of surfacing that...

@alex-frankel
Copy link
Collaborator

@zebslc - we do not actually. Bicep/Template Deployments naively redeploy all resources in the template (by design) and we rely on the Resource Providers to handle the PUT call as gracefully as possible.

@WithHolm
Copy link

@alex-frankel bicep might not have this, but checking resource existance is a possible management operation https://learn.microsoft.com/en-us/rest/api/resources/resources/check-existence?view=rest-resources-2021-04-01

@jikuja
Copy link

jikuja commented Mar 14, 2024

Other view for that API endpoint: https://learn.microsoft.com/en-us/rest/api/resources/resources/check-existence-by-id?view=rest-resources-2021-04-01

Checks by ID whether a resource exists. This API currently works only for a limited set of Resource providers. In the event that a Resource provider does not implement this API, ARM will respond with a 405. The alternative then is to use the GET API to check for the existence of the resource.

@alex-frankel
Copy link
Collaborator

Right, we don't lack the ARM APIs to add this functionality. I was just pointing out that it's not as if we are already doing this today and choosing not to expose it to bicep devs.

@WithHolm
Copy link

@alex-frankel

We are considering building support for this as part of the next semester of work. Will know more by the end of March.

we are past the end of march. you have any updates for us?

@alex-frankel
Copy link
Collaborator

This is currently planned to be implemented in the current semester (4/1 - 9/30). However, the design of this is not complete. Once we have closed on design, we can provide a more precise and accurate ETA.

@lhardy-scs
Copy link

Great to see this functionality is being added. I believe I'm hitting a similar issue with the SQLVirtualMachine extension on redeployment as I'm getting the error 'Volume with drive letter F already exists' as it appears to be trying to initialise a disk as F whereas that was already done in the initial deployment. I'll be raising a ticket for this as I would like to be able to redeploy the extension without issue, however the ability to just skip that extension for now without having to use a bool (I do that for key vault keys at the moment) would be much appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests