ARM template enforcing script execution order and timing in a loop
In a recent project we were trying to setup an active-active MariaDB cluster with custom script extension in an ARM template. The VMs were created in a loop. The scripts were written to have strict order of execution. Script for second VM should not start to execute until script for the first VM has completed and so forth so on. However, in a VM loop, the next VM provision may start before the previous one is completed. This could result in scripts execution overlap from different VMs created in a loop. To ensure the order and timing of the script execution, I created an array variable that defines the order of the execution. This variable was then used by the script extension to enforce the execution order.
In this particular implementation, the array variable, dbscriptDependencies, contained items ordered by script sequence. The number of items defined in this variable needed to match the max number of VMs. In this case, we limited the number of VMs in the set to 5. The dbscriptDependencies was then used as script extension dependency (in addition to the vmloop).
Below were the details of the template (https://github.com/harrchen/armscriptorder).
The VM loop was straightforward:
The script extension loop was also straightforward except for the scriptDependencies variable dependency in addition to the VM loop (vmloop):
The variable array was defined as below. The first entry could be anything as first script can run as soon as VM was ready. In this case, we just used the vnet as a convenience. The remainder of the entries were ordered by the sequence of the scripts:
Below were the execution result. As you can see, the VM provision completed pretty quickly but script execution took some time. Without the additional script dependency, the script would have executed concurrently. With the additional dependency, the scripts executed in an orderly fashion.
Full source is available (https://github.com/harrchen/armscriptorder)