Feature Friday #18: Augments - def.json

Posted by Nick Anderson
July 12, 2024

Ever want to get some data into CFEngine? Have you heard about the def.json Augments file?1

Augments are JSON data files that allow you to define classes and variables very early during agent initialization, before policy. Augments are practical in a variety of ways. Perhaps most notably for overriding policy defaults.

Let’s look at a simple example.

Here we have a policy /tmp/feature-friday/18-0.cf

/tmp/feature-friday/18-0.cf
bundle agent main
{
  reports:
     "MyVariable $(with) defined '$(MyVariable)'"
        with => ifelse( isvariable( MyVariable ), "is", "is not" );
}

Running it, we can see that MyVariable isn’t defined

command
cf-agent -Kf /tmp/feature-friday/18-0.cf
output
R: MyVariable is not defined '$(MyVariable)'

Now, let’s create an Augments file, def.json, to define the variable and place it in /tmp/feature-friday (next to the policy entry).

{
    "variables": {
        "default:main.MyVariable": "defined in augments"
    }
}

By executing the policy again, we can see the effect:

command
cf-agent -Kf /tmp/feature-friday/18-0.cf
output
R: MyVariable is defined 'defined in augments'

Great, it’s defined, but how can this be utilized to override policy?

Well, it can only override the policy if the policy accepts it. Let’s see what happens if we define the variable in the policy. Here, we have modified the policy as /tmp/feature-friday/18-1.cf:

/tmp/feature-friday/18-1.cf
bundle agent main
{
  vars:
      "MyVariable" string => "defined in policy";

  reports:
     "MyVariable $(with) defined '$(MyVariable)'"
        with => ifelse( isvariable( MyVariable ), "is", "is not" );
}

Running it, we see MyVariable holds defined in policy:

command
cf-agent -Kf /tmp/feature-friday/18-1.cf
output
R: MyVariable is defined 'defined in policy'

Now we have a variable defined in policy, and policy always wins. So, we can readily define that variable in policy - conditionally - based on whether it’s already defined. Here we have the modified policy as /tmp/feature-friday/18-2.cf:

/tmp/feature-friday/18-2.cf
bundle agent main
{
  vars:
      "MyVariable"
        string => "defined in policy",
        if => not( isvariable( MyVariable ) );

  reports:
     "MyVariable $(with) defined '$(MyVariable)'"
        with => ifelse( isvariable( MyVariable ), "is", "is not" );
}

Now executing the policy, we see that the variable holds defined in augments as defined in def.json.

command
cf-agent -Kf /tmp/feature-friday/18-2.cf
output
R: MyVariable is defined 'defined in augments'

Happy Friday! 🎉