TL;DR
You can set Diagnostic Settings on Azure Management Groups with API, and by extension Terraform AzApi!
This will only be a quick update on my recent post about exporting Activity Log to Event Hub with Terraform.
After a LinkedIn comment from Mats Estensen, I was made aware of the Azure Management Group Activity Logs. This is also a resource I want to add diagnostic settings to, and I won’t say no to a chance for practicing my AzApi skills :-)
This article from Microsoft tells about the possibility of adding diagnostic settings to an Azure Management Group with the Azure REST API. It seems to be about Sentinel, but it also shares good information that sparks some thoughts on other possibilities. Can we configure this with Terraform?
Management Group Activity Log records important events that happen on your Management Group scopes. The categories that seem to be available are “Administrative” for RBAC assignments, and “Policy” for Azure Policy events. I don’t think this log is recursive, meaning you might need to add a diagnostic setting for each level. Initial testing indicates that this is for current management group only, and not child groups automatically.
Using this information, I could quickly determine that this would be possible to set with the AzApi provider for Terraform. As I - among others - use to say..
Anything possible with the ARM API is possible with Terraform AzApi!
- Me
After assuming this can be configured with AzApi, I needed to find the correct syntax for adding the resource. Luckily Microsoft has recently added Terraform to the great Azure Resource Reference! Given this terrific source of information, I easily found the correct AzApi syntax, and added it to my Terraform config.
First i tried scope of the diagnostic setting (parent_id) set to only the name of my Management Group, but this turned out to not be correct. Tried this because the name is also called an UUID or ID.
I needed to determine the Resource ID of my Management Group. Luckily I found some more good information from Microsoft, and determined that it should be:
/providers/Microsoft.Management/managementGroups/
This led me to the correct configuration for my use case. The Terraform code can be found in my GitHub repository.
resource “azapi_resource” “diag-setting-management-group” { type = “Microsoft.Insights/diagnosticSettings@2021-05-01-preview” name = “toEventHub” parent_id = “/providers/Microsoft.Management/managementGroups/groupname” #UPDATE ME body = jsonencode({ properties = { eventHubAuthorizationRuleId = azurerm_eventhub_namespace_authorization_rule.listen-send.id eventHubName = azurerm_eventhub.activity-logs.name logs = [ … ] } }) }
After applying it the setting is deployed correctly! 🥳
Now, I could add workspaceId or storageAccountId, or both to send to all possible destinations, but this would be greedy, no? 😂
resource “azapi_resource” “diag-setting-management-group” {
type = “Microsoft.Insights/diagnosticSettings@2021-05-01-preview”
name = “toEventHub”
parent_id = “/providers/Microsoft.Management/managementGroups/groupname” #UPDATE ME
body = jsonencode({
properties = {
workspaceId = “log-analytics-workspace-resource-id”
storageAccountId = “storage-account-resource-id”
eventHubName = “eventhubname”
eventHubAuthorizationRuleId = “eventhubauthorizationruleid”
logs = [ … ]
}
})
}
You should ideally use Resource IDs from data sources in the Terraform code, but in this test case a plaintext string works fine. Resource ID from a resource or data source will ensure implicit dependencies are handled correctly by Terraform. You won’t have a Management Group with my name on it, and it will fail if you don’t update the parent_id.
As always, there is much to learn, and I appreciate feedback and comments from anyone willing to share. Mats Estensen in this case, shared an additional approach, which motivated me to write this follow up post.
A big thank you to anyone sharing their knowledge, and driving the communities forward! 😊
Comments welcome, and please let me know if you found it useful 💡