Puppet inline template with puppet:// in URL

2.2k views Asked by At

In my Puppet module, I have something like this:

file {'myfile':
  ensure => 'file',
  path => '/whatever/myfile',
  content =>  inline_template(file(
    "puppet:///modules/my_module/templates/${domain}/${::hostname}_myfile.erb",
    "puppet:///modules/my_module/templates/${domain}/myfile.erb"
  ))
}

And my spec looks like:

require 'spec_helper'

describe 'my_module' do
  context 'with defaults for all parameters' do
    it { should compile }
  end
end

If try to run it, I get:

Failure/Error: it { should compile }
  error during compilation: Evaluation Error: Error while evaluating a Function Call, Could not find any files from puppet:///modules/my_module/templates/dev.contaazul.local/myfile.erb, puppet:///modules/my_module/templates/dev.contaazul.local/myfile.erb at /home/carlos/Code/Puppet/modules/my_module/spec/fixtures/modules/my_module/manifests/init.pp:48:33 on node becker.local

Obviously, it cannot find any of the ERB templates. If I replace the puppet:// part for /home/carlos/Code/Puppet/ (where the code actually lives), it passes, but in production it is /etc/puppet/, so, it will not work.

How can I make this work?

2

There are 2 answers

0
Chris Pitman On BEST ANSWER

RI Pienaar has released a code snippet for a function with this behavior. You will need to copy this code into a file in one of your modules at the path lib/puppet/parser/functions/multi_source_template.rb.

Once you do that, you should be able to use it like so:

file {'myfile':
  ensure => 'file',
  path => '/whatever/myfile',
  content =>  multi_source_template(
    "my_module/${domain}/${::hostname}_myfile.erb",
    "my_module/${domain}/myfile.erb"
  )
}
0
Felix Frank On

As to why the original approach doesn't work: URLs are usually used with the source property only and transferred to the agent as is. The agent consumes the URL and makes an according request to a Puppet fileserver (which is just another master).

The file function on the other hand (as used here with the content property in conjunction with inline_template) will not process URLs and expects local paths instead.

All that being said, the issue could possibly have been side-stepped by specifying both the paths for the test box and the production system, with the latter just acknowledging that /home/carlos is missing. But that would have been far from a clean solution.