ARM deployment, New Azure Deployment options with PowerShell
Tags: azure, powershell, devops, iac
Published: 2020-02-23 16:11:35

Until recently to deploy a resource to Azure using an ARM template and PowerShell you had two options;

the New-AzDeployment cmdlet for subscription scope objects. It permits you to deploy resource groups, policy definitions, custom roles…

And the New-AzResourceGroupDeployment cmdlet for resource group objects. With this cmdlet, you can deploy storage account, VM, Vnet, API Management, everything that needs a resource group …. And yes, resource group too. 

But if you updated your PowerShell AZ Module recently you may have remarked few new cmdlets to deploy resources to Azure.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qrddi13nu5v0nlxb4znv.PNG)

And few others to test your deployments 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/942qekx67h2f7niyzt38.PNG)

Let's try these new deployment tools.

AzDeployment and AzResourceGroupDeployment are still here but we now have three more options, azSubscriptionDeployement, azManagementGroupDeployment and azTenantDeployment. 

First, note, why do we have a new-azDeployment and a new-AzSubscriptionDeployment? They have the same purpose and do the same things, deploy objects at the subscription level.

To investigate you need to open the Az.ressources module folder and open the Az.Resources.psd1 file. you will see that *-AzSubscriptionDeployment is an alias, another name for an existing cmdlet, new-azDeployment. 

The ARM template bellow deploys a resource group in  the current subscription

```json
{
    "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [
      {
        "type": "Microsoft.Resources/resourceGroups",
        "apiVersion": "2018-05-01",
        "location": "westeurope",
        "name": "az-deploy-demo-rg",
        "properties": {}
      }
    ]
}
```

To deploy the template 

```powershell 
New-AzSubscriptionDeployment -Name DevToDemo -Location westeurope -TemplateFile .\subscription.json
```

But you will be able to use New-AzDeployment too

Unlike New-AzSubscriptionDeployment, New-AzManagementGroupDeployment is not an alias. It’s a plain cmdlet designed to deploy objects at the management group level.  At this scope, you can deploy Azure Policies, roles assignments, and blueprints.

An example, to create a custom policy and assign it to a management group you can use this template.

```json
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {
      "mgScope": "/providers/Microsoft.Management/managementGroups/group01"
    },
    "resources": [
      {
        "type": "Microsoft.Authorization/policyDefinitions",
        "name": "policy-marseille",
        "apiVersion": "2016-12-01",
        "properties": {
          "policyType": "Custom",
          "parameters": { },
          "policyRule": {
            "if": {
              "field": "location",
              "equals": "francesouth"
            },
            "then": {
              "effect": "audit"
            }
          }
        }
      },
      {
        "type": "Microsoft.Authorization/policyAssignments",
        "name": "location-lock",
        "apiVersion": "2016-12-01",
        "dependsOn": [ 
            "policy-marseille" 
            ],
        "properties": {
          "scope": "[variables('mgScope')]",
          "policyDefinitionId": "[concat(variables('mgScope'), '/providers/', 'Microsoft.Authorization/policyDefinitions/', 'policy-marseille')]"
        }
      }
    ]
  }
```

The template creates a custom policy, the policy audit if any resource is located in Marseille, France South (No malice here, this is the place I was born), then it assigns this policy to a management group.

To deploy it, use the new cmdlet New-AzManagementGroupDeployment

```powershell
New-AzManagementGroupDeployment -Name Mars13-policy-assign -Location northeurope -TemplateFile .\managementGroup.json -ManagementGroupId group01 
```

We need to provide a name for the deployment (it’s optional but recommended to identify the deployment later), the template file (and template parameters if any) and the Management Group ID. This ID is the unique name of the management group you gave at the creation of the group. 

These new cmdlets open a new approach to defining subscriptions and management group by code using the same principles and the same toolset we use to deploy resources.

The fact that new-azSubscriptionDeployment is an alias of new-AzDeployment makes me deem there will be some breaking change to this module soon.