Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I would like to have a method that only evaluates a particular class once a day at a specific time. Right now I am running my puppet agent from the cron, but I would like to change it to either run as a daemon, or run more frequently. The barrier with increasing the frequency is that there is one class that takes about 4 minutes to process, and doesn't need to happen very often. I am trying to find some method to only evaluate that particular class once a day from cron.

Is there a simple method for me to set an environment variable (FOO=bar;puppet agent ..), or add a command line option (puppet agent .. --foo bar) to the crontab that will become a fact I can use in my manifests to include or not include the class?

class foobar {
  if 'bar' == $::foo {
    # do the slow stuff
share|improve this question
up vote 7 down vote accepted

A schedule sounds like it'll provide what you're looking for. First you create a schedule resource that specifies when things can run and how many times in a given period.

schedule { "slow":
  range  => "1 - 5",
  period => daily,
  repeat => 1,

The example above will only be evaluated or run during the hours of 1am and 5am and a maximum of once. You can remove the range parameter and it'll run any time of the day, but again, only once.

On resources, you then specify the schedule meta-parameter to link them to the above schedule:

exec { "example":
  command  => "/usr/bin/foo",
  unless   => "/usr/bin/bar",
  schedule => "slow",

When you run Puppet with --debug, you'll now see the following if it's already been evaluated the given number of times, or the range isn't applicable:

debug: /Stage[main]//Exec[example]: Not scheduled

If you've got a few resources, you could use resource defaults inside the class you're restricting to affect all resources of the same type:

Exec {
  schedule => "slow",

You'd need to do this for each resource type - Exec, File, Augeas etc.

Couple of notes on improving this:

  • I don't know a way to apply it to all types of resources in the class
  • Applying the schedule meta-parameter to a class doesn't appear to work, might be worth raising a bug
share|improve this answer
This looks like exactly what I need. I never noticed ths in the docs before. Any idea what version of puppet ths feature requires? – Zoredache Dec 17 '11 at 10:27
It's been in Puppet for a long time, at least as far back as 0.24.x! Puppet Labs publish the type documentation for every version so you can check compatibility, change the version number in this URL. – m0dlx Dec 17 '11 at 10:30
So, is this approach recommended over configuring a crontab job from puppet ? – Paul Praet May 27 '15 at 14:34
I don't think I'd replace cronjobs with schedules. Keep schedules for circumstances like this, when you want to change configuration resources only at certain times of the day, or a limited number of times. Cronjobs are good at what they do, running commands on a regular interval. – m0dlx May 28 '15 at 7:21

I believe you can accomplish this via an Environment declaration. You invoke it on the command-line:

puppet agent --environment latetbus

You can use it to specify a different manifest in the puppet.conf file:

  manifest = $confdir/latetbus/site.pp

And even can do different modules that way.

There is also a method for adding custom facts to facter. This leverages plugins to make work. You create a custom ruby file to check for something:

# run_latebus.rb

facter.add("latebus_exec") do
    setcode do
        %x{if [ -e /tmp/run_latebus ] ; then echo "true" ; else echo "false" ; fi}.chomp

Where the puppet agent invocation script would touch /etc/run_latebus before starting puppet agent, which is evaluated by Facter during the puppet run.

The .rb file is placed in a custom module, specifically in the lib/facter directory of the module itself.

share|improve this answer
As much as this feels like using a sledge on a finishing nail, it is the most elegant method I can think of. Doing a run against that environment via cron once a day will probably do exactly what he wants. – Scott Pack Dec 17 '11 at 1:17
I am actually already using environments for testing/production. I was kind hoping there was some other method. If no other alternatives are presented, this is what I was probably going to do. – Zoredache Dec 17 '11 at 1:25

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.