How to Configure Windows Server 2019 with Puppet
Puppet is a widely-used configuration management tool that uses a declarative language to define the desired state of infrastructure. Windows Server 2019 is a first-class supported platform in Puppet, with a comprehensive set of built-in and community resource types covering Windows features, services, registry, files, users, packages, and scheduled tasks. Puppet agents run on managed Windows nodes, communicate with the Puppet Server, and apply manifests that define the desired server configuration.
Puppet Architecture Overview
A Puppet deployment consists of the Puppet Server (or Puppet Enterprise master), which stores manifests and compiled catalogs, and Puppet Agents that run on managed nodes. Agents contact the server every 30 minutes by default, request a compiled catalog for their node, and apply it. The catalog is produced by compiling Puppet manifests (code in Puppet’s DSL) with node-specific data from Hiera (Puppet’s data separation layer). Communication occurs over HTTPS on port 8140 using mutual TLS certificate authentication.
Installing the Puppet Agent on Windows Server 2019
Download and install the Puppet Agent from the Puppet website or from your Puppet Server’s package repository. The agent can be installed silently with parameters pointing it at the Puppet Server.
# Download Puppet Agent MSI (replace version as appropriate)
$PuppetVersion = "7.28.0"
$PuppetMSI = "puppet-agent-$PuppetVersion-x64.msi"
Invoke-WebRequest -Uri "https://downloads.puppet.com/windows/puppet7/$PuppetMSI" `
-OutFile "C:Temp$PuppetMSI"
# Install silently pointing to the Puppet Server
Start-Process msiexec.exe -ArgumentList `
"/qn /i C:Temp$PuppetMSI PUPPET_MASTER_SERVER=puppet.corp.local" `
-Wait
# Verify Puppet Agent is installed
puppet --version
puppet agent --configprint server
Configuring puppet.conf
The main Puppet configuration file on Windows is located at C:ProgramDataPuppetLabspuppetetcpuppet.conf. Configure the server address, certname, and agent behaviour here.
# C:ProgramDataPuppetLabspuppetetcpuppet.conf
[main]
certname = websvr01.corp.local
server = puppet.corp.local
environment = production
[agent]
runinterval = 1800
splaylimit = 300
report = true
usecacheonfailure = true
daemonize = false
# Apply the configuration using PowerShell to write the file
$PuppetConf = @"
[main]
certname = websvr01.corp.local
server = puppet.corp.local
environment = production
[agent]
runinterval = 1800
splaylimit = 300
report = true
"@
$PuppetConf | Out-File "C:ProgramDataPuppetLabspuppetetcpuppet.conf" -Encoding UTF8
First Agent Run and Certificate Signing
On the first run, the Puppet Agent generates a certificate and sends a signing request to the Puppet Server. The request must be signed on the Puppet Server before the agent can receive catalogs.
# On the Windows node - run the agent to generate certificate request
puppet agent --test --noop
# On the Puppet Server (Linux) - list pending certificate requests
puppetserver ca list
# Sign the certificate for the Windows node
puppetserver ca sign --certname websvr01.corp.local
# Back on the Windows node - run the agent to apply the first catalog
puppet agent --test
Writing Puppet Manifests for Windows Server 2019
Puppet manifests use .pp files with a declarative DSL. Write manifests on the Puppet Server to configure Windows Server 2019 nodes. Resources are the fundamental unit of Puppet manifests.
# Example manifest: configure IIS web server on Windows Server 2019
# /etc/puppetlabs/code/environments/production/manifests/webserver.pp
class profile::windows_webserver {
# Install IIS Web Server feature
windowsfeature { 'Web-Server':
ensure => present,
}
# Install ASP.NET 4.5 feature
windowsfeature { 'Web-Asp-Net45':
ensure => present,
require => Windowsfeature['Web-Server'],
}
# Ensure W3SVC service is running
service { 'W3SVC':
ensure => running,
enable => true,
require => Windowsfeature['Web-Server'],
}
# Create web application directory
file { 'C:\inetpub\myapp':
ensure => directory,
}
# Deploy configuration file
file { 'C:\inetpub\myapp\web.config':
ensure => file,
source => 'puppet:///modules/profile/webserver/web.config',
require => File['C:\inetpub\myapp'],
}
}
Managing Registry Keys with Puppet
The registry resource type is built into the Puppet agent for Windows and allows management of registry keys and values.
# Puppet manifest for registry configuration
class profile::windows_registry {
registry_key { 'HKLMSOFTWAREMyCompanyMyApp':
ensure => present,
}
registry_value { 'HKLMSOFTWAREMyCompanyMyAppInstallPath':
ensure => present,
type => string,
data => 'C:Program FilesMyApp',
}
registry_value { 'HKLMSOFTWAREMyCompanyMyAppLogLevel':
ensure => present,
type => dword,
data => 2,
}
# Disable automatic admin shares (security hardening)
registry_value { 'HKLMSYSTEMCurrentControlSetServicesLanmanServerParametersAutoShareWks':
ensure => present,
type => dword,
data => 0,
}
}
Using Hiera for Node-Specific Data
Hiera separates data from Puppet code, allowing the same manifests to be used across different environments with different variable values.
# hiera.yaml - hierarchy definition
---
version: 5
hierarchy:
- name: "Node-specific data"
path: "nodes/%{trusted.certname}.yaml"
- name: "OS-specific data"
path: "os/%{facts.os.name}.yaml"
- name: "Common data"
path: "common.yaml"
defaults:
data_hash: yaml_data
datadir: data
# data/nodes/websvr01.corp.local.yaml
---
profile::windows_webserver::app_path: 'C:inetpubwebapp1'
profile::windows_webserver::site_name: 'WebApp Production'
profile::windows_webserver::port: 80
Scheduling Automatic Puppet Runs
Install the Puppet Agent as a Windows service for automatic periodic runs.
# Install and start Puppet service
puppet resource service puppet ensure=running enable=true
# Verify the service is running
Get-Service puppet | Select-Object Status, StartType
# Run Puppet manually to test
puppet agent --test --noop # Dry run (show changes without applying)
puppet agent --test # Apply changes
# Check the last run summary
Get-Content "C:ProgramDataPuppetLabspuppetcachestatelast_run_summary.yaml"
Viewing Puppet Reports
# View Puppet agent log on the Windows node
Get-Content "C:ProgramDataPuppetLabspuppetvarlogpuppet.log" -Tail 100
# Query node status from the Puppet Server (run on Puppet Server)
puppet node status websvr01.corp.local
# Use PuppetDB query for report data (if PuppetDB is installed)
curl -s "https://puppet.corp.local:8081/pdb/query/v4/nodes" | python -m json.tool
Common Windows Puppet Modules
The Puppet Forge hosts many community modules specifically for Windows Server. Install them using the puppet module command on the Puppet Server.
# Install commonly used Windows modules from Puppet Forge
puppet module install puppetlabs-windows_env
puppet module install puppetlabs-iis
puppet module install puppetlabs-scheduled_task
puppet module install puppetlabs-dsc
# List installed modules
puppet module list
Conclusion
Puppet provides a robust, scalable configuration management solution for Windows Server 2019. Writing class-based manifests with Hiera data separation, using Windows-specific resource types for features, services, registry, and IIS, and operating the Puppet Agent as a Windows service enables continuous automated configuration management. Puppet’s strong reporting through PuppetDB and the Puppet Enterprise console gives visibility into the compliance state of every managed node, making it suitable for large-scale Windows infrastructure management.