Do you want to get granular insights on your technical Azure Governance implementation? - document it in CSV, HTML, Markdown and JSON?
AzGovViz is a PowerShell based script that iterates your Azure Tenant´s Management Group hierarchy down to Subscription level. It captures most relevant Azure governance capabilities such as Azure Policy, RBAC and Blueprints and a lot more. From the collected data AzGovViz provides visibility on your HierarchyMap, creates a TenantSummary, creates DefinitionInsights and builds granular ScopeInsights on Management Groups and Subscriptions. The technical requirements as well as the required permissions are minimal.
You can run the script either for your Tenant Root Group or any other Management Group.
Listed as tool for the Govern discipline in the Microsoft Cloud Adoption Framework!
https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/reference/tools-templates#govern
Included in the Microsoft Cloud Adoption Framework´s Strategy-Plan-Ready-Gov Azure DevOps Demo Generator template.
Changes (2021-May-19)
- Removed Azure PowerShell module requirement Az.ResourceGraph
- TenantSummary 'Change tracking' section. Tracks newly created and updated custom Policy, PolicySet and RBAC Role definitions, Policy/RBAC Role assignments and Resources that occured within the last 14 days (period can be adjusted using new parameter
-ChangeTrackingDays
) - New parameters
-PolicyIncludeResourceGroups
and-RBACIncludeResourceGroupsAndResources
- include Policy assignments on ResourceGroups, include Role assignments on ResourceGroups and Resources - New parameters
-PolicyAtScopeOnly
and-RBACAtScopeOnly
- removing 'inherited' lines in the HTML file; use this parameter if you run against a larger tenants - New parameter
-CsvExport
- export enriched data for 'Role assignments', 'Policy assignments' data and 'all resources' (subscriptionId, managementGroup path, resourceType, id, name, location, tags, createdTime, changedTime) - !experimental New parameter
-JsonExport
- export of ManagementGroup Hierarchy including all MG/Sub Policy/RBAC definitions, Policy/RBAC assignments and some more relevant information to JSON - Added ClassicAdministrators Role assignment information
- Restructure TenantSummary - Limits gets its own section
- Added sytem metadata for Policy/RBAC definitions and assignments
- New parameter
-FileTimeStampFormat
- define the time format for the output files (default isyyyyMMdd_HHmmss
) - Updated API error codes
- Cosmetics / Icons
- Bugfixes
- Performance optimization
Enterprise-Scale (WingTip) implementation |
- Hierarchy of Management Groups
- Builds a visual hierarchy of your Management Group setup including count of linked Subscriptions
- Azure Policy
- Custom Policy definitions
- Scope information
- Policy effect
- If Policy effect is DeployIfNotExists (DINE) will show the specified RBAC Role
- List of assignments
- Usage in custom PolicySet definitions
- System metadata 'createdOn, createdBy, updatedOn, updatedBy'
- Orphaned custom Policy definitions
- List of custom Policy definitions that matches the following criteria:
- Policy definition is not used in any custom PolicySet definition
- No Policy assignment exists for the Policy definition
- List of custom Policy definitions that matches the following criteria:
- Custom PolicySet definitions
- Scope information
- List unique assignments
- List of Policy definitions used
- Orphaned custom PolicySet definitions
- Criteria: no Policy assignment exists for the PolicySet definition
- Custom PolicySet definitions using deprecated built-in Policy definitions
- Policy assignments of deprecated built-in Policy definition
- Policy Exemptions
- Lists all Exemptions (scopes: Management Groups, Subscriptions, ResourceGroups, Resources)
- Enrich information on Exemption scope
- Summary on expired Exemptions
- Policy assignments throughout the entirety of scopes (Management Groups, Subscriptions)
- Core information on Policy assignments
- Advanced/enriched information on Policy assignments
- Policy assignment scope (at scope/inheritance)
- Indicates if scope is excluded from Policy assignment
- Indicates if Exemption applies for scope
- Policy/Resource Compliance (Policy: NonCompliant, Compliant; Resource: NonCompliant, Compliant, Conflicting)
- Related RBAC Role assignments (if Policy effect is DeployIfNotExists (DINE))
- System metadata 'createdOn, createdBy, updatedOn, updatedBy'
- Custom Policy definitions
- Role-Based Access Control (RBAC)
- Custom Role definitions
- List assignable scopes
- System metadata 'createdOn, createdBy, updatedOn, updatedBy'
- Orphaned custom Role definitions
- List of custom Role definitions that matches the following criteria:
- Role definition is not used in any Role assignment
- List of custom Role definitions that matches the following criteria:
- Orphaned Role assignments
- List of Role assignments that matches the following criteria:
- Role definition was deleted although and assignment existed
- Role assignmet's target identity (User, Group, ServicePrincipal) was deleted
- List of Role assignments that matches the following criteria:
- Role assignments throughout the entirety of scopes (Management Groups, Subscriptions)
- Core information on Role assignments
- Advanced information on Role assignments
- Role assignment scope (at scope / inheritance)
- For Role Assignments on Groups the AAD Group members are fully resolved. With this capability AzGovViz can ultimately provide holistic insights on permissions granted
- For identity-type == 'ServicePrincipal' the type (Application/ManagedIdentity) will be reported
- For identity-type == 'User' the userType (Member/Guest) will be reported
- Related Policy assignments (Policy assignment of a Policy definition that uses the DeployIfNotExists (DINE) effect)
- System metadata 'createdOn, createdBy'
- Role assignments ClassicAdministrators
- Security & Best practice analysis
- Existence of custom Role definition that reflect 'Owner' permissions
- Role assignments for 'Owner' permissions on identity-type == 'ServicePrincipal'
- Role assignments for 'Owner' permissions on identity-type != 'Group'
- Role assignments for 'User Access Administrator' permissions on identity-type != 'Group'
- High priviledge Role assignments for 'Guest Users' (Owner & User Access Administrator)
- Custom Role definitions
- Blueprints
- Blueprint scopes and assignments
- Orphaned Blueprints
- Management Groups
- Management Group count, level/depth, MG children, Sub children
- Hierarchy Settings | Default Management Group Id
- Hierarchy Settings | Require authorization for Management Group creation
- Subscriptions, Resources
- Subscription insights
- QuotaId, State, Tags, Azure Security Center Secure Score, Cost, Management Group path
- Tag Name usage
- Insights on usage of Tag Names on Subscriptions, ResourceGroups and Resources
- Resources
- Resource Types
- ResourceType count per location
- ResourceType capability for Resource Diagnostics including
- ResourceType count and information if capable for logs including list of available og categories
- ResourceType count and information if capable for metrics
- Lifecyle recommendations for existing Azure Policy definitions that configure Resource diagnostics of type=Log
- Check if Policy definitions hold the latest set of applicable log categories
- Recommendation to create Policy definition for ResourceType if supported
- Lists all PolicyDefinitions that deploy Resource diagnostics of type=log, lists Policy assignments and PolicySet assignments if the Policy defintion is used in a PolicySet definition
- Resource Provider
- Resource Provider state aggregation throughout all Subscriptions
- Explicit Resource Provider state per Subscription
- Resource Locks
- Aggregated insights for Lock and respective Lock-type usage on Subscriptions, ResourceGroups and Resources
- Resource Types
- Subscription insights
- Limits
- Tenant approaching ARM limits:
- Custom Role definitions
- PolicySet definitions
- Management Groups approaching ARM limits:
- Policy assignment limit
- Policy / PolicySet definition scope limit
- Role assignment limit
- Subscriptions approaching ARM limits:
- ResourceGroup limit
- Subscription Tags limit
- Policy assignment limit
- Policy / PolicySet definition scope limit
- Role assignment limit
- Tenant approaching ARM limits:
- Azure Active Directory (AAD)
- Insights on those Service Principals where a Role assignment exists (scopes: Management Group, Subscription, ResourceGroup, Resource):
- Type=ManagedIdentity
- Core information on the Service Principal such as related Ids and use case information
- Type=Application
- Secrets and Certificates expiry information & warning
- Report on external Service Principals
- Type=ManagedIdentity
- Insights on those Service Principals where a Role assignment exists (scopes: Management Group, Subscription, ResourceGroup, Resource):
- Consumption
- Aggregated consumption insights throughout the entirety of scopes (Management Groups, Subscriptions)
- Change tracking
- Policy
- Created/Updated Policy and PolicySet definitions (system metadata 'createdOn, createdBy, updatedOn, updatedBy')
- Created/Updated Policy assignments (system metadata 'createdOn, createdBy, updatedOn, updatedBy')
- RBAC
- Created/Updated Role definitions (system metadata 'createdOn, createdBy, updatedOn, updatedBy')
- Created Role assignments (system metadata 'createdOn, createdBy)
- Resources
- Aggregated insights on Created/Changed Resources
- Policy
HTML file
HierarchyMap
TenantSummary
DefinitionInsights
ScopeInsights
*IDs from screenshot are randomized
markdown in Azure DevOps Wiki as Code
*IDs from screenshot are randomized
- CSV file
- HTML file
- the HTML file uses Java Script and CSS files which are hosted on various CDNs (Content Delivery Network). For details review the BuildHTML region in the PowerShell script file.
- Browsers tested: Edge, new Edge and Chrome
- MD (Markdown) file
- for use with Azure DevOps Wiki leveraging the Mermaid plugin
- JSON file (experimental)
- export of ManagementGroup Hierarchy including all MG/Sub Policy/RBAC definitions, Policy/RBAC assignments and some more relevant information to JSON
Note: there is some fixing ongoing at the mermaid project to optimize the graphical experience:
mermaid-js/mermaid#1177
Short presentation on AzGovViz Download
This permission is mandatory in each and every scenario!
Scenario | Permissions |
---|---|
ANY Console or AzureDevOps Pipeline |
Reader Role assignment on Management Group |
Scenario | Permissions | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
A Console | Member user account |
No AAD permissions required | |||||||||||||||
B Console | Guest user account |
Add assignment for the Guest user to AAD Role Directory readers OR Use parameters: -NoAADGuestUsers -NoAADGroupsResolveMembers -NoAADServicePrincipalResolve 💡 Compare member and guest default permissions |
|||||||||||||||
C Console | Service Principal |
Option 1 (simple setup but more read permissions than required) Add assignment for the Service Principal to AAD Role Directory readers 💡 Directory readers Option 2 (explicit permission model)
|
|||||||||||||||
D Azure DevOps Pipeline | ServicePrincipal (ServiceConnection) |
Option 1 (simple setup but more read permissions than required) Add assignment for the Azure DevOps Service Connection's Service Principal to AAD Role Directory readers 💡 Directory readers Option 2 (explicit permission model)
|
-
Requires PowerShell 7 (minimum supported version 7.0.3)
-
Requires PowerShell Az Modules
- Az.Accounts
- Az.Resources
Az.ResourceGraph- Install the Azure Az PowerShell module
-
Usage
.\AzGovVizParallel.ps1 -ManagementGroupId <your-Management-Group-Id>
-
Parameters
-ManagementGroupId
Tenant Id or any child Management Group Id-CsvDelimiter
the world is split into two kind of delimiters - comma and semicolon - choose yours-OutputPath
-AzureDevOpsWikiAsCode
-DoNotShowRoleAssignmentsUserData
scrub personally identifiable information (PII)-LimitCriticalPercentage
limit warning level, default is 80%-HierarchyTreeOnly
-HierarchyMapOnly
output only the HierarchyMap for Management Groups including linked Subscriptions-SubscriptionQuotaIdWhitelist
process only Subscriptions with defined QuotaId(s)-NoResourceProvidersDetailed
disables output for ResourceProvider states for all Subscriptions in the TenantSummary section, in large Tenants this can become time consuming-NoASCSecureScore
disables ASC Secure Score request for Subscriptions. The used API is in preview you may want to disable this-DisablePolicyComplianceStates
-NoPolicyComplianceStates
will not query policy compliance states. You may want to use this parameter to accellerate script execution or when receiving error 'ResponseTooLarge'.-NoResourceDiagnosticsPolicyLifecycle
disables Resource Diagnostics Policy Lifecycle recommendations-NoAADGroupsResolveMembers
disables resolving Azure Active Directory Group memberships-NoAADGuestUsers
disables resolving Azure Active Directory User type (Guest or Member)-NoServicePrincipalResolve
-NoAADServicePrincipalResolve
disables resolving ServicePrincipals-ServicePrincipalExpiryWarningDays
-AADServicePrincipalExpiryWarningDays
define warning period for Service Principal secret and certificate expiry; default is 14 days-NoAzureConsumption
Azure Consumption data should not be collected/reported-AzureConsumptionPeriod
define for which time period Azure Consumption data should be gathered; default is 1 day-NoAzureConsumptionReportExportToCSV
Azure Consumption data should not be exported (CSV)-NoScopeInsights
- Q: Why would you want to do this? A: In larger tenants the ScopeInsights section blows up the html file (up to unusable due to html file size)-ThrottleLimit
- leveraging PowerShell´s parallel capability you can define the ThrottleLimit (default=5; 💡 values from 5 up to 15 proved to perform best)-DoTranscript
- log the console output-SubscriptionId4AzContext
- Define the Subscription Id to use for AzContext (default is to use a random Subscription Id)-PolicyAtScopeOnly
- removing 'inherited' lines in the HTML file for 'Policy Assignments'; use this parameter if you run against a larger tenants-RBACAtScopeOnly
- removing 'inherited' lines in the HTML file for 'Role Assignments'; use this parameter if you run against a larger tenants-CsvExport
- export enriched data for 'Role assignments', 'Policy assignments' data and 'all resources' (subscriptionId, managementGroup path, resourceType, id, name, location, tags, createdTime, changedTime)-PolicyIncludeResourceGroups
- include Policy assignments on ResourceGroups-RBACIncludeResourceGroupsAndResources
- include Role assignments on ResourceGroups and Resources-ChangeTrackingDays
- define the period for Change tracking on newly created and updated custom Policy, PolicySet and RBAC Role definitions and Policy/RBAC Role assignments (default is '14')-FileTimeStampFormat
- define the time format for the output files (default isyyyyMMdd_HHmmss
)-JsonExport
- enable export of ManagementGroup Hierarchy including all MG/Sub Policy/RBAC definitions, Policy/RBAC assignments and some more relevant information to JSON
-
Passed tests: Powershell Core 7.1.2 on Windows
-
Passed tests: Powershell Core 7.1.3 Azure DevOps hosted ubuntu-18.04
The provided example Pipeline is configured to run based on a schedule (every 12 hours). It will push the AzGovViz markdown output file to the 'wiki' folder in the 'Azure-MG-Sub-Governance-Reporting' Repository which will feed your Wiki.
- In Azure DevOps make sure to enable the Multistage Pipelines feature https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/multi-stage-pipelines-experience?view=azure-devops
- Clone the AzGovViz Repo
- Create Pipeline, configure your pipeline selecting Existing Azure Pipelines YAML file, select the AzGovViz YAML from the AzGovViz (Azure-MG-Sub-Governance-Reporting) Repo
- Grant Repository permissions: In order to allow the pipeline to push files back to our 'wiki' folder in the 'Azure-MG-Sub-Governance-Reporting' Repository the Build Service Account ('%ProjectName% Build Service (%OrgName%)') must be granted with Contribute permission
- Run the Pipeline
- Create Wiki by choosing Publish Code as Wiki, define the folder 'wiki' from the 'Azure-MG-Sub-Governance-Reporting' Repository as source
Make sure your Service Connection´s Service Principal has been granted with the required permissions (see Required permissions in Azure Active Directory).
AzGovViz creates very detailed information about your Azure Governance setup. In your organization's best interest the outputs should be protected from not authorized access!
Disabled Subscriptions and Subscriptions where Quota Id starts with with "AAD_" are being skipped, all others are queried. More info on Quota Id / Offer numbers: Supported Microsoft Azure offers .
ARM Limits are not acquired programmatically, they are hardcoded. The links used to check related Limits are commented in the param section of the script.
Please feel free to contribute. Thanks to so many supporters - testing, giving feedback, making suggestions, presenting use-case, posting/blogging articles, refactoring code - THANK YOU!
Thanks Stefan Stranger (Microsoft) for providing me with his AzGovViz outputs executed on his implementation of EnterpriseScale. Make sure you read Stefan´s Blog Article: Enterprise-Scale - Policy Driven Governance
Thanks Frank Oltmanns-Mack (Microsoft) for providing me with his AzGovViz outputs executed on his implementation of EnterpriseScale.
Special thanks to Tim Wanierke, Brooks Vaughn and Friedrich Weinmann (Microsoft).
Kudos to the TableFilter Project Team!
Also check https://www.azadvertizer.net - AzAdvertizer helps you to keep up with the pace by providing overview and insights on new releases and changes/updates for Azure Governance capabilities such as Azure Policy's Policy definitions, initiatives (Set definitions), aliases and Azure RBAC's Role definitions and resource provider operations.
Please note that while being developed by a Microsoft employee, AzGovViz is not a Microsoft service or product. AzGovViz is a personal/community driven project, there are none implicit or explicit obligations related to this project, it is provided 'as is' with no warranties and confer no rights.