A practical toolkit for authoring custom Azure Machine Configuration (formerly Guest Configuration) policies for Linux VMs. Includes example DSC configurations, a CI/CD pipeline with full lifecycle testing, and scripts to package, test, and publish custom policies. Uses a pre-built Docker container for the authoring environment — see azure-machine-config-container.
Looking for Windows? See azure-machine-config-windows — native PowerShell setup, no Docker needed.
Container image: See azure-machine-config-container for the Dockerfile and container docs.
Azure Machine Configuration uses PowerShell Desired State Configuration (DSC) to audit and enforce settings on Azure VMs and Arc-enabled servers. This repo walks through setting up the authoring environment on Linux (Ubuntu 20+) and creating a custom policy that:
- Ensures a specific file exists with required content
- Packages the configuration as a
.zipartifact - Tests compliance locally before deploying
- Publishes to Azure Storage and creates a policy definition
- Ubuntu 20.04 or later (authoring machine)
- Azure subscription with Contributor access
- PowerShell 7.2.4 or later
# 1. Install PowerShell 7 (if not already installed)
sudo apt-get update
sudo apt-get install -y powershell
# 2. Run the setup script to install required modules
pwsh -File scripts/setup-authoring-env.ps1
# 3. Author your configuration (see examples/)
# 4. Package, test, and publish (see scripts/).
├── README.md
├── examples/
│ ├── LinuxFileConfig.ps1 # Example: ensure file exists with content
│ └── LinuxSecurityBaseline.ps1 # Example: basic security hardening checks
├── scripts/
│ ├── setup-authoring-env.ps1 # Install all required PowerShell modules
│ ├── build-package.ps1 # Compile MOF and create .zip package
│ ├── test-package.ps1 # Test compliance locally
│ └── publish-and-assign.ps1 # Publish to Azure Storage + create policy
├── .gitignore
└── docs/
└── authoring-guide.md # Detailed walkthrough
Azure Guest Configuration was renamed to Azure Machine Configuration as part of the Azure Automanage rebranding. The PowerShell module is still called GuestConfiguration for backwards compatibility, but the service name in the portal and documentation is "Machine Configuration".
- Author a DSC configuration using PowerShell classes or DSC resources
- Compile the configuration into a MOF file
- Package the MOF and dependencies into a
.zipusingNew-GuestConfigurationPackage - Test locally with
Get-GuestConfigurationPackageComplianceStatus - Publish the package to Azure Blob Storage
- Create an Azure Policy definition referencing the package
- Assign the policy to a scope (subscription, resource group, management group)
| Mode | Behaviour |
|---|---|
Audit |
Reports compliance without making changes |
ApplyAndMonitor |
Applies configuration once, then monitors for drift |
ApplyAndAutoCorrect |
Applies configuration and automatically remediates drift |
| Module | Version | Notes |
|---|---|---|
| PowerShell | 7.2.4+ | Required for Linux authoring |
| GuestConfiguration | 4.7.0 | Latest stable |
| PSDesiredStateConfiguration | 3.0.0-beta1 | Required for Linux (prerelease) |
| nxtools | latest | Linux DSC resources (file, service, user, etc.) |
| Az.Accounts | latest | Azure authentication |
| Az.Storage | latest | Blob upload for packages |
| Az.Resources | latest | Policy definition management |
- Machine Configuration overview
- Develop custom packages
- Set up authoring environment
- Create policy definitions
- GuestConfiguration PowerShell module
MIT
A pre-built Docker image is available on Docker Hub — PowerShell 7, OMI, and all required modules pre-installed:
docker pull petariv/azure-machine-config-linux
docker run -it --rm petariv/azure-machine-config-linuxThe Dockerfile and full container documentation (including a guide for setting up the authoring environment without Docker) live in the dedicated container repo:
azure-machine-config-container
Every push to main automatically runs a matrix build on Linux:
Compile → Package → Audit (non-compliant) → Remediate → Audit (compliant) ✓
Tests the full lifecycle inside the Docker container — no host dependencies needed.
A separate manual workflow (Deploy to Azure) can publish packages to Azure Storage and assign them as policies. To use it:
-
Create a service principal:
az ad sp create-for-rbac --name "mc-github-deploy" \ --role "Resource Policy Contributor" \ --scopes /subscriptions/<subscription-id> \ --sdk-auth
-
Add the JSON output as a GitHub secret named
AZURE_CREDENTIALS -
Create a storage account for package hosting (update
STORAGE_ACCOUNTin the workflow) -
Trigger the workflow from the Actions tab — pick your config, mode, and target resource group
The pipeline will compile, package, upload to blob storage, create the policy definition, and assign it.