augeas

Augeas is a redhat project, it is a configuration API. It is a method for manipulating configuration files safely. It may be found at augeas.net.

Augeas manipulates files through a system of lenses. Lenses abstract configuration files into configuration parameters that can be manipulated using get and set commands in augeas. The first example I like to work with is /etc/hosts. First we'll install augeas on client15 then we'll make a new entry in /etc/hosts on client15.

[root@client15 ~]# yum install augeas
Loading "installonlyn" plugin
Loading "rhnplugin" plugin
Setting up Install Process
Setting up repositories
Local                     100% |=========================| 1.1 kB    00:00     
Reading repository metadata in from local files
...
Installed: augeas.x86_64 0:0.5.1-1.el5
Complete!
[root@client15 ~]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1		localhost.localdomain localhost
::1		localhost6.localdomain6 localhost6
192.168.0.31		client15.example.com client15
[root@client15 ~]# augtool -b
augtool> ls /files/etc/hosts
#comment[1] = Do not remove the following line, or various programs
#comment[2] = that require network functionality will fail.
1/ = (none)
2/ = (none)
3/ = (none)
augtool> ls /files/etc/hosts/1/
ipaddr = 127.0.0.1
canonical = localhost.localdomain
alias = localhost
augtool> ls /files/etc/hosts/2/
ipaddr = ::1
canonical = localhost6.localdomain6
alias = localhost6
augtool> ls /files/etc/hosts/3/
ipaddr = 192.168.0.31
canonical = client15.example.com
alias = client15

augtool> set /files/etc/hosts/4/ipaddr 192.168.0.1
augtool> set /files/etc/hosts/4/canonical server0.example.com
augtool> set /files/etc/hosts/4/alias[1] server0
augtool> set /files/etc/hosts/4/alias[2] puppet.example.com
augtool> save
Saved 1 file(s)
augtool> quit
[root@client15 ~]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1		localhost.localdomain localhost
::1		localhost6.localdomain6 localhost6
192.168.0.31		client15.example.com client15
192.168.0.1	server0.example.com server0 puppet.example.com
[root@client15 ~]# 

There are several lenses provided with augeas for manipulating different types of configuration files. The best way to work with augeas is to provide yourself a testing area and use the environment variable AUGEAS_ROOT to specify your "sandbox" to play in. It is important that the directory structure remain the same in your sandbox as it would be in /etc, file locations are used by augeas to apply the correct lens.

[root@client15 ~]# mkdir augeas-play
[root@client15 ~]# export AUGEAS_ROOT=/root/augeas-play
[root@client15 ~]# cp /etc/ssh/sshd_config augeas-play/
[root@client15 ~]# augtool -b
augtool> ls /files/sshd_config
augtool> quit
[root@client15 ~]# cd augeas-play/
[root@client15 augeas-play]# mkdir -p etc/ssh
[root@client15 augeas-play]# mv sshd_config etc/ssh/
[root@client15 augeas-play]# augtool -b
augtool> ls /files/etc/ssh/sshd_config
#comment[1] = $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
#comment[2] = This is the sshd server system-wide configuration file.  See
#comment[3] = sshd_config(5) for more information.
#comment[4] = This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
#comment[5] = The strategy used for options in the default sshd_config shipped with
#comment[6] = OpenSSH is to specify options with their default value where
#comment[7] = possible, but leave them commented.  Uncommented options change a
#comment[8] = default value.
#comment[9] = Port 22
#comment[10] = Protocol 2,1
Protocol = 2
#comment[11] = AddressFamily any
#comment[12] = ListenAddress 0.0.0.0
...
Subsystem/ = (none)
augtool> quit
After familiarizing yourself with augeas and making some changes to files in the sandbox, it's time to incorporate those changes into puppet using puppet's augeas plugin.

puppet-augeas

Help on using puppet-augeas is available on the puppet-augeas wikipage. After you have worked out the commands you need with augtool, you can rewrite them to work in puppet. From our previous example, we used set a few times to make a new entry in /etc/hosts. In puppet we'll use the augeas type and call set the same way.
augeas{ "server0":
	context => "/files/etc/hosts",
	changes => [
		"set 4/ipaddr 192.168.0.1",
		"set 4/canonical server0.example.com",
		"set 4/alias[1] server0",
		"set 4/alias[2] puppet-augeas.example.com",
	],
}

[root@client15 augeas-play]# puppetd --fqdn=$HOSTNAME --test --no-splay --server=server0.example.com --onetime --verbose --factsync
info: Retrieving facts
info: Caching catalog at /var/lib/puppet/localconfig.yaml
notice: Starting catalog run
notice: //Node[default]/base/Augeas[server0]/returns: executed successfully
notice: Finished catalog run in 1.87 seconds
[root@client15 augeas-play]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1		localhost.localdomain localhost
::1		localhost6.localdomain6 localhost6
192.168.0.31		client15.example.com client15
192.168.0.1	server0.example.com server0 puppet-augeas.example.com
[root@client15 augeas-play]# 
We replaced the alias puppet.example.com with puppet-augeas.example.com using puppet-augeas. Trying to make this change with a combination of sed or awk would be possible, but with augeas it is much more clear what we are trying to achieve and it is safer also.

For a more concrete example, we'll modify ssh to deny password access. We'll use the puppet nofity system to have ssh restart after we make the change with augeas.
Added to base.pp

service { sshd: ensure => true, enable => true, hasrestart => true }
augeas{ "ssh":
	context => "/files/etc/ssh/sshd_config",
	changes => [
		"set PasswordAuthentication no"
	],
	notify => Service["sshd"]
}
Now when we run puppet again sshd_config will be updated which will cause sshd to be restarted (triggered).
[root@client15 augeas-play]# puppetd --fqdn=$HOSTNAME --test --no-splay --server=server0.example.com --onetime --verbose --factsync
info: Retrieving facts
info: Caching catalog at /var/lib/puppet/localconfig.yaml
notice: Starting catalog run
notice: //Node[default]/base/Augeas[ssh]/returns: executed successfully
info: //Node[default]/base/Augeas[ssh]: Scheduling refresh of Service[sshd]
notice: //Node[default]/base/Service[sshd]: Triggering 'refresh' from 1 dependencies
notice: Finished catalog run in 3.04 seconds
[root@client15 augeas-play]# exit
Connection to client15.example.com closed.
[root@server0 manifests]# ssh root@client15.example.com
Permission denied (publickey,gssapi-with-mic).
Using a combination of kickstart, puppet and puppet-augeas, you can configure just about every change you need to make on a machine. But for those occasions where you need to make the change immediately, there is a solution, func. We'll talk about that next.