Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Puppet Can't Find Variable for Template

Tags:

puppet

Just getting started with Puppet, and I'm having trouble with my first template. It should be very easy, but I can't figure it out.

I have a module "base" at

/etc/puppet/modules/base/
    ./manifests
    ./manifests/service.pp
    ./manifests/init.pp
    ./manifests/params.pp
    ./manifests/config.pp
    ./manifests/install.pp
    ./templates
    ./templates/puppet.conf.erb

There's other stuff, but it's not necessary.

base/manifests/init.pp:

class base {
  include base::install, base::service, base::config, base::params
}

base/manifests/config.pp

class base::config {
  include base::params

  File {
    require => Class["base::install"],
    ensure => present,
    owner => root,
    group => root,
  }

  file { "/etc/puppet/puppet.conf":
    mode => 0644,
    content => template("base/puppet.conf.erb"),
    require => Class["base::install"],
    nofity => Service["puppet"],
  }
...

base/manifests/params.pp

class base::params {
  $puppetserver = "pup01.sdirect.lab"
}

Finally the interesting part of the template at base/templates/puppet.conf.erb

...
server=<% puppetserver %>

The error message:

err: Failed to parse template base/puppet.conf.erb: Could not find value for 'puppetserver' at /etc/puppet/modules/base/manifests/config.pp:13 on node ...

I don't get what the problem is. I've copied this part straight out of the Pro Puppet book.

Could someone show me where $puppetserver should be defined and how?

like image 547
fandingo Avatar asked Nov 28 '22 17:11

fandingo


1 Answers

The issue is that the name "puppetserver" needs to be fully qualified so Puppet can find the value, since it's defined in a different scope to the one the template is evaluated in.

The variable is defined in base::params so can only be referred to simply as "puppetserver" in that scope. When you're evaluating the template from within base::config, you're in a different scope and so you can't refer to the variable simply by its short name. The "include" adds the other class to the catalog, but doesn't change these rules.

This means to access it, you fully qualify it with the class name: base::params::puppetserver. If you were using it in the manifest itself, this would be $base::params::puppetserver. You'll see similar examples in Pro Puppet in the ssh::config and ssh::service classes where it refers to "ssh_service_name" in the params class (pages 43-45).

To access the variable in a template it's a bit different, use scope.lookupvar("base::params::puppetserver"). Taking your full example and adding a missing equals sign (to output the value) in the template:

...
server=<%= scope.lookupvar("base::params::puppetserver") %>

There's a bit more information about scoping on the Scope and Puppet as of 2.7 page.

(Edit: looks like it's listed on the confirmed errata page too with the same solution.)

like image 112
Dominic Cleal Avatar answered Feb 23 '23 22:02

Dominic Cleal