Logging Architecture — the good, the bad and the automated

Developing logging architecture can be complex and there can be a lot of considerations that need to be taken into account. These may or may not be immediately apparent but will come to fruition most likely after implementation.

When it comes to managing a large number of resources, policies can be a blessing but what if you apply some settings which were not quite right or you want to undo? Unfortunately, there is no undo button.

Without the possibility to undo our actions this means that it then becomes a tedious task to go through each resource one by one and remove the diagnostics setting(s).

This tool aims to be the solution to this exact problem.

Github Link — https://github.com/luketylerwilliams/AzQuickLog

The Tool

This is where AzQuickLog comes into play. At the time of writing this only encompasses diagnostics logs but in future could also include activity logs.

So how does it work?

The tool can take multiple different options:

  • Scope — This should be one of the following (case insensitive); [1] Management group, [2] Subscription, [3] Resource Group — For ease of use either the value or relative number can be specified. If resource group is chosen then the parent subscription id must be provided — Parameter is -Scope
  • Scope Id — Specify the Id of the scope object. For example we have a management group named “lukeroot”, the parameter should be as follows: -ScopeId “lukeroot” — Parameter is -ScopeId
  • Diagnostic Setting Name (optional) — If this is not specified then it will effect all — Parameter is -DSName
  • Target (optional) — Resource Type — Only provide the name of the resource type, e.g. for a Storage Account the resource type is “Microsoft.Storage/storageAccounts”, provide “storageAccounts” — Parameter is -Target

Sub-menu options:

1: Print resources found in specified scope
2: Find all resources with diagnostic setting name: <Provided-DSName> and target: <Provided-Target>
3: Delete the specified diagnostic settings from resources: <Provided-DSName> and target: <Provided-Target>
Q: Press “Q” to quit


Capture of main menu

Usage Example

For this example we will target a management group names ‘Global’ and remove all of the diagnostic settings from the resources in the subscriptions beneath the given scope.

After inputting the following parameters per the above example architecture:

  • Scope: 1 = Management group
  • ScopeId: Global
  • DSName: logging-diag-setting

The script will perform various different functions before prompting you with a sub-menu allowing you to choose what action you wish to take.

Output after specifying above values

Sub-menu outputs

Output of option 1

Output of option 1 using the example architecture

Output of option 2 with no matches:

Output of option 2 using example architecture

Example of option 2 with matches:

First, in the portal we add diagnostic setting named ‘logging-diag-setting’ to the storage account ‘luketesttesttest’

Diagnostic setting ‘logging-diag-setting’ added to storage account ‘luketesttesttest’
Example of script output of option 2, showing match

Example of option 3 with matches:

The following shows the output of option 3, resulting in a deletion of the desired diagnostic setting from all resources under the given scope of ‘Global’ management group.

Example output of option 3 with matches
Example of audit log file for the above removal


Screenshots in above examples may differ slightly as new updates are pushed which likely include new features or improvements. However, on the whole overall functionality is the same except there may obviously be additional capability.

v1.1 Release

  • Update to logic to fix some issues with error handling and scoping of functions
  • Added WhatIf functionality to provide an overview of actions which would take place
Added option 4 for WhatIf

Further improvement ideas

As I was writing this I did have further ideas on how to improve this but would also love to hear any feedback from other people! Other ideas include:

  • For the target parameter potentially make it possible to select on Resource Name Prefix/Suffix
  • Further optimizations — enhance the capability of the capturing the resources per subscription by saving each in a hash function with key/value pairs. Then for the remove function match enumerate through subscriptions keys for removal at management group scope
  • Add functionality to remove all diagnostic settings from specified resources within specified scope
  • Troubleshoot the below edge-case when running remediation against a resource which has been remediated and the diagnostic setting name is the same
# Error handling for error<# Remove-AzDiagnosticSetting : Exception type: ErrorResponseException, Message: Null/Empty, Code: Null, Status code:Conflict, Reason phrase: ConflictAt C:\Users\Admin\Downloads\azquicklog.ps1:365 char:27+ … emoveDiag = Remove-AzDiagnosticSetting -ResourceId $azDiagid -Name $a …+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : CloseError: (:) [Remove-AzDiagnosticSetting], PSInvalidOperationException+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Insights.Diagnostics.RemoveAzureRmDiagnosticSettingCommand #>

Wrapping up

I hope you’ve enjoyed the article. If you have any questions, ideas, or suggestions, please feel free to reach out via Twitter or in the comments below!

Thanks for reading!


Credits to Charbel Nemnom for logic around diagnostics setting removal // @CharbelNemnom // https://charbelnemnom.com/removing-diagnostic-settings-configuration-for-azure-resources/

A collection of azure articles and ramblings // Cloud Security Consultant @ Integrity360 // Comments and thoughts are my own