Azure / deployment-stacks

Contains Deployment Stacks CLI scripts and releases
MIT License
87 stars 7 forks source link

Proposal: changes updateBehavior property #59

Closed bmoore-msft closed 1 year ago

bmoore-msft commented 2 years ago

We're looking at making some changes to the updateBehavior property on the stack that will allow for some more flexibility in managing resourceTypes and also attempts to reduce the confusion around when the property value is used by the stack.

With the current schema we have a single string property on the stack:

"updateBehavior": "deleteResources" // or "detachResources"

The property is used during the current PUT on the stack, to determine what happens when a resource is no longer managed by the stack. I.e. the resource was in the template in the previous iteration of the stack and now has been removed from the template. When the template deployment succeeds and resources that were removed from the template are then removed from the stack and either deleted or detached. The property name of updateBehavior has been confusing for some.

The other item we want to address is how to handle removal (specifically deletion) of resource "containers" - resourceGroups and managementGroups. Realizing these containers, even though they are created by the stack may need a different lifecycle than the resources themselves. We're proposing the following changes:

"actionOnUnmanage": { 
  "resources": "delete", 
  "resourceGroups": "delete",
  "managementGroups": "detach" 
},

The property name changes from updateBehavior to actionOnUnmanage - i.e. what happens when the resource is no longer managed by the stack. The type is changed from a string to a dictionary that allows for separating behavior of resource types. This would allow for deleting resources but preserving resourceGroups in case there are other resources that need to be preserved.

The default for all is detach - if a value of delete is submitted, then the stack will issue a DELETE call to the platform and the platform will control what happens from there. So for example, if DELETE is called on a resourceGroup, the platform will proceed to delete the group and all resources in the group.

Let us know if you have any feedback on the proposed approach.

You can vote on other options here: https://forms.office.com/r/8ZLc28z5XW

slavizh commented 2 years ago

Assuming that resources applies to all resources no matter if they are in the scope of resource group, management group or subscription? In that case should we have separate option for resources on each level? I currently cannot figure out such scenario that requires that but in case someone has may be can jump in.

slavizh commented 2 years ago

actionOnUnmanage for me sounds a little weird but may be that is just me and my sense on how it sounds in English which is not my native language. Also shouldn't be actionsOnUnmanage as there are multiple actions.

On another thought I would guess you will have different options available depending on the scope you do stacks deployment?

bmoore-msft commented 2 years ago

Assuming that resources applies to all resources no matter if they are in the scope of resource group, management group or subscription?

All resources that are managed by the stack - regardless of scope. So theoretically you can do things like

  1. create a resourceGroup
  2. create a bunch of resources that are in a different resourceGroup

Both can be deleted by setting the respective properties. In the case if the RG, the resources in that RG would also be deleted, even if they were not managed by the stack.

In that case should we have separate option for resources on each level? I currently cannot figure out such scenario that requires that but in case someone has may be can jump in.

Not sure I follow on this one - you mean have a setting for the RG and the resource in that RG even if they were not managed by the stack? Though now that I type that, it doesn't really work since if the RG is deleted, the resources have to go.

actionOnUnmanage for me sounds a little weird but may be that is just me and my sense on how it sounds in English which is not my native language. Also shouldn't be actionsOnUnmanage as there are multiple actions.

We struggle with this quite a bit (and English is my native language :) - certainly open to feedback on this maybe we can do a survey...

On another thought I would guess you will have different options available depending on the scope you do stacks deployment?

In theory yes, but I think we'll keep it simple and just ignore them... it also means the user does not have to do the mental exercise of when it's allowed and not.

bmoore-msft commented 2 years ago

added a survey link to the OP above

maikvandergaag commented 2 years ago

I'm unable to open the form. Unauthorized.

bmoore-msft commented 2 years ago

Sorry about that (pesky defaults) - can you try again?

maikvandergaag commented 2 years ago

Thanks it works now!

slavizh commented 2 years ago

For the below I guess the scenario is for example you have:

From your deployment you remove the policy assignments and you remove a resource within the resource group. But when you do deployment via stacks you want the policy assignments to be detached but the resource inside the resource group to be removed. Also could be the vice versa - policy assignments removed but resource within resource group detached. This is made up scenario as I have mentioned from my personal experience I cannot think of such scenario that was applicable for my deployments but not sure if there are others who may have it. Judging that nobody has responded on this I would say that others do not see such scenario as well.

In that case should we have separate option for resources on each level? I currently cannot figure out such scenario that requires that but in case someone has may be can jump in.

Not sure I follow on this one - you mean have a setting for the RG and the resource in that RG even if they were not managed by the stack? Though now that I type that, it doesn't really work since if the RG is deleted, the resources have to go.

henrybeen commented 2 years ago

I understand why three options are introduced, and I see no better alternative.

Unintentinal deletion of resources in a resourceGroup is a real thing. I wouldn't support specifying it per individual resource scope (the two RGs and the MG from @slavizh example) though. It feels like this would be to much of a move away from the declarative model.

As an alternative, have you considered just failing the deployment if any resource that needs to be deleted has child resources that are not marked for deletion in the same operation? To me it /feels/ like something is off anyway when you want to remove a container that (for whatever reason) has someone else their stuff in it. But maybe that is to much of an opinion / not general enough..

loekd commented 2 years ago

Combining a "delete" action on an RG with a "detach" action on its resources sounds like something that should be detected and denied by the platform. This becomes complicated when a stack has multiple.

bmoore-msft commented 2 years ago

Combining a "delete" action on an RG with a "detach" action on its resources sounds like something that should be detected and denied by the platform. This becomes complicated when a stack has multiple.

Hmm... you could have resources that are not in a/the resourceGroup. Perhaps an odd scenario, but certainly possible.

@snarkywolverine @apclouds - should we think about blocking such a request? (or ignoring the delete on the scope?)

J0F3 commented 2 years ago

@slavizh @bmoore-msft Not sure if I followed on this only correctly but the following is a scenario which I can imagine to be happen:

Also could be the vice versa - policy assignments removed but resource within resource group detached.

I think of a scenario of which you have, for example, applied some sort of "template" through a deployment stack to the subscription. Now, after a while the initial "template" does not longer apply or has changed (maybe the governance requirement has changed or the workload has developed in a different direction...) and thus you want to remove the policy assignments but the created resources in the resource group should keep exist further. So policy assignments on subscription level should be deleted but resource groups and the resources in it should be get detached.

Not sure if it makes completely sense 🤔 and if such scenario may be already possible with the proposed by setting: "resources": "delete", "resourceGroups": "detach". In overall I am thinking here more of an Azure Blueprints scenario because as far as I understood it is the long term idea that Blueprints will be replaced by Deployment Stack. But please correct me if I am wrong.

So in general I thin the proposed makes really sense. An I have voted for "cleanupMode" in the Survey as I think it describe it best what it does.

slavizh commented 2 years ago

With the proposed setting such scenario is not possible. With the above you will need to detach all resources and delete the policy manually. I have put the scenario just for the discussion part as if you do not discuss all the ideas no matter how weird or not so real world they are you could miss something important. Yes, deployment stacks will be replacement of Blueprints but also will be something more. Blueprints was very limited and let's say it was not completely aligned to ARM. Thus do not think about deployment stacks as a replacement for Blueprints only.

bmoore-msft commented 2 years ago

I think of a scenario of which you have, for example, applied some sort of "template" through a deployment stack to the subscription. Now, after a while the initial "template" does not longer apply or has changed (maybe the governance requirement has changed or the workload has developed in a different direction...) and thus you want to remove the policy assignments but the created resources in the resource group should keep exist further. So policy assignments on subscription level should be deleted but resource groups and the resources in it should be get detached.

Not sure if it makes completely sense 🤔 and if such scenario may be already possible with the proposed by setting: "resources": "delete", "resourceGroups": "detach". In overall I am thinking here more of an Azure Blueprints scenario because as far as I understood it is the long term idea that Blueprints will be replaced by Deployment Stack. But please correct me if I am wrong.

If you had a scenario where the stack contained policies and then resources in resourceGroups I would think of a few things... in addition to what @slavizh mentioned in that "you can't do that".

If there is a lifecycle you see where you'd want to delete the policies at one scope and then preserve resources at another, then the stack is scoped incorrectly. A stack should contain resources that share the same lifecycle and by implication that's not this scenario. Granted - stuff happens, but that helped remind me that we need to really clarify that point as folks adopt stacks.

Second would be that you can "technically" do what you want by:

So if you found yourself in a hard spot because you didn't realize when the stack was created that this may be needed - you could still land there without too much trouble.


Aside we're going to talk through blocking the scenario where you resources: detach and resourceGroups: delete. While I can see a valid scenario for it, seems like it would create more problems if we allow it.

J0F3 commented 2 years ago

A stack should contain resources that share the same lifecycle

Ah yes, that makes sense. I was maybe also a bit a constructed example. Ans yes with the steps you outline above it can be "resolved". But I agree with you that such a stack should probably not be done at all in the first place.

blocking the scenario where you resources: detach and resourceGroups: delete.

That sounds also very logic to me. When you want to delete resource groups you would normally also delete the resources. Otherwise it would be probably again more a case of an incorrectly scoped deployment/stack. And blocking this can save one also from stupid mistakes were then more get deleted than initially thought.

bmoore-msft commented 2 years ago

A stack should contain resources that share the same lifecycle

Ah yes, that makes sense. I was maybe also a bit a constructed example. Ans yes with the steps you outline above it can be "resolved". But I agree with you that such a stack should probably not be done at all in the first place.

I think it's a valid example for a scenario where I have some policies that enable log analytics... you want to "decommission" the policies but keep the data in LA... networking may have similar scenarios. Now why do you want to decomm the policies? ok maybe I'm stretching there...

In any case the exercise made clear to me that we really do need to emphasize life cycle when building these things.

bmoore-msft commented 1 year ago

This is where we landed for the new apiVersion:

"actionOnUnmanage": { 
  "resources": "delete", 
  "resourceGroups": "delete",
  "managementGroups": "detach" 
},

PowerShell/CLI will use switches, e.g.

Remove-AzSubscriptionDeploymentStack -Name myStack -DeleteAll # sets all 3 properties to delete
az stack sub delete -n myStack --delete-all

Thanks to all those who chimed in and filled out the survey...