In my last blog I talked about the policy-driven governance with Enterprise-Scale. In this fourth article of my little series about Enterprise-Scale, I will write about one of the options to operationalize Enterprise-Scale: AzOps.
Using Infrastructure-as-Code (IaC) to deploy and manage complex platform infrastructure deployments can quickly become quite tricky. For example, existing IaC code(s) to deploy an Azure platform infrastructure (management groups, policies, RBAC roles, etc.) must be updated when a new Azure resource is added to the platform infrastructure, and available CI/CD pipelines maybe have to be updated too, in order to address new deployment parameters. If the platform has to be changed, for example an additional management group hierarchy is introduced, may also lead to significant coding effort (adding smart logic), with all associated additional work. Furthermore, even more complexity is added when multiple platform engineers are supposed to work on the same IaC for the platform. In the end, it may be that one engineer is responsible for the entire deployment, to avoid breaking all implementation details. And finally, using IaC usually relies on the principle that the source code is the immutable source of truth. As a consequence of this, the expectation is that no changes should be made via other channels, such as the Azure portal or Azure CLI.
A possible solution - AzOps
AzOps is a reference implementation and represents a possible solution to the mentioned challenges with many IaC implementations. It’s important to call out that AzOps is an optional component to operationalize Enterprise-Scale, and there are other options as well. AzOps is orthogonal and can be used in any Azure environment, to transition to IaC once an organization is ready for it. Therefore, AzOps exists in a dedicated GitHub repository.
What is AzOps?
AzOps is an atomic, primitive CI/CD pipeline for the Azure platform scopes (tenant, management groups, and subscriptions). AzOps allows organizations to bring their own Azure Resource Manager (ARM) templates, and deploy them at the designated scope. It helps to keep the Azure platform up-to-date with the ARM-based configuration stored in a Git repository, but it can also be used to update the Git repository with changes made via alternate methods and channels, e.g. via the Azure portal. AzOps is packaged as Docker-compatible container image and invoked as part of an GitHub Action or Azure DevOps Pipelines (or another CI/CD tool). AzOps is used to deploy ARM templates at the scopes where the service principal (used Azure Active Directory identity) has been grated access.
Now a concrete example related to policies:
An engineer works on a new policy (policyDefinitions), and stores it in the Git repository (the new policy is nothing more than an ARM template).
The new policy (ARM template) will used by AzOps to deploy it (Microsoft.Authorization/policyDefinitions resource) at the designated scope.
The engineer can concentrate solely on the policy development (one ARM template), no other changes are required with regards to IaC or CI/CD pipeline.
Azure platform infrastructure in a Git repository
As mentioned above, AzOps enables to store the ARM-based configuration (Azure platform infrastructure) in a Git repository. This includes the Azure resources managementGroups, subscriptions, policyDefinitions, policySetDefinitions, policyAssignments, roleDefinitions, and roleAssignments.
The ARM-based configuration stored in a Git repository may look as follows:
Figure 1: Azure configuration hierarchy stored in a Git repository.
What you can see in figure 1 is the following:
Tenant Root Group
Tenant root management group
Management group for all management-related subscriptions
Subscription used for management-related Azure services
policyAssignments created on the dz-management management group, which deploys a Log Analytics workspace in all subscriptions associated to the management group
I personally really like the approach with AzOps, as it is based on native tools such as Azure PowerShell and ARM templates, and it has been continuously developed and adapted to cover new requirements. Furthermore, the implementation option with AzOps is also described in Enterprise-Scale, in the chapter “[Optional] Getting started with Infrastructure-as-code”.
Finally, another big thank you to @KristianNese for reviewing and providing feedback.