Custom libraries
Creating custom libraries to be hosted in GitHub, checking the contents, generating documentation, and creating tags and releases for sematic versioning.
Table of Contents
Overview
The focus of the deploy lab series for both Azure Landing Zone and Sovereign Landing Zone was the platform libraries themselves, and the local override library that you then added to your repo before testing and deploying via the CI/CD pipelines.
For most customers this will be all they ever need.
The platform libraries will be updated over time, and you have control on how and when you update to a more recent version using the semantic versioning specified in the ref argument for either the alz provider block’s library_references array or in the local override metadata’ dependencies array.
The local override library can be use to add or remove whole definitions or assignments, and the module block can be used to modify those assignments. The local library could also be used to host custom definitions and assignments and extend at that level.
Environment variable are already embedded into the GitHub config that the ALZ Accelerator created, and it wouldn’t take too much to extend that with a more complex pipeline structure for a canary approach.
So, what is the point of a custom library hosted in GitHub?
There are a main reasons, and I’ll give a single word for each: reuse and security.
The main reason is reuse and it particularly valid for the work I do with Microsoft partners. Here they can pull together their own custom definitions into a custom repo and reuse for multiple Azure Landing Zone customers, including support for multiple archetypes and architectures for common patterns, avoiding local overriding by default.
The value is even greater in sovereignty scenarios, where the baseline Sovereign Landing Zone library can be extended and customised with packs specific to requirement for specific regions, countries, and industry compliancy demands.
A benefit is that the custom libraries support semantic versioning, which allows release control at a customer level.
Finally, there is the question of security which is enhanced by keeping the configs cleanly outside of the main customer repo. This allows for a more flexible security model where the right group has access to make feature branch changes to the customer repo, whilst the separate repos for custom library user and for CI/CD workflows remain outside and can have separate RBAC permissions.
These pages specify GitHub for hosting the custom library, but it could be any valid URL format that go-getter can access.
It is assumed that you will be proficient with creating custom policies, assignments and role definitions, and comfortable with git and GitHub. Therefore this page will be reference level to give a few key pointers that you may find useful.
Reference repos
This series has described the assets and structure of a library, but it is always useful to look at examples as a reference point when creating your own custom libraries.
Platform libraries found in the platform subfolder of https://aka.ms/alz/library:
-
The main Azure Landing Zone repo has a huge selection of assets to use as a reference.
-
The Sovereign Landing Zone library is a good example of a “stacked” library, extending the dependency (alz) and creating new management groups in the architecture. This is the repo I use most often as a reference when creating custom libraries.
-
The Azure Monitor Baseline Alerts library is more standalone and assumes that the management group hierarchy is already in place. Note the
"exists": trueagainst the management groups in the architecture files.This library is useful as it serves a slightly different purpose with its Deploy If Not Exists policies when compared to the governance focused alz and slz libraries. The library could also be “sideloaded” as the second library in an array if you wanted both alz/slz and amba deployed together.
Additional example library repos found pinned in my https://github.com/richeney-org GitHub organisation:
-
Example single custom library for Azure Landing Zones’ alz provider for partners or organisations that repeatably deploy customised landing zones.
-
Example repo capable of hosting multiple libraries to extend a Sovereign Landing Zone to meet country and industry requirements. Each library will be in a subfolder.
Construct your repo to match the format of one of these.
Checking assets
The library specific constructs - archetypes, overrides, architectures, metadata, policy default values - are all pretty simple, so the key is to check that your assets - policies, policy sets, assignments, and role definitions - are all functioning correctly.
All of the assets are designed for creation and use at a management group level. You may wish to create one specifically for testing, e.g.:
az account management-group create --name "test" --display-name "Library test scope"
This will allow you to test creation without affecting any subscriptions or their resources.
These are the example commands that I use to check that my JSON files are syntactically sound and create the Azure resources correctly.
-
Define the scope
The example is for a management group called “test”. Change if required.
scope="/providers/Microsoft.Management/managementGroups/test" -
Set the file variable
It is assumed that you have already ensured that the name value within the file matches the prefix for the filename.
Example policy definition filename. Change as required.
file="policy_definitions/Enforce-KV-Premium.alz_policy_definition.json"Example policy set definition filename. Change as required.
file="policy_set_definitions/Deny-NL-Global.alz_policy_set_definition.json"Example policy assignment filename. Change as required.
file="policy_assignments/Deny-NL-Global.alz_policy_assignment.json"Example role definition filename. Change as required.
file="role_definitions/fabric_reader.alz_role_definition.json" -
Test using the REST API
The REST API is preferable to the matching CLI and PowerShell cmdlets as they cannot use the full JSON file definitions.
name="$(basename $file .alz_policy_definition.json)" uri="${scope}/providers/Microsoft.Authorization/policyDefinitions/${name}?api-version=2021-06-01" az rest --method put --url "$uri" --body @"$file"name="$(basename $file .alz_policy_set_definition.json)" uri="${scope}/providers/Microsoft.Authorization/policySetDefinitions/${name}?api-version=2021-06-01" az rest --method put --url "$uri" --body @"$file"name="$(basename $file .alz_policy_assignment.json)" uri="${scope}/providers/Microsoft.Authorization/policyAssignments/${name}?api-version=2023-04-01" az rest --method put --url "$uri" --body @"$file"name="$(basename $file .alz_role_definitioncopilot.json)" uri="${scope}/providers/Microsoft.Authorization/roleDefinitions/${name}?api-version=2022-04-01" az rest --method put --url "$uri" --body @"$file" -
Delete
Assuming that the definitions were successfully created, you may want to tidy up and remove them. Here are the commands to match the example names. Update as required.
az policy definition delete --management-group test --name "Enforce-KV-Premium"az policy set-definition delete --management-group test --name "Deny-NL-Global"az policy assignment delete --scope /providers/Microsoft.Management/managementGroups/test --name "Deny-NL-Global"az role definition delete --scope /providers/Microsoft.Management/managementGroups/test --name "fabric_reader"
Using the alzlibtool
The alzlibtool is a standalone CLI tool that is part of the github.com/Azure/alzlib source repo. The tool has many uses, but I primarily use it to
- check and validate a custom library
- generate the documentation in the style seen for the platform libraries’ README.md files
You will need to have Go installed.
Install
go install github.com/Azure/alzlib@latest
By default this will install azlibtool into your $HOME/go/bin directory.
Testing libraries
The alzlibtool can validate your custom library structure and content to ensure it conforms to the expected format.
alzlibtool check library .
This assumes you are running in the root of your library.
Creating documentation
The alzlibtool can automatically generate comprehensive documentation for your custom library in markdown format, including the mermaid diagrams for the architecture hierarchy if it contains a hierarchy file. The command only works if your library can pass the check.
Generate documentation and output to README.md.
alzlibtool document library . > README.md
This creates markdown files documenting all archetypes, policies, assignments and other library components. You can then customise.
Note that the provide block generated for the Usage section is in the format for a platform library, with path and ref arguments. Update to your custom_url format, e.g.:
provider "alz" {
library_references = [
{
custom_url = "github.com/richeney-org/Sovereign-Landing-Zone-Packs//country/nl/bio?ref=2026.01.0"
}
]
}
Semantic versioning, tags and releases
Follow the formatting of the platform libraries by adding your own tags and releases.
This GitHub CLI command to create releases is great. Once you have committed and pushed your repo, you can use this to interactively and it will configure a tag on the local and origin, and it will create a release in GitHub.
gh release create 2026.01.0
Modify the semantic version to match the right yyyy.mm.v for your release. This will also be interactively suggested for the Title, so hit enter to accept.
If you select Write using generated notes as template then it will generate default release notes based on your commits and their descriptions and open in your default editor. Save.
You can then publish, save as draft or cancel.