Making quick edits to config files
When you need to have Puppet change a particular setting in a config file, it's common to simply deploy the whole file with Puppet. This isn't always possible, though; especially if it's a file that several different parts of your Puppet manifest may need to modify.
What would be useful is a simple recipe to add a line to a config file if it's not already present, for example, adding a module name to /etc/modules
to tell the kernel to load that module at boot. There are several ways to do this, the simplest is to use the file_line
type provided by the puppetlabs-stdlib
module. In this example, we install the stdlib
module and use this type to append a line to a text file.
Getting ready
Install the puppetlabs-stdlib
module using puppet:
t@mylaptop ~ $ puppet module install puppetlabs-stdlib Notice: Preparing to install into /home/thomas/.puppet/modules ... Notice: Downloading from https://forgeapi.puppetlabs.com ... Notice: Installing -- do not interrupt ... /home/thomas/.puppet/modules └── puppetlabs-stdlib (v4.5.1)
This installs the module from the forge into my user's puppet directory; to install into the system directory, run the command as root or use sudo
. For the purpose of this example, we'll continue working as our own user.
How to do it...
Using the file_line
resource type, we can ensure that a line exists or is absent in a config file. Using file_line
we can quickly make edits to files without controlling the entire file.
- Create a manifest named
oneline.pp
that will usefile_line
on a file in/tmp
:file {'/tmp/cookbook': ensure => 'file', } file_line {'cookbook-hello': path => '/tmp/cookbook', line => 'Hello World!', require => File['/tmp/cookbook'], }
- Run
puppet apply
on theoneline.pp
manifest:t@mylaptop ~/.puppet/manifests $ puppet apply oneline.pp Notice: Compiled catalog for mylaptop in environment production in 0.39 seconds Notice: /Stage[main]/Main/File[/tmp/cookbook]/ensure: created Notice: /Stage[main]/Main/File_line[cookbook-hello]/ensure: created Notice: Finished catalog run in 0.02 seconds
- Now verify that
/tmp/cookbook
contains the line we defined:t@mylaptop ~/.puppet/manifests $ cat /tmp/cookbook Hello World!
How it works…
We installed the puppetlabs-stdlib
module into the default module path for Puppet, so when we ran puppet apply
, Puppet knew where to find the file_line
type definition. Puppet then created the /tmp/cookbook
file if it didn't exist. The line Hello World!
was not found in the file, so Puppet added the line to the file.
There's more…
We can define more instances of file_line
and add more lines to the file; we can have multiple resources modifying a single file.
Modify the oneline.pp
file and add another file_line
resource:
file {'/tmp/cookbook': ensure => 'file', } file_line {'cookbook-hello': path => '/tmp/cookbook', line => 'Hello World!', require => File['/tmp/cookbook'], } file_line {'cookbook-goodbye': path => '/tmp/cookbook', line => 'So long, and thanks for all the fish.', require => File['/tmp/cookbook'], }
Now apply the manifest again and verify whether the new line is appended to the file:
t@mylaptop ~/.puppet/manifests $ puppet apply oneline.pp Notice: Compiled catalog for mylaptop in environment production in 0.36 seconds Notice: /Stage[main]/Main/File_line[cookbook-goodbye]/ensure: created Notice: Finished catalog run in 0.02 seconds t@mylaptop ~/.puppet/manifests $ cat /tmp/cookbook Hello World! So long, and thanks for all the fish.
The file_line
type also supports pattern matching and line removal as we'll show you in the following example:
file {'/tmp/cookbook': ensure => 'file', } file_line {'cookbook-remove': ensure => 'absent', path => '/tmp/cookbook', line => 'Hello World!', require => File['/tmp/cookbook'], } file_line {'cookbook-match': path => '/tmp/cookbook', line => 'Oh freddled gruntbuggly, thanks for all the fish.', match => 'fish.$', require => File['/tmp/cookbook'], }
Verify the contents of /tmp/cookbook
before your Puppet run:
t@mylaptop ~/.puppet/manifests $ cat /tmp/cookbook Hello World! So long, and thanks for all the fish.
Apply the updated manifest:
t@mylaptop ~/.puppet/manifests $ puppet apply oneline.pp Notice: Compiled catalog for mylaptop in environment production in 0.30 seconds Notice: /Stage[main]/Main/File_line[cookbook-match]/ensure: created Notice: /Stage[main]/Main/File_line[cookbook-remove]/ensure: removed Notice: Finished catalog run in 0.02 seconds
Verify that the line has been removed and the goodbye line has been replaced:
t@mylaptop ~/.puppet/manifests $ cat /tmp/cookbook Oh freddled gruntbuggly, thanks for all the fish.
Editing files with file_line
works well if the file is unstructured. Structured files may have similar lines in different sections that have different meanings. In the next section, we'll show you how to deal with one particular type of structured file, a file using INI syntax.