muru muru - 9 months ago 90
Ruby Question

How do I optionally include a file in a Puppet ERB template?

I'm trying to create a Puppet ERB template for a file, with some default content and an optional tail. The optional part is to be determined by the hostname/FQDN of the Ppuppet client, and need not exist. Currently, I have this:

<%= scope.function_file(['mod/default']) %>
<%= scope.function_file(["mod/" + @hostname, "mod/" + @fqdn, 'mod/empty']) %>

is the module name. I had to create an empty
so that
doesn't fail if it doesn't find a file for the hostname or FQDN. I think this is ugly.

I have tried variations of:

<%='default') %>
<% if File.file?(@hostname) %>
<%= %>
<$ elsif File.file?(@fqdn) %>
<%= %>
<& end %>

With files placed in the
directory instead of
, but I usually got an error about missing files. Using
with the files in
also has the same problem as
- the action fails if files are missing.

How can I do this, without having to create placeholder files (like


Instead of using scope.function_file in the erb template itself, you should consider using it in your manifest. The below should suffice and should stop you from creating the "empty" file.

$default_content = file('mod/default')
$tail = file(

if $tail != "" {
  $real_content = "${default_content}\n${tail}"
} else {
  $real_content = $default_content

Then in your template you can just use <%= @real_content %>

If that is the only content of the file then you can skip using a template altogether and just use the file resource as follows:

file { '/path/to/file':
  ensure  => file,
  content => $real_content

By using /dev/null you will get empty content if mod/${::hostname}, or mod/${::fqdn} do not exist. Or you can stick with your route and just add /dev/null to your scope.function_file calls.