azure-powershell
azure-powershell copied to clipboard
`New-AzSubscriptionDeployment` is lacking `Mode` parameter, right?
Description
According to @alex-frankel's answer to my original question, a subscription
Bicep file may load and execute a resouceGroup
Bicep file in order to (re-)create a resource group and all resources contained therein.
While the New-AzResourceGroupDeployment
Cmdlet comes with a Mode
parameter, providing an option to either leave all existing resources (Incremental
) or remove all resources not existing in the ARM template being deployed. (Complete
). the New-AzSubscriptionDeployment
lacks this parameter.
Question
In order to create idempotent Bicep files, I think the Mode
parameter is crucial, even to New-AzSubscriptionDeployment
, as it may execute a resourceGroup
Bicep module.
You think so, too? Then I'd create a Feature Request issue.
Thank you for your feedback. This has been routed to the support team for assistance.
Only Resource Group scoped deployments support Mode
, so the issue is not that the command is missing a parameter set, but that the functionality at those deployments scopes does not exist. We are in a private preview of a new way of deploying bicep/template code which is called Deployment Stacks that among other things is kind of like complete mode v2 and will support all deployment scopes.
Interesting video (though I'm not sure how CRUD operations on stacks are going behave if the same resource will be assigned to two different stacks at the same time).
Yet, I'm referring to the following comment you made in #7819:
Typically, you will start the deployment at subscription scope, create the RG, then use that RG as the scope for a module deployment to that RG.
So, when I launch a deployment, I will start-off with a Subscription scope Bicep file which then in turn runs a ResourceGroup scoped Bicep file/module, like this:
So, AFAIK, I should be able to provide a --Mode
to the New-AzSubscriptionDeployment
Cmdlet. Then when I re-deploy resources, redundant resources in the target resource group should either be pruned or left as-is.
You cannot mix and match deployment modes in the way you describe. Because the subscription must be deployed with incremental
mode, so do all the other linked/nested deployments.
Hmm, that doesn't sound good to me.
If a project manager requests to establish, for example, a new stage
environment, some member of the Environment Administrators staff, who is not acquainted with the project, should be able to do that from a single, atomic, ACID Bicep operation.
And if the same project manager requested to amend that same environment, another member of the Environment Administrators staff should be able to run the same Bicep file again and have obsolete resources be removed without further manual intervention.
Azure/Bicep/788 seems critical and crucial to me. It should be the barrier from keeping Bicep version 0.8
to move on to 0.9
.
We recognize it is not the ideal situation, which is why we are focused on getting Deployment Stacks out. That will effectively support Complete Mode at all scopes. @settrend -- have you spent much time with complete mode? Besides only working at RG scope, it has many other limitations, which is also why we are focused on obsoleting it with deployment stacks.
FWIW, https://github.com/Azure/bicep/issues/788 does not seem related to the original ask in this thread. Can you help clarify?
Thank you for keeping engaged with my concerns @alex-frankel!
You are right. It took a steep learning curve for me to get all pieces in place, but now, after reading all the valuable answers from you and the other contributors, it all (Mode
switch etc.) seems to boil down to a single observation:
The concept of scopes per Bicep file seems an unnecessary limitation to the Bicep language.
Azure/bicep#788 basically deals with that design flaw.
I believe it's important in enterprise environments to be able to create any kind of service, regardless of scope, from a single Bicep file. – It's nice to be able to modularize things, but administrative constraints might demand to use a single file to run.
That said, a Bicep deployment run, moreover, should be able to remove redundant resources. So, if a previous version of the Bicep file contained 5 VMs (resource vm = [for i in range(0, 5): { ... }]
) and a new version of the same Bicep file only required 2 VMs ((resource vm = [for i in range(0, 2): { ... }]
)), then, when being deployed, the three now redundant VMs should be deleted/removed so they won't cost fees anymore. — A new keyword (e.g. prune
), might be added to the Bicep language to replace the current Mode
CLI parameter, so the Bicep language itself determined whether all resources from resource groups mentioned in the Bicep deployment run will eventually be deleted at the end of the run if not being touched during the Bicep deployment run. Plus, a remove
keyword should be added to resources (e.g. remove resource existing = {}
), so they can be explicitly removed instead of being added. (Perhaps a language update would allow for the existing
keyword to prepend the resource
keyword, resulting in Bicep code like remove existing resource =
or existing resource x =
.)
Finally, a Bicep deployment run should either fully succeed or fully retain the previous state (i.e. it should behave like a database transaction; see ACID), so resources will be in a defined state, no matter of the outcome.
That said, a Bicep deployment run, moreover, should be able to remove redundant resources.
The delete functionality you are describing is exactly how Deployment Stacks is expected to behave. There is no plan to add an explicit remove
keyword, it will always be implicit by comparing the previous bicep code to the current one.
regarding ACID transactions: Unfortunately, ARM is not a transactional system, so there is no way to do ACID transactions and perform a 100% reliable rollback. We'd like to introduce a psuedo-rollback functionality in stacks by allowing you to re-apply the old version on a failure, but to be clear that is more of a roll forward and there is no guarantee that will leave you in exactly the same state as before.
Again, I am still not clear on the relevance of https://github.com/Azure/bicep/issues/788. We would like to implement that, but it does not have a direct effect on any of the above.
There is no plan to add an explicit
remove
keyword, it will always be implicit by comparing the previous bicep code to the current one.
I don't think this will work for subscription/tenant/ManagementGroup resources. Hence, my remove
proposal.
Again, I am still not clear on the relevance of Azure/bicep#788.
I see. Well, to me, all the above considerations boil down to a single improvement request (You are right, this becomes partially off-topic here. This discussion should rather be added to Azure/bicep#788):
If Azure/bicep#788 (or, FWIW, Azure/bicep#7860 that basically describes the same idea) got implemented …
- Target scopes could be intermixed in a single Bicep file.
- All deployment related PowerShell Cmdlets would become obsole, except for a single one that's running the Bicep file, with no bias on scope.
So, given the following pseudo, future Bicep file:
(in this example called Setup.bicep
)
@secure()
@match('^\d{8}-\d{4}-\d{4}-\d{4}-\d{12}$')
@description('GUID of subscription to be touched.')
param subscrGuid string = 'My-Subscription'
@minLength(3)
@maxLength(24)
@description('Name of resource group to be created or updated.')
param rgName string = 'My-Website'
@minLength(3)
@maxLength(24)
@description('Name of resource group with resources to be deleted.')
param oldRgName string = ''
@minLength(3)
@maxLength(24)
@description('Location for Azure resource manager to store resources.')
param loc string = 'germanywestcentral'
@minValue(1)
@maxValue(100)
@description('Number of Key Vault secrets to create.')
param secNum int
// --------------------------------------------
targetScope = subscription(subscrGuid)
// ---- create new resource group if not exists, or reconfigure if existing
resource rg 'Microsoft.Resources/resourceGroups' =
{
name: rgName
location: loc
...
}
// ---- delete existing other resource group if exists, or just skip (with warning) if not existing
if (!empty(oldRgName))
{
remove existing resource 'Microsoft.Resources/resourceGroups' =
{
name: oldRgName
}
}
// --------------------------------------------
targetScope = resourceGroup(rg) prune // the prune keyword will delete all resources from this resource group not touched by this deployment.
// ---- create new key vault if not exists, or reconfigure if existing
resource kv 'Microsoft.KeyVault/vaults' =
{
name: 'PATs'
location: loc
...
// ---- create new secrets in key vault, or reconfigure if existing.
/* >>>> All existing resources (i.e. secrets) beyond the current
range will be deleted due to the `prune` keyword
given above.
*/
resource mySecrets 'secrets' = [for i in range(1, secNum):
{
name: 'PAT${i}'
properties:
{
value: i
attributes:
{
exp: dateTimeToEpoch('2023-01-01')
}
}
}]
}
(Please note the use of the suggested prune
and remove
keywords in the Bicep example above.)
… such future Bicep file could simply be run by a non-biased PowerShell Cmdlet (or Bicep CLI call):
$parameters = @{
subscrGuid = '1234568-1234-1234-1234-123456789012';
rgName = 'My-New-Website'
oldRgName = 'My-Ole-Website'
loc = 'centralus'
secNum = 5
}
New-AzDeployment -TemplateFile '.\Setup.bicep' -TemplateParametersObject $parameters
# now, let's reduce the number of Secret resources
# in the "My-New-Website" Resource Group to two items ...
$parameters.secNum = 2
New-AzDeployment -TemplateFile '.\Setup.bicep' -TemplateParametersObject $parameters
The delete functionality you are describing is exactly how Deployment Stacks is expected to behave.
From the video presentation I understood that Stacks merely is a new way of grouping otherwise unrelated resources:
As I wrote above, I wonder what will happen if I delete a Stack that's referencing a resource used by another stack (or by no stack at all but just a common resource group).
I believe my suggestion will be very advantageous to Bicep and bring the whole deployment process a large leap forward. (I.e. only a single PowerShell command compared to four, being able to boil the whole deployment process, no matter how complex, down to a single Bicep file.)
I would very much want to bring this idea forward. Would you suggest to copy my suggestion to Azure/bicep#788?
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @satyavel, @apclouds.
Issue Details
Description
According to @alex-frankel's answer to my original question, a subscription
Bicep file may load and execute a resouceGroup
Bicep file in order to (re-)create a resource group and all resources contained therein.
While the New-AzResourceGroupDeployment
Cmdlet comes with a Mode
parameter, providing an option to either leave all existing resources (Incremental
) or remove all resources not existing in the ARM template being deployed. (Complete
). the New-AzSubscriptionDeployment
lacks this parameter.
Question
In order to create idempotent Bicep files, I think the Mode
parameter is crucial, even to New-AzSubscriptionDeployment
, as it may execute a resourceGroup
Bicep module.
You think so, too? Then I'd create a Feature Request issue.
Author: | SetTrend |
---|---|
Assignees: | - |
Labels: |
|
Milestone: | - |