Deploy Azure Linux Virtual Machines with LAD 3.0 Diagnostics Extension from Azure DevOps
Note that what follows is specific to the implementation of deploying a Linux ARM template with diagnostics enabled from Azure DevOps pipeline.
I was recently tasked with enabling diagnostics (LAD 3.0 extension) on a client's Linux ARM templates. The previous method was to have the diagnostics enabled post deployment but, as we know, having the diagnostics enabled via the ARM template allows for more consistent and less error prone deployment. I had easily been able to add diagnostics to their Windows ARM template so I thought that adding the Linux diagnostics would be a breeze. As a quick overview, diagnostic logging for Azure virtual machines allow you to monitor the health of the VM by sending information about performance counters and metrics to a logging location. Without going into too much detail, there are a number of locations to which you can send diagnostic logging for VMs including Event Hubs and Storage Accounts. From there one can peruse/ingest the information logged.
There is an example configuration that Microsoft gives that clients typically begin with before more customizations are added as needed. This example can be found here. One would simply need to add the extension as a separate resource in the template with a dependency on the virtual machine deployment. As we can see in the linked example, there is a protected setting section. Here is where we list the settings needed to continuously send the logging information to a storage account (in this case). The storage account name and endpoint properties are fairly self-explanatory. Where I ran into trouble was the storage account SAS token. The documentation mentions briefly that we must use a list() function (there are several list() functions for use in ARM templates depending on the resource) linked in that page in order to retrieve the SAS token from the storage account. What is not clear about using the list() function documentation is where exactly to place it. The documentation would have us use the function at the place that we need it, which may lead us to believe that the protected settings should look something like this:
I will note here that there are two pieces to build the Storage Account SAS token in JSON. In addition to the name of the storage account, you will notice the parameter of accountSasProperties. This parameter is an object that contains specifications for the SAS token. An example of the accountSasProperties parameter would be the following (in the parameters section of the template):
There are other values that can be specified for the SAS token: https://docs.microsoft.com/en-us/rest/api/storagerp/storageaccounts/listaccountsas
The above example are the specific signedServices, signedPermission, and signedResourceTypes permission values needed for out purposes. This configuration, however, kept throwing an error that the expiration date on the accountSasProperties object was invalid: Values for request parameters are invalid: signedExpiry I kept struggling to find alternative ways to list the expiration date of the SAS token even though my initial way was correct according to the documentation. I can only assume that the script that runs the extension on the machine has an issue concatenating and/or parsing the result of the listAccountSas function and the accountSasProperties but I actually am not sure why the error comes about. Once I came to the conclusion that it might be a concat/parsing error, I decided to have the function generating the SAS token as a parameter rather than in the protected settings, like so:
Note that the sasToken parameter is a securestring to protect the SAS token during deployment. The final version of the protected settings is:
This worked for me and I hope I have saved others a headache figuring this out. The most I could find out about this is that this is a long standing bug with the ARM extension as of today, 05-13-2020 as it should be available in the actual protected settings section rather than as a parameter.