Using Augeas to manage resources in Puppet

January 31, 2020 

This translated from the original Finnish article that is available here.

The Augeas resource in Puppet allows one to manage parts of a complex configuration file instead of managing the whole file using a template or a static file. For trivial cases stdlib's file_line resource may be sufficient. While use of templates or static files is in general more reliable and easier than use of Augeas, the latter is quite useful in many cases. As using Puppet Augeas resource directly is quite challenging, a useful practice is to first make the changes manually with "augtool" and only then convert the results into Puppet Augeas resources. We use PostgreSQL's pg_hba.conf file here as an example.

The first step is to check what Augeas' view of a configuration file is:

$ augtool
augtool> ls /files/etc/postgresql/9.4/main/pg_hba.conf
--- snip ---
#comment[65] = Database administrative login by Unix domain socket
1/ = (none)
2/ = (none)
3/ = (none)
4/ = (none)

The lines (or objects) to edit have been numbered with 1-4 in the above example. To view their contents use the "print" command:

augtool> print /files/etc/postgresql/9.4/main/pg_hba.conf/1
/files/etc/postgresql/9.4/main/pg_hba.conf/1/type = "local"
/files/etc/postgresql/9.4/main/pg_hba.conf/1/database = "all"
/files/etc/postgresql/9.4/main/pg_hba.conf/1/user = "postgres"
/files/etc/postgresql/9.4/main/pg_hba.conf/1/method = "peer"

Augeas allows modifying these four objects. For example, to set method = "password" you would use the "set" command:

augtool> set /files/etc/postgresql/9.4/main/pg_hba.conf/1/method password
augtool> print /files/etc/postgresql/9.4/main/pg_hba.conf/1
/files/etc/postgresql/9.4/main/pg_hba.conf/1/type = "local"
/files/etc/postgresql/9.4/main/pg_hba.conf/1/database = "all"
/files/etc/postgresql/9.4/main/pg_hba.conf/1/user = "postgres"
/files/etc/postgresql/9.4/main/pg_hba.conf/1/method = "password"

If you want to add a new line to the file you need to use the "ins" command. The first step is to add a new line after the authentication settings, i.e. object 1 above:

augtool> ins 0444 after /files/etc/postgresql/9.4/main/pg_hba.conf/1

Finally you define the fields you want the line to contain:

augtool> set /files/etc/postgresql/9.4/main/pg_hba.conf/0444/type local
augtool> set /files/etc/postgresql/9.4/main/pg_hba.conf/0444/database mydatabase
augtool> set /files/etc/postgresql/9.4/main/pg_hba.conf/0444/user johndoe
augtool> set /files/etc/postgresql/9.4/main/pg_hba.conf/0444/method password

The line number is set high (0444) to avoid other lines (objects) getting the same identifier. A zero further reduces that risk, because anecdotal evindence tells us that Augeas never prepends its line numbers with a zero. In case of pg_hba.conf the risk of line numbering conflicts is rather minimal anyways because usually there only few lines in it.

Finally you need to save the changes you made:

augtool> save

Now that you know the incantations to use with augtool you can convert those into a Puppet Augeas resource:

augeas { 'postgresql-pg_hba.conf':
  context => "/files/etc/postgresql/9.4/main/pg_hba.conf",
  changes => [
    "ins 0444 after 1",
    "set 0444/type local",
    "set 0444/database mydatabase",
    "set 0444/user johndoe",
    "set 0444/method password"
  lens => 'Pg_hba.lns',
  incl => "/etc/postgresql/9.4/main/pg_hba.conf",
  # Prevent the same line from being created again
  onlyif => "match *[user = 'johndoe'] size == 0",

The "context" parameter gets added to the beginning of the Augeas path. That allows you to avoid repeating the full path in every change you make, like you have to do when using augtool directly.

Samuli Seppänen
Samuli Seppänen
Author archive