First off, can (and is it good practice) chef run a recipe at a specified interval on a specific role?
I’ve got a ruby script which manages user accounts and ssh identities, it currently runs on a cron every hour and I’d like to turn it into a Chef recipe for obvious reasons (I want it to be there on all machines).
I can see two ways of doing this:
Either turn the script into a template, the recipe would simply render the template to a given path and then register a cronjob
OR
Break the script into resources, providers, etc., and have Chef run it every hour.
Ideas?
You can run chef-client as a daemon (-d option, as used in init scripts), or under a service management tool like upstart, runit/daemontools or bluepill. You can certainly also launch it from cron – just make sure to not run daemon mode there :).
Chef’s resource providers take idempotent actions to configure the resources to be in the desired state. This means that if Chef has already run on the system, it only modifies resources if they do not match what the recipe says. For example, if you have a recipe that says:
The package will be installed the first time chef runs and won’t be modified again unless the package were removed from the system, or you modify the resource. Likewise, the haproxy service will be enabled (through your platform’s service management tools, usually symlinks in /etc/rc*.d) and then started (e.g., via /etc/init.d/haproxy start). Finally only if the content of the template changes will Chef render a new version of the template. For templates it determines this based on a SHA256 checksum.
There are a few exceptions – execute, script and ruby_block resources are not idempotent without you providing some kind of qualifier conditional.
Also, Chef doesn’t have “one time” or “one off” recipes run lists when using the server. There was a thread on the Chef mailing list recently about the topic.