Automation is one of the key benefit of cloud computing. These days, most of the infrastructure and services in cloud is built and configured through automation, and this approach is being referred as Infrastructure as Code (IaC). The benefit of this approach is not only to avoid manual effort and time, but also to standardize the built process through re-usable codes.

Microsoft Azure support various automation tools and approaches. One of the most common deployment method for Azure resources is Azure Resource Manager (ARM) template.

While using ARM template, we often face a requirement where we have to deploy different number of resources at different time. We want our code to be flexible and re-usable for any number of resources. We do not want to change our code every time we need to deploy some resources.

For example, we have prepared an ARM template for Storage Account creation. That single template should deploy 2, 5, 10 or even more Storage Accounts. The users do not need to change the code (deployment file) every time; all they need to do is to update the Parameter file with Storage Account name and location details.

In this article, we will cover the solution for the above requirement, and will deploy different number of Storage Accounts without making any change in the deployment file. The same approach can be followed to create other deployment file, which will make the code extremely flexible and re-usable.

The Approach

• Since we have to deploy multiple Storage Accounts, we will use an Array. We will refer this as StorageArray. This array will contain two Parameters, one for Storage Account name and another for Storage Account location.

• To deploy any number of resources, we will use Copy object. Using Copy object, we can deploy one or more number of resources, as long as the count of resources is less than or equal to 800.

• Inside the Copy object, we will have the Count property, which will define the number of resources to be deployed. Since we do not want to hardcode the count, we need to take a different approach here so that count would be flexible based on user’s input. In this case, the code will get the count from the array length.

The Parameter File

Suppose we would like to deploy three Storage Accounts in South India region, and account type would be Standard_GRS. Then our parameter file would look like this :

As you can see, we are using below two parameters:

• storageAccountType
• StorageArray

Under StorageArray, we are specifying Storage Account Location and Storage Account Name.

The Deployment File

Now that we have decided the basic approach and created our Parameter file, let’s start creating the deployment file.

Parameter Section

In the Parameter Section of the deployment file, we will define below two parameters :


One important point to observe here is; we are just declaring the array in this section, not the parameters within the array (StorageAccountLocation and StorageAccName).

Resource Section

Since we are going to deploy Storage Account, resource type would be:


Now, we will use Copy function so that the code would work for any number of Storage Accounts. The Copy function works like a loop. Inside the copy function, we have to specify below properties:

Name : Name of this loop. This name should be unique within the deployment file, means no other loop should use this name. This is the name which we will use later to refer the loop. 

Count : The Count property under the Copy ( ) function would determine number of iterations, which in this case would be the number of Storage Accounts. We are not going to hardcode the count within deployment file. Instead, we willuse parameter length to get the count. For example, if we enter 3 Storage Accounts name and location in the parameter file, the parameter length would be 3, and the loop will run 3 times, creating 3 storage accounts.

Now that we have defined copy function and all its components, we can now move on to actual deployment.

The deployment will use the loop named “store”, and will take parameters one by one as mentioned below:

1) name : This will be the name of the Storage Account, which it will take from the parameter file. Since this is a loop, it will take the positional parameter from the array using below expression:


The copyIndex() function returns the current iteration of the loop. It starts counting from zero.

Here copyIndex('Store') will return the current index (iteration) of the loop named “store”, which we have declared earlier. Accordingly, the appropriate Storage Account name will be picked up from the array within the parameter file, which matches the current index.

2) location : Location of the Storage Account. This will also come from the same array, and will follow below expression:


3) SKU : This parameter is not coming from the array, so it has a simple expression :


4) Kind : We want that all Storage Accounts would be created as General Purpose V2. So we have hard coded this value in the deployment file.

"kind": "StorageV2"

So, our [resources] section will look like this :

Validate and Deploy

We are going to deploy this ARM Template through Visual Studio. Before deployment, we would like to validate the files and the parameters.

So,our deployment is complete, and we can see below three storage accounts which we have mentioned in the parameter file.


In this article, we have seen how can we leverage copy object and Arrays to make our code flexible for any number of resources. I suggest to follow same approach for each and every ARM template whenever possible and feasible. 

You can get the complete code from here

See Also