The example control repo doesn’t, at present, have a mechanism to classify nodes. To bolt puppet apply functionality onto an existing master-based control repo, it needs to sit along side a classification mechanism.
This post will extend control repo with the ability to assign a role to a machine, and change hiera and the code to so it behaves differently when running via puppet apply. It’s a proof of concept: most live control repos out there will have existing classification code, so getting puppet apply would be bespoke to each implementation.
I’ve not found a nicer way to code detection of puppet apply than what I do here (or similar.) There is no fact set by the runtime, for example, to indicate puppet apply vs. puppet agent.
A new fact
There are lots of ways to create facts, I’ll pick one of the really easy ones – all you need to do is create a yaml file. It’s one of the external structured data facts documented by Puppet.
$ git status # On branch puppetapply05 nothing to commit, working directory clean
There’s two additional classes already in your current revision of control repo (from posts #7/#8)
- profile::puppet::factsd will create /etc/puppetlabs/facter/facts.d/
- profile::motd::role will add the role to the message of the day, if defined.
Add them to puppetapply.yaml, it will then look as follows:
--- classes: - '::profile::puppet::clientscope' - '::profile::puppet::factsd' - '::profile::motd::role' profile::motd::params::motd_behav: 'deploy'
Run puppet apply, and it’ll create /etc/puppetlabs/facter/facts.d
sudo scripts/puppetapply.sh #--noop
Then populate a yaml file. The output of the command below is as follows – run the command, or edit that into /etc/puppetlabs/facter/facts.d/local.yaml some other way.
--- role: 'role::test1'
Run ..
echo -e "---\nrole: 'role::test1'" | \ sudo tee -a /etc/puppetlabs/facter/facts.d/local.yaml
Re-run puppet apply, and it’ll log adding the role to /etc/motd.
sudo scripts/puppetapply.sh #--noop
This confirms that the new role fact has been detected as the code (site/profile/manifests/motd/role.pp) will not trigger if it isn’t defined.
Classification code
Once the fact is populated, the classification is done – it’s just a question of whether it does anything.
Check out the last milestone in control repo
git checkout puppetapply06
Changed: data/common.yaml, manifests/site.pp
- site.pp now also requires stdlib (which puppetmodule.sh installs by default) ensuring that this control repo is either running with stdlib available, or it’ll fail immediately.
- site.pp guesses puppet apply is being run based on how it finds a couple of facts, and if so, it includes all the classes in a new hiera array called ‘apply_classes’
- Else: If the role isn’t set, or if it doesn’t start with ‘role::’, a message is generated, and no classes are applied.
- If Validation passes, all classes in the ‘classes’ array in hiera are included.
If you’re developing stuff, you just want the profiles useful when developing (in common.yaml) plus the ones you’re actually developing (in puppetapply.yaml.) So: apply_classes OR classes, but not both.
Having the apply_classes array in common.yaml also makes it easy to seed puppetapply.yaml – you can copy it over and then amend.
The role fact is only validated if the code thinks puppet apply isn’t in use. However, if it’s set, it is still available for use under puppet apply, and this includes anything supplied by the role within hiera (ie, in data/role/)
If you include classes in apply_classes that are modified by data supplied for that machine’s role, puppet apply will use that data, and not the defaults in either the class definition or common.yaml.
Forking this control repo
The instructions supplied by Puppet, which are in README.md in control-repo, should work. This details how to remove the origin (pointing at gitlab) add your own, and push the production branch.