Scheduling when resources are applied

So far, we looked at what Puppet can do, and the order that it does things in, but not when it does them. One way to control this is to use the schedule metaparameter. When you need to limit the number of times a resource is applied within a specified period, schedule can help. For example:

exec { "/usr/bin/apt-get update":
    schedule => daily,
}

The most important thing to understand about schedule is that it can only stop a resource being applied. It doesn't guarantee that the resource will be applied with a certain frequency. For example, the exec resource shown in the preceding code snippet has schedule => daily, but this just represents an upper limit on the number of times the exec resource can run per day. It won't be applied more than once a day. If you don't run Puppet at all, the resource won't be applied at all. Using the hourly schedule, for instance, is meaningless on a machine configured to run the agent every 4 hours (via the runinterval configuration setting).

That being said, schedule is best used to restrict resources from running when they shouldn't, or don't need to; for example, you might want to make sure that apt-get update isn't run more than once an hour. There are some built-in schedules available for you to use:

  • hourly
  • daily
  • weekly
  • monthly
  • never

However, you can modify these and create your own custom schedules, using the schedule resource. We'll see how to do this in the following example. Let's say we want to make sure that an exec resource representing a maintenance job won't run during office hours, when it might interfere with production.

How to do it...

In this example, we'll create a custom schedule resource and assign this to the resource:

  1. Modify your site.pp file as follows:
    schedule { 'outside-office-hours':
      period => daily,
      range  => ['17:00-23:59','00:00-09:00'],
      repeat => 1,
    }
    node 'cookbook' {
      notify { 'Doing some maintenance':
        schedule => 'outside-office-hours',
      }
    }
  2. Run Puppet. What you'll see will depend on the time of the day. If it's currently outside the office hours period you defined, Puppet will apply the resource as follows:
    [root@cookbook ~]# date
    Fri Jan 2 23:59:01 PST 2015
    [root@cookbook ~]# puppet agent -t
    Info: Caching catalog for cookbook.example.com
    Info: Applying configuration version '1413734477'
    Notice: Doing some maintenance
    Notice: /Stage[main]/Main/Node[cookbook]/Notify[Doing some maintenance]/message: defined 'message' as 'Doing some maintenance'
    Notice: Finished catalog run in 0.07 seconds
    
  3. If the time is within the office hours period, Puppet will do nothing:
    [root@cookbook ~]# date
    Fri Jan 2 09:59:01 PST 2015
    [root@cookbook ~]# puppet agent -t
    Info: Caching catalog for cookbook.example.com
    Info: Applying configuration version '1413734289'
    Notice: Finished catalog run in 0.09 seconds
    

How it works...

A schedule consists of three bits of information:

  • The period (hourly, daily, weekly, or monthly)
  • The range (defaults to the whole period, but can be a smaller part of it)
  • The repeat count (how often the resource is allowed to be applied within the range; the default is 1 or once per period)

Our custom schedule named outside-office-hours supplies these three parameters:

schedule { 'outside-office-hours':
  period => daily,
  range  => ['17:00-23:59','00:00-09:00'],
  repeat => 1,
}

The period is daily, and range is defined as an array of two time intervals:

17:00-23:59
00:00-09:00

The schedule named outside-office-hours is now available for us to use with any resource, just as though it were built into Puppet such as the daily or hourly schedules. In our example, we assign this schedule to the exec resource using the schedule metaparameter:

notify { 'Doing some maintenance':
  schedule => 'outside-office-hours',
}

Without this schedule parameter, the resource would be applied every time Puppet runs. With it, Puppet will check the following parameters to decide whether or not to apply the resource:

  • Whether the time is in the permitted range
  • Whether the resource has already been run the maximum permitted number of times in this period

For example, let's consider what happens if Puppet runs at 4 p.m., 5 p.m., and 6 p.m. on a given day:

  • 4 p.m.: It's outside the permitted time range, so Puppet will do nothing
  • 5 p.m.: It's inside the permitted time range, and the resource hasn't been run yet in this period, so Puppet will apply the resource
  • 6 p.m.: It's inside the permitted time range, but the resource has already been run the maximum number of times in this period, so Puppet will do nothing

And so on until the next day.

There's more...

The repeat parameter governs how many times the resource will be applied given the other constraints of the schedule. For example, to apply a resource no more than six times an hour, use a schedule as follows:

period => hourly,
repeat => 6,

Remember that this won't guarantee that the job is run six times an hour. It just sets an upper limit; no matter how often Puppet runs or anything else happens, the job won't be run if it has already run six times this hour. If Puppet only runs once a day, the job will just be run once. So schedule is best used to make sure things don't happen at certain times (or don't exceed a given frequency).