{"id":1309,"date":"2010-02-19T19:14:20","date_gmt":"2010-02-19T18:14:20","guid":{"rendered":"http:\/\/www.devco.net\/?p=1309"},"modified":"2010-06-27T19:11:41","modified_gmt":"2010-06-27T18:11:41","slug":"building_files_from_fragments_with_puppet","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2010\/02\/19\/building_files_from_fragments_with_puppet.php","title":{"rendered":"Building files from fragments with Puppet"},"content":{"rendered":"
While building up complex configs with Puppet you often need to build up one file from many fragments. This is useful for files like older sysctl.conf<\/em> files and maybe named.conf<\/em> files. <\/p>\n The basic pattern is you want to manage a file, but want the contents to be very different from node to node. A fragment based system lets you register different contents into a file on different nodes. It’s exactly like the conf.d<\/em> directory you’d find in Apache but for daemons that does not support this construct on their own.<\/p>\n I’ve had an older version of this floating around but had to clean it up for a client today so thought I might as well do a proper job, release it and get some more eye balls on it. This version is specific to Puppet 0.25.x, I will soon make a >= 0.24.8 version too since that is what my client is on.<\/p>\n An example says more than words, so lets create something to manage sysctl.conf<\/em>: <\/code><\/p>\n The above sets up a class that will create an empty sysctl.conf<\/em> and provides an utility for setting individual values. Whenever the sysctl.conf<\/em> file gets changed the changes will be made live using the refreshonly exec<\/em>.<\/p>\n Lets see how we might use it:<\/p>\n <\/code><\/p>\n You can see this looks and feels a lot like a native type but without a lot of the hassle it would take to write one, you can really get a lot of mileage out of this pattern. The concat is clever enough to unregister the setting should you remove lines 4 to 6 in the above node block.<\/p>\n
\n<\/p>\n
\r\n# Initial setup\r\nclass sysctl {\r\n include concat::setup\r\n\r\n exec{\"reload-sysctl\":\r\n refreshonly => true,\r\n command => \"\/sbin\/sysctl -p\"\r\n }\r\n\r\n concat{\"\/etc\/sysctl.conf\":\r\n notify => Exec[\"reload-sysctl\"],\r\n }\r\n}\r\n\r\n# use this to set values\r\ndefine sysctl::setting($value) {\r\n concat::fragment{\"sysctl_${name}\": \r\n target => \"\/etc\/sysctl.conf\",\r\n content => \"${name} = ${value}\\n\",\r\n }\r\n}\r\n<\/pre>\n
<\/p>\n
\r\nnode \"your.example.com\" {\r\n include sysctl\r\n\r\n sysctl::setting{\"net.ipv4.ip_forward\":\r\n value => 1\r\n }\r\n}\r\n<\/pre>\n