Search code examples
azureazure-devopsazure-cliazure-rm-templateazure-bicep

My Az cli what-if for a bicep deployment at Management scope is not showing the change at the nested management group


So I have a bicep deployment file that creates a subscription and passes the subscription ID to another bicep file that targets management group scope to deploy resourcegroup and the other resource.

when I run a what-if to see changes, I see only the changes at the scope of the bicep file that deploys the subscription.

enter image description here

az deployment mg what-if --name 'name' --management-group-id '$(mgmtgroupid)' --location"$(location)" --    template-file '.A.bicep' 

biceps look like this

** A.bicep**

 targetScope = 'managementGroup'

       module subAlias './modules/subscription.bicep' = {
         name: 'create-${subscriptionAlias}'
          params: {
              billingAccount: billingAccount
             subscriptionAlias: subscriptionAlias
              subscriptionDisplayName: subscriptionDisplayName
               subscriptionWorkload: environmentconfigurationMap[environment].subscriptionWorkload
          }
       }

     module createResourceGroupStorage 'B.bicep' = {
      name: 'nested-createResources-${subscriptionDisplayName}'
       params:{
           subID : subAlias.output.subscriptionID  
         }
     

B.bicep

        targetScope = 'managementGroup'

       {{other modules that deploy resourcesgroup and other resources}}

Expecting to see the changes from the nested deployment happening in B.bicep and not just that happening in A.bicep

example is below but it is a Subscription scoped deployment.

enter image description here


Solution

  • Update

    Per your follow-up query,

    Tried the answer by hardcoding the subID to the B.bicep and it worked; the question now is, how do I pass the value of the output from the subscription module to the B.bicep as a parameter value ?

    If you prefer Azure CLI tool, after you succeed in creating a new subscription with the subscription module, you can use the az deployment mg show command to retrieve the valid subscriptionId output from 1stARMDeployment-CreateNewSub and then pass it into the B.bicep as a parameter value for 2ndARMDeployment-CreateResourcesFromB.

    Add output subscriptionId string = subAlias.outputs.subscriptionId in A.bicep;

    targetScope = 'managementGroup'
    
    module subAlias './modules/subscription.bicep' = {
      name: 'create-${subscriptionAlias}'
      params: {
        billingAccount: billingAccount
        subscriptionAlias: subscriptionAlias
        subscriptionDisplayName: subscriptionDisplayName
        subscriptionWorkload: environmentconfigurationMap[environment].subscriptionWorkload
      }
    }
    
    output subscriptionId string = subAlias.outputs.subscriptionId
    

    PowerShell

    $newSubID = $(az deployment mg show --name '1stARMDeployment-CreateNewSub' --management-group-id 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' --query properties.outputs.subscriptionId.value)
    
    az deployment mg what-if --name '2ndARMDeployment-CreateResourcesFromB' --management-group-id 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' --location "southeast asia" --template-file 'B.bicep' --parameters subID=$newSubID
    

    enter image description here


    Based on your description, I managed to reproduce the issue via local PowerShell with the sample bicep templates below.

    A.bicep

    param subscriptionDisplayName string = 'Azure Subscription ARM1'
    param subscriptionAlias string = 'subARM1'
    param billingAccount string = '/providers/Microsoft.Billing/billingAccounts/123456/enrollmentAccounts/654321'
    param environment string = 'Prod'
    param environmentconfigurationMap object= {
      Prod: {
        subscriptionWorkload: 'Production'
      }
    }
    
    targetScope = 'managementGroup'
    
    module subAlias './modules/subscription.bicep' = {
      name: 'create-${subscriptionAlias}'
      params: {
        billingAccount: billingAccount
        subscriptionAlias: subscriptionAlias
        subscriptionDisplayName: subscriptionDisplayName
        subscriptionWorkload: environmentconfigurationMap[environment].subscriptionWorkload
      }
    }
    
    module createResourceGroupStorage 'B.bicep' = {
      name: 'nested-createResources-${subscriptionDisplayName}'
      params:{
          subID : subAlias.outputs.subscriptionId // Require a valid subID
        }
    }
    

    /modules/subscription.bicep

    targetScope = 'managementGroup'
    
    @description('BillingAccount used for subscription billing')
    param billingAccount string
    
    @description('Alias to assign to the subscription')
    param subscriptionAlias string
    
    @description('Display name for the subscription')
    param subscriptionDisplayName string
    
    @description('Workload type for the subscription')
    param subscriptionWorkload string
    
    resource alias 'Microsoft.Subscription/aliases@2020-09-01' = {
      scope: tenant()
      name: subscriptionAlias
      properties: {
        workload: subscriptionWorkload
        displayName: subscriptionDisplayName
        billingScope: billingAccount
      }
    }
    
    output subscriptionId string = alias.properties.subscriptionId
    
    

    B.bicep

    targetScope = 'managementGroup'
    
    @description('subscriptionId for the deployment')
    param subID string
    
    @description('Name of the resourceGroup, will be created in the same location as the deployment.')
    param resourceGroupName string = 'rg-armdemo'
    
    @description('Location for the deployments and the resources')
    param location string = deployment().location
    
    // deploy to the subscription and create the resourceGroup
    module rg './modules/resourcegroup.bicep' = {
      scope: subscription(subID)
      name: 'create-${resourceGroupName}'
      params: {
        resourceGroupName: resourceGroupName
        location: location
      }
    }
    

    /modules/resourcegroup.bicep

    targetScope = 'subscription'
    
    @description('Name of the resourceGroup.')
    param resourceGroupName string
    
    param location string = deployment().location
    
    resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
      name: resourceGroupName
      location: location
    }
    

    Image If directly using a string of subID instead of the outputs from the upstream module, the what-if command was able to preview the resources to be deployed in B.bicep. The behavior is by-design, since the what-if command can only preview the changes in a deployment rather than make any changes to existing resources. Besides, the resource for deployment in B.bicep requires to use a valid subID, while what-if command doesn't output such a value.

    Image

    Regarding the Scope concern, it should be consistent with the deployment scope of each resource to be deployed. Taking my C.bicep template below to create a new management group for example, its scope was the same as that of a new subscription in A.bicep but different from that of a new resource group in B.bicep.

    Image