Hello again fellow geeks!
Over the past few months I’ve been working with a customer who is just beginning their journey into the cloud. We’ve had a ton of great conversations around security, governance, and operationalizing Microsoft Azure. We recently finalized the RACI and identified the controls required by both their internal security policy and their industry compliance requirements. With those two items complete, we put together our Azure RBAC model and narrowed down the Azure Policies we needed to put in place to satisfy our compliance controls.
After a lot of discussion about the customer’s organization, its geographical locations, business unit makeup, and how its developers and central IT operate, we came up with a subscription model. This customer had decided on an Azure subscription model where each workload would exist in its own subscription. Further, each workload’s production and non-production environment would be segmented in different subscriptions. Keeping each workload in a different subscription ensures no workload will compete for resources with other workloads and hit any subscription limits. Additionally, it allowed the customer to very easily track the costs associated with each workload.
Now why did we use separate production and non-production subscriptions for each workload? One reason is to address the same risk as above where a non-production workload could potentially consume all resources within a subscription impacting a production workload. The other more critical reason is it makes it easier for us to apply different governance and access controls on production workloads vs non-production workloads. The way we do this is through the usage of Azure Management Groups.
Management Groups were introduced into general availability back in late 2018 to help address the challenges organizations were having operating subscriptions at scale. They provided a hierarchal method to apply governance and access controls across a collection of subscriptions. For those of you familiar with AWS, Management Groups are somewhat similar to AWS Organizations and Organizational Units. For my fellow Windows AD peeps, you can think of Management Groups somewhat like the Active Directory container and organizational unit hierarchy in an Active Directory domain where you apply different access control entries and group policy at high levels in the OU hierarchy that is then enforced and inherited down to the children. Management Groups work in a similar manner in that the Azure RBAC definitions and assignments and Azure Policy you assign to the parent Management Groups are inherited down into the children.
Every Azure AD tenant starts with a top-level management group called the tenant root group. Additional management groups created within the tenant are children of the group up to a maximum of 10,000 management groups and up to six levels of depth. Any RBAC assignment or Azure Policy assigned to the tenant root group applies to all children management group in the tenant. It’s important to understand that Management Groups are a resource within the Azure AD tenant and not a resource of an Azure subscription. This will matter for reasons we’ll see later.
The tenant root management group can only be administered by a Global Admin by default and even this requires a configuration change in the tenant. The method is describe here and what it does is places the global administrator performing the action in the User Access Administrator RBAC role at the root of scope. Once that is complete, the name of the root management group could be changed, role assignments created, or policy assigned.
Now there is one aspect of Management Groups that is a bit funky. If you’re very observant you probably noticed the menu option below.
That’s right folks, Management Groups have their own Activity Log. Every action you perform at the management group scope such creating an Azure RBAC role assignment or assigning or un-assigning an Azure Policy is captured in this Activity Log. Now as of today, the only way to access these logs is viewing them through the portal or through the Azure REST API. Unlike the Activity Logs associated with a subscription, there isn’t native integration with Event Hubs or Azure Storage. Don’t be fooled by the Export To Event Hub link seen in the screenshot below, this will simply send you to the standard menu where you would configure subscription Activity Logs to be exported.
Now you could log into the GUI every day and export the logs to a CSV (yes that does work with Management Groups) but that simply isn’t scalable and also prevents you from proactively monitoring the logs. So how do we deal with this gap while the product team works on incorporating the feature? This will be the challenge we address in this series.
Over the next few posts I’ll walk through the solution I put together using Azure Automation Runbooks to capture these Activity Logs and send them to Azure Storage for retention and an Azure Log Analytics Workspace for analysis and monitoring using Azure Monitor.
Continue the series in my second post.
The ability to export management group activity logs is coming. I opened a case on this issue and was told by support it will be end of this month.
Awesome to hear! I had heard this was coming for a long time, so keeping my fingers crossed the timeline is met.
Looks like this is finally happening. It’s in preview currently and not available directly via the Azure portal yet but you can configure via the API.
We’re you able to get this working? I tried hitting this API the other day with a quick and dirty Python script and got a rejection stating I was missing a permission. The user in question was owner at the subscription level, so I am thinking that the API end point is available but Microsoft is someone locking it down via some permission which isn’t yet available. I’ll take a look at it again this week.
Haven’t tried other ways but I was able to get it configured right from the link using the “Try it” button. I only tried with an EventHub and it shows configured when I do a List/Get. Still not seeing the activity logs in EventHub however but it does appear to be configured.
Awesome! What region did you do it out of curiosity?
My EventHub is in West US but when creating the diagnostic setting I didn’t specify location in the JSON body so it defaulted to “global”.