Posted On 16.02.2026

Puppet with Foreman – Populating the master with R10k

0 comments
confdroid.com >> blog >> Puppet with Foreman – Populating the master with R10k

Populating Your Puppet Master: Modules, Environments, and R10k Made Simple

In the last few posts in this Puppet with Foreman series, we’ve covered the full infrastructure setup, the initial installation, agent registration, and even a deep dive into the confdroid_puppet module. At this point, you have a working Puppet server with Foreman — agents are connecting, facts are flowing, and the basics are in place.

Now it’s time to make it useful. That means populating the Puppet master with the modules that actually do the work: your custom ones from the ConfDroid Forge, community modules from the Puppet Forge, or even your own internal code.

Today, we’ll walk through the best way to handle this — using R10k, the gold standard for Puppet module management. We’ll also show how the confdroid_puppet module makes the whole process effortless.

Where Puppet Stores Modules

Puppet expects modules to live in a specific directory structure:

/etc/puppetlabs/code/environments/
├── production/
│   ├── manifests/
│   ├── modules/
│   └── hieradata/
├── development/
│   └── ...
└── ...

Each subfolder is an environment (production, staging, testing, etc.). Inside each one, you’ll find:

  • manifests/ — site.pp and other top-level manifests
  • modules/ — your Puppet modules
  • hieradata/ — Hiera data (if you’re using it)

You could manually copy modules into these folders, but that’s error-prone, hard to version-control, and doesn’t scale. Git clones with cron jobs work okay for small setups, but they still require manual intervention.

Enter R10k — the elegant, automated solution.

What Is R10k?

R10k is a tool from Puppet Labs (now Puppet) that turns your Puppet environments into GitOps. It uses a single control repository (a Git repo) to define everything for your Puppet setup.

Here’s how it works:

  1. You maintain one Git repo (the control repo) with branches for each environment.
  2. Each branch contains a Puppetfile — a simple manifest that declares exactly which modules should be in that environment.
  3. R10k reads the Puppetfile, pulls the modules (from Git or the Forge), and deploys them into the correct environment folder.
  4. It also removes anything not listed in the Puppetfile — keeping things clean and consistent.

This approach is perfect for teams, CI/CD pipelines, and anyone who wants reproducible, version-controlled Puppet code.

The Puppetfile: Your Module Shopping List

The heart of R10k is the Puppetfile. Here’s a real-world example from the ConfDroid Forge:

# Custom modules from the ConfDroid Forge
mod 'confdroid_puppet',
  :git => 'https://sourcecode.confdroid.com/confdroid/confdroid_puppet.git',
  :ref => 'master'

mod 'confdroid_resources',
  :git => 'https://sourcecode.confdroid.com/confdroid/confdroid_resources.git',
  :ref => 'master'

# Official Forge modules with exact versions
mod 'puppetlabs-firewall', '8.1.2'
mod 'puppetlabs-apt', '9.0.0'
  • Git modules: Use :git and :ref (branch, tag, or commit) to pull from any repo.
  • Forge modules: Just the name and version — R10k downloads them automatically.
  • You can add anything else to the control repo: custom facts, functions, Hiera data, even scripts.

R10k creates an environment for every branch in the control repo (production, development, etc.). Super clean.

The r10k.yaml Configuration

On the Puppet master, R10k reads its settings from /etc/puppetlabs/r10k/r10k.yaml:

:cachedir: /var/cache/r10k
:sources:
  :puppet:
    remote: git@your-git-server:path/to/control-repo.git
    prefix: false
    basedir: '/etc/puppetlabs/code/environments'

This tells R10k where to find the control repo and where to deploy the environments. (Make sure your puppet master host has git installed and can read from the repo, i.e. using deployment keys)

Making It Easy with confdroid_puppet

Configuring all this manually can feel overwhelming at first. That’s why confdroid_puppet does the heavy lifting for you.

Just set two parameters in Foreman:

  • pt_use_r10k: true (defaults to false)
  • pt_r10k_remote: git@your-git-server:path/to/control-repo.git

Optionally (see below):

  • pt_use_r10k_webhook: true (defaults to false)
  • pt_r10k_webhook_port: ` ` (defaults to 8085)

That’s it. The module:

  • Installs R10k
  • Creates the r10k.yaml file
  • (If enabled) Installs a webhook listener on port 8085 (or your choice) and opens the firewall for it ( requires puppetlabs-firewall).

Deploying Modules

Once configured, run the deployment command on the master:

r10k deploy environment -pv
  • -p = purge (remove modules not in the Puppetfile)
  • -v = verbose (see what’s happening)

R10k will clone the control repo, fetch all modules, and populate every environment.

The Cherry on Top: GitOps with the Webhook

For true automation, enable the webhook in confdroid_puppet:

  • Every time you push to your control repo (or a module repo), the webhook triggers r10k deploy automatically. For this to work, you need to create a webhook in the repo(s) and set it to your puppet master: http://puppet.example.net:8085.
  • In my own setup, I wire this to GitLab CI/CD: successful builds or merged MRs hit the webhook.
  • Result: Changes land on the Puppet master in seconds — no manual steps. Codebase is always in sync.

This is the GitOps dream for Puppet.

Wrapping Up

With R10k and confdroid_puppet, managing modules becomes predictable, versioned, and effortless. You can mix ConfDroid Forge modules, Puppet Forge gems, and your own code — all in one clean workflow.

Ready to try it? Clone the control repo template from the ConfDroid Forge and get deploying!

Next in the series: We’ll take a specific module (like confdroid_postgresql) and show how to use it in practice.

In the meantime, check out:

Questions or feedback? Hit the portal at https://feedback.confdroid.com. Happy Puppet-ing! 🚀


Did you find this post helpful? You can support me.

Hetzner Referral
Substack
ConfDroid Feedback Portal

Related posts

Author Profile

12ww1160DevOps engineer & architect

Leave a Reply

Your email address will not be published. Required fields are marked *

11 − eleven =

Related Post

Puppet with Foreman – Pilot

## Understanding Puppet Core with Foreman as ENC ### Introduction to Puppet DSL Puppet DSL…

Kubernetes – create a configuration backup with kubectl

This article intends to explain how to create a configuration backup of an helm installed…

Centralized OIDC for Wiki.js using Keycloak

Single Sign-On for Wiki.js with Keycloak Managing multiple credentials across internal tools is tedious. We’ve…
Social Media Auto Publish Powered By : XYZScripts.com