azure-powershell icon indicating copy to clipboard operation
azure-powershell copied to clipboard

`New-AzSubscriptionDeployment` is lacking `Mode` parameter, right?

Open SetTrend opened this issue 2 years ago • 11 comments

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.

SetTrend avatar Aug 04 '22 18:08 SetTrend

Thank you for your feedback. This has been routed to the support team for assistance.

msftbot[bot] avatar Aug 06 '22 00:08 msftbot[bot]

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.

alex-frankel avatar Aug 10 '22 23:08 alex-frankel

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:

Bicep workflow

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.

SetTrend avatar Aug 11 '22 12:08 SetTrend

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.

alex-frankel avatar Aug 12 '22 21:08 alex-frankel

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.

SetTrend avatar Aug 15 '22 11:08 SetTrend

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?

alex-frankel avatar Aug 15 '22 15:08 alex-frankel

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.

SetTrend avatar Aug 16 '22 14:08 SetTrend

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.

alex-frankel avatar Aug 16 '22 17:08 alex-frankel

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 …

  1. Target scopes could be intermixed in a single Bicep file.
  2. 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:

Stacks

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).

SetTrend avatar Aug 18 '22 12:08 SetTrend

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?

SetTrend avatar Sep 01 '22 11:09 SetTrend

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:

Service Attention, question, ARM - Templates, customer-reported

Milestone: -

msftbot[bot] avatar Sep 02 '22 06:09 msftbot[bot]