Authors – All

If you have a few years of experience in the DevOps ecosystem, and you're interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Overview

Puppet is a popular open-source configuration management tool that enables us to automate the provisioning, configuration, and management of infrastructure. One of the key features of Puppet is the ability to use variables to store and reuse values throughout a given manifest. In this context, a manifest defines the features of a provision or configuration. However, we sometimes need to check whether we have set a variable before using it to avoid errors or unexpected behavior.

In this tutorial, we’ll look at different methods to check if we’ve set a variable in Puppet.

2. Understanding Variables in Puppet

In Puppet, we use variables to store data that we can reference and manipulate throughout a given manifest.

Similar to many scripting languages, variables start with a dollar sign $ and can contain strings, numbers, booleans, arrays, or hashes:

$package_name = 'nginx'
$port = 80
$enable_ssl = true
$allowed_ips = ['127.0.0.1', '10.0.0.0/24']  
$config = {
  'user'  => 'www-data',
  'group' => 'www-data',
}

These are examples of variables in Puppet.

We can set variables in various ways and at various points in Puppet:

  • using the assignment operator = in the manifest itself
  • in Hiera, an external key-value configuration data store
  • in an external facts file containing system information
  • using the –define or -e flag in the command line

Considering the many alternatives, it’s often important to consider how to check whether a variable is defined at any point.

3. Check Variable Set Status With Conditional Statements

One of the ways we can check if we set a variable in Puppet is to use a conditional statement, such as an if statement or a case statement.

The if statements enable us to test a condition and execute a block of code if the condition is true:

if $enable_ssl {
  # Configure SSL
  package { 'openssl':
    ensure => installed,
  }
  file { '/etc/nginx/ssl':
    ensure => directory,
  }
  # ... more SSL config
} else {
  # Configure non-SSL
  file { '/etc/nginx/conf.d/default.conf':
    ensure  => file,
    content => template('nginx/default.conf.erb'),
  }  
}

In the code snippet above, the if statement checks whether we’ve set $enable_ssl variable to true. If so, it installs the openssl package and creates an ssl directory. If not, it configures nginx without SSL.

Similarly, we can use a case statement to check the value of a variable and execute different blocks of code based on the value:

case $::osfamily {
  'Debian': {
    $package_name = 'nginx-light'
  }
  'RedHat': {
    $package_name = 'nginx'
  }
  default: {
    fail("Unsupported OS family: ${::osfamily}")
  }
}

package { $package_name:
  ensure => installed,
}

In the code snippet above, the case statement checks the value of the $::osfamily fact, which contains the OS family (e.g., Debian or RedHat). Then, based on the value, the script sets the $package_name variable to the appropriate package name for that OS family. If it doesn’t support the OS family, it raises an error using the fail() function.

4. Check Variable Set Status With the defined() Function

Another way we can check if we’ve set a variable in Puppet is to use the defined() function. This function returns true if we define the variable, and false if otherwise:

if defined('$nginx_version') {
  notice("nginx version is set to ${nginx_version}")
} else {
  notice('nginx version is not set')
}

In the code snippet above, the defined() function checks if we have the $nginx_version variable already defined. If so, it prints a notice message with the value of the variable. If not, it prints a different notice message.

Furthermore, we can also use the defined() function in a conditional expression, such as a selector:

$nginx_version_string = defined('$nginx_version') ? {
  true    => $nginx_version,
  default => 'unknown',
}

file { '/usr/share/nginx/html/version.txt':
  ensure  => file,
  content => $nginx_version_string,
}

In the code snippet above, the selector checks if we’ve set the $nginx_version variable. If so, it assigns $nginx_version_string the value of $nginx_version. If not, it sets it to unknown. Then, it creates a file containing the version string.

5. Check Variable Set Status With the getvar() Function

Additionally, a third way we can check if we set a variable in Puppet is to use the getvar() function. This function retrieves the value of a variable if we set it, or returns under if it’s not:

$port = getvar('nginx_port')
if $port {
  notice("nginx port is set to ${port}")
} else {
  $port = 80
  notice("nginx port is not set, defaulting to ${port}")
}

In the code snippet above, the getvar() function retrieves the value of the nginx_port variable if we set it. If so, it sets $port to that value and prints a notice message. If not, it sets $port to 80 and prints a different notice message.

6. Check Variable Set Status With lookup() Function

Puppet 4 introduces the lookup() function, which provides a unified way to retrieve values from Heira, the environment data provider, and the module data provider. The lookup() function can specify a default value to return if it doesn’t find the key we request. This makes it an effective way to check for set variables and provide fallback values:

$nginx_port = lookup('nginx::port', { 'default_value' => 80 })
$nginx_user = lookup('nginx::user', { 'default_value' => 'www-data' })

class { 'nginx':
  port => $nginx_port,
  user => $nginx_user,
}

In the code snippet above, the lookup() function retrieves the values of nginx::port and nginx::user from Hiera or the module data provider. If these keys aren’t found, it uses the default values we specify (80 and www-data) instead.

Thus, using lookup() with default values is an efficient way to check if variables are set. In particular, it combines the variable lookup and the default value assignment in a single step. This approach reduces the need for conditional statements and makes the code more concise and readable.

7. Best Practices

Let’s look at some of the best practices we should keep in mind when we’re checking if a variable is set in Puppet:

  • using meaningful variable names that convey the purpose and scope of the variable
  • set default values for variables that are optional or have a common value
  • using Hiera to store external data and override default values to separate the configuration data from the code logic

So, if we follow these best practices, we can write cleaner, more maintainable Puppet code that’s usually easier to understand and debug.

8. Conclusion

In this tutorial, we’ve learned different methods we can use to check if a variable is set in Puppet.

To begin with, we discussed variables in Puppet and how we can set variables in Puppet. After that, we looked at ways to check if a variable is set using conditional statements, the define() function, the getvar() function, and the lookup() function. Finally, we went through some best practices we should keep in mind when checking if a variable is set in Puppet.

Authors – All

If you have a few years of experience in the DevOps ecosystem, and you're interested in sharing that experience with the community, have a look at our Contribution Guidelines.