Search code examples
puppet

How to build a file based on defined-type instances in Puppet


I want my Puppet class to create a file resource with contents based on all instances of a particular defined type. I looked at this question with the idea of iterating over the instances to build the file, but apparently it's a "Bad Idea" per the one answer currently there.

Some background: I am building a monitor_service class in Puppet to deploy a custom monitoring application. The application reads a config file that tells it what to monitor, one item per line, along the lines of

ITEM: /var/things/thing-one (123)
ITEM: /var/things/thing-two (456)

I am also writing a defined type that deploys instances of the monitored items:

define my_thing::monitored_thing ( $port ) {
  file { "/var/things/$name":
     ...
  }
}

On a given node, I set up several monitored_things like

my_thing::monitored_thing { "thing-one":
  port => 123
}
my_thing::monitored_thing { "thing-two":
  port => 456
}

What's the "right" Puppet idiom for building the monitoring service config file? I would prefer for this to work in such a way that the monitor_service class doesn't have to be told which monitored_thing instances it is watching -- just creating a monitored_thing instance should cause it to be added to the config file automatically.


Solution

  • There are several ways to modify/declare only part of a file within multiple defined types:

    1. Use puppetlabs-stdlib's file_line. This lets you specify that a file should contain a specific line. Best when you do not care about the other file contents and just want to make sure a line is present or absent.

    2. Use puppetlabs-concat if you want to make sure that the final file only includes the fragments that you are specifying or the order of the fragments matters.

    3. Use the augeas type if you need to edit/add configuration to a file with a more complicated structure, like xml, apache configurations, etc.