Enable automatic running of policies with autorun module

Posted by Craig Comstock
February 3, 2025

When writing CFEngine policy we create files ending in the .cf extension but this alone won’t cause the policy to be parsed and evaluated. By default cf-agent runs ${sys.inputdir}/promises.cf.

For a non-privileged user running cf-agent this will be in their $HOME directory:

$ cf-promises --show-vars=sys.inputdir
Variable name                            Variable value                                               Meta tags                                Comment                                 
default:sys.inputdir                     /home/craig/.cfagent/inputs                                  source=agent                            

Usually though, CFEngine is run as a privileged user so the more common value is:

root@rpi4:/home/craig# cf-promises --show-vars=sys.inputdir
Variable name                            Variable value                                               Meta tags                                Comment                                 
default:sys.inputdir                     /var/cfengine/inputs                                         source=agent                             

MPF (Masterfiles Policy Framework)

Typically users will use the Masterfiles Policy Framework which is our body of standard policy that provides a nice standard library of helpers as well as many tunables to our standard policy set.

Using the MPF you must include additional policy files in inputs. This is possible in many ways such as in policy with the body file control attribute or with augments as well as with the MPF autorun feature.

In addition to enabling this feature with augments you can enable it with the autorun module.

The build module way

To get started from scratch you would download cfbs and create a new project:

pipx install cfbs
mkdir my-cfbs-project
cd my-cfbs-project
cfbs init

Then add the autorun module to your build project:

cfbs add autorun

Then add policy files with cfbs add ./file.cf and in this case cfbs will add the file to list of inputs so we can skip the placing of files in services/autorun. The files will be generated by default to services/cfbs/(filename) when cfbs build is run.

my-cfbs-project/my-autorun.cf
bundle agent my_autorun_bundle
{
  meta:
    "tags" slist => { "autorun" };
  reports:
    "hello from my autorun bundle!";
}

And add it to your project. When cfbs asks which bundle should be evaluated answer None because the autorun module will take care of running it as it has that meta tag autorun and cfbs is handling the parsing of the file by adding it to inputs in def.json.

command
cfbs add ./my-autorun.cf
output
Which bundle should be evaluated (added to bundle sequence)?
 1. ./my-autorun.cf:my_autorun_bundle (default)
 2. (None)
 [1/2]: 2
Added module: ./my-autorun.cf
The default commit message is 'Added module './my-autorun.cf'' - edit it? [yes/y/NO/n] 
Committing using git:

[main 9dadfc3] Added module './my-autorun.cf'
 2 files changed, 17 insertions(+)
 create mode 100644 my-autorun.cf

Let’s see the build result.

$ cfbs build
$ cat out/masterfiles/def.json 
{
  "classes": { "services_autorun": ["any"] },
  "inputs": ["services/cfbs/my-autorun.cf"]
}

Notice that our file is added to inputs and the services_autorun class will be defined for all hosts because the special class any is a hard class which is always set.

And the output when we run policy?

R: hello from my autorun bundle!

Autorun feature options

There are two classes which give you more control over this feature: services_autorun_inputs which allows you to control when files in services/autorun are parsed and services_autorun_bundles which allows you to specify when autorun tagged bundles are evaluated.

There is also variable that can be defined in augments to extend which directories are searched for .cf files: def.mpf_extra_autorun_inputs.

For a more advanced look at the autorun feature, how to extend it and how to implement your own see the Extending autorun blog post

Contact

For help with upgrading or additional questions, please contact support at:

https://support.northern.tech