Accessing EPP variables

Embedded Puppet (EPP) templates can access variables with the $variable syntax used in Puppet.

A template works like a defined type:

  • It has its own anonymous local scope.
  • The parent scope is set to node scope (or top scope if there’s no node definition).
  • When you call the template (with the epp or inline_epp functions), you can use parameters to set variables in its local scope.
  • Unlike Embedded Ruby (ERB) templates, EPP templates cannot directly access variables in the calling class without namespacing. Fully qualify variables or pass them in as parameters.

EPP templates can use short names to access global variables (like $os or $trusted) and their own local variables, but must use qualified names (like $ntp::tinker) to access variables from any class. The exception to this rule is inline_epp.

Special scope rule for inline_epp

If you evaluate a template with the inline_epp function, and if the template has no parameters, either passed or declared, you can access variables from the calling class in the template by using the variables’ short names. This exceptional behavior is only allowed if all of the above conditions are true.

Should I use a parameter or a class variable?

Templates have two ways to use data:

  • Directly access class variables, such as $ntp::tinker

  • Use parameters passed at call time

Use class variables when a template is closely tied to the class that uses it, you don’t expect it to be used anywhere else, and you need to use a lot of variables.

Use parameters when a template is used in several different places and you want to keep it flexible. Remember that declaring parameters with a tag makes a template’s data requirements visible at a glance.

EPP parameters

When you pass parameters when you call a template, the parameters become local variables inside the template. To use a parameter in this way, pass a hash as the last argument of the epp or inline_epp functions.

For example, calling this:

epp('example/example.epp', { 'logfile' => "/var/log/ntp.log" })
to evaluate this template:
<%- | Optional[String] $logfile = undef | -%>
<%# (Declare the $logfile parameter as optional) -%>

<% unless $logfile =~ Undef { -%>
logfile <%= $logfile %>
<% } -%>
The keys of the hash match the variable names you’ll be using in the template, minus the leading $ sign. Parameters must follow the normal rules for local variable names.

If the template uses a parameter tag, it must be the first content in a template and you can only pass the parameters it declares. Passing any additional parameters is a syntax error. However, if a template omits the parameter tag, you can pass it any parameters.

If a template’s parameter tag includes any parameters without default values, they are mandatory. You must pass values for them when calling the template.

Sensitive data

Puppet (version 6.20 and later) can interpolate sensitive values. In your EPP template, you can access the sensitive variable without unwrapping. For example:

host=<%= $db_host %>
password=<%= $db_password %>

The rendered output is automatically sensitive and used as the file content:

db_password= Sensitive('secure_test')
host = examplehost
file { '/etc/service.conf':
  ensure => file,
  content => epp('<module>/service.conf.epp')
}
ERB templates do not support interpolation of sensitive values — you have to manually unwrap and re-wrap these.