6

There is a config file e.g. /etc/network/interfaces. I want to manage only a certain section of that file using Puppet.

Example:

# At the beginning at least is some dynamic content that can be different
# from machine to machine and changed by an admin manually
auto eth0
iface eth0 inet static
    address 192.168.108.5
    netmask 255.255.255.0

# BEGIN PUPPET WLAN0
allow-hotplug wlan0
iface wlan0 inet static
    address 192.168.109.5
    netmask 255.255.255.0
# END PUPPET WLAN0

# Potentially more stuff that I do not want to touch through Puppet
# But could be static if it makes it more easy. E.g. simply force sections to end of file.

The stdlib file_line resource is very close to what I need. A regex and content to replace a match with. However, unfortunately, there is no way to make file_line match over multiple lines and replace with new content.

Alternative 1: create a bash script: ugly Exec resources and temp files.

Alternaitve 2: Use Augeas: seems overkill for a simple search & replace.

Is there another module than stdlib that allows me to do a regex match & replace over multiple lines?

Any other handcraft solutions better than juggling temp bash script and Exec resource?

3
  • Is the #More stuf... section static?
    – Joseph R.
    Aug 6, 2014 at 21:17
  • Ideally, there could be any content. Like in the example above, there might be an additional interface, or not. Keeping it static is a possible constraint of course if it makes maintenance through puppet much easier.
    – Alex
    Aug 7, 2014 at 2:18
  • You may find this ticket worth watching...
    – Mikhail T.
    Oct 22, 2016 at 17:13

4 Answers 4

2

You can simply use a single line match as the placeholder for a multi-line value:

$wlan_address = [...]
$wlan_netmask = [...]
$wlan_string = "allow-hotplug wlan0
iface wlan0 inet static
    address ${wlan_address}
    netmask ${wlan_netmask}"

file_line { 'wlan0':
  path  => '/etc/network/interfaces',
  line  => $wlan_string,
  match => '^# PUPPET WLAN0$',
}
2

Managing part of a file is a configuration management anti pattern that should be discouraged as much as possible.

You have already identified the various tools that can do this.

  • Augeas
  • stdlib/file_line
  • exec + sed

You can alternatively manage the whole file, and do an 'onlyif' so the file isn't overwritten every time.

As you have found, file_line only really works on init style config files, that are single line.

Your best bet will be to do an exec on that file with a sed insert.

1

There is a module in puppet already installed by default called:puppetlabs-stdlib and within this module a defined type called file_line which does the trick :) Here is my case scenario under the /manifests/node.pp:

node elk.ershandc.org {
...
file_line { 'backup_authorized_key' :
    ensure => 'present',
    path   => '/root/.ssh/authorized_keys',
    line   =>'ssh-rsaAAAAB3NzaC1yc2EAAAADAQABAAABAQC1ZCi/K0hlffi9ZUmveJ05l301RE6u/TzrCK+i54edzN5stR/tTjd28vFIup10HTYoZxbqBgRMrxVGDnfwtaSsCZH31g2/flZBxSZGzjySKeUqnf/YyGJP6my/IjA4xcKVcPDPx2FF/u1Sd07y7wnLizjAhtIOwq1daiCcRbXkIxfpobQt/RtJLAyDA1CwACr9NWmAezS0rnaYXRBQrmrkCBx91fMhKsarvxB3z4mTG8wVNwXvE9g2Hps6bRzff0hIXaIoVFYHwqmyIkN+4xCDGcjt3TjZp0zvTK20RR7DNOHxOGs8GBhcvitEkGY/JXgA4AJ26ncfXaspaUgEM/Rt root@devop-testbed'
 }

...
}
0

If you can guarantee the other file contents are static, you can just make that file into a template and keep the static sections unchanged. Example:

auto eth0
iface eth0 inet static
address 192.168.108.5
netmask 255.255.255.0

# BEGIN PUPPET WLAN0
allow-hotplug wlan0
iface wlan0 inet static
    address <%= wlan0_address %>
    netmask <%= wlan0_netmask %>
# END PUPPET WLAN0

# More stuff that I do not want to touch through Puppet
# Static content here

This example assumes that you have defined the variables $wlan0_address and $wlan0_netmask elsewhere.

You then deploy with a file resource:

file{'interfaces':
        ensure  => file,
        path    => '/etc/network/interfaces',
        content => template('/path/to/template'),
}
1
  • Ok, sure, but now we're not talking about "replacing a section" at all anymore. I could constrain it to "section must always be at the end". The idea here is though to allow some modifications in the file outside of the scope of Puppet (e.g. can be whatever and different on every machine). Sorry, I guess my previous comment on the question was not clear.
    – Alex
    Aug 8, 2014 at 23:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .