Hiera lookups in rspec-puppet

February 9, 2022 

While rspec-puppet documentation is quite decent, it does not really explain how to test classes that get their parameters via Hiera lookups, such as profiles in the roles and profiles pattern. Several parameters related to Hiera are listed in the rspec-puppet configuration reference, but that's all. The other documentation you find on the Internet is generally outdated and not applicable for modules converted with PDK.

In this article we show how to test an "ipa_client" class that uses lookups to get its parameter from Hiera. It used to be a profile that was later separated from the control-repo into a separate module, which means that rspec-puppet does not have access to the control-repo's Hiera data.

The first step is to make the class spec file load a Hiera config:

let(:hiera_config) { 'hiera-rspec.yaml' }

If this line is missing then rspec-puppet will not do any Hiera lookups. The hiera-rspec.yaml file should be placed to the module root. Its contents should be like this:

---
version: 5

defaults:  # Used for any hierarchy level that omits these keys.
  datadir: data         # This path is relative to hiera.yaml's directory.
  data_hash: yaml_data  # Use the built-in YAML backend.

hierarchy:
  - name: 'rspec'
    path: 'rspec.yaml'

This hierarchy is completely separate from the module's default hierarchy to prevent rspec data and module data (defaults) from getting entangled.

The data/rspec.yaml file contains the data required by the lookups in the class and nothing more:

ipa_manage: true
ipa_domain: 'example.org'
ipa_admin_password: 'foobar'
ipa_master_fqdn: 'ipa.example.org'
ipa_configure_sshd: false
ipa_enable_dns_updates: true
ipa_client_sshd_notify:

The class spec file was generated with PDK and only slightly modified to support lookups and the special requirements of the class itself:

# frozen_string_literal: true

require 'spec_helper'

describe 'ipa_client' do
  on_supported_os.each do |os, os_facts|
    context "on #{os}" do
      extra_facts = {}
      extra_facts[:ipa_force_join] = false
      extra_facts[:lsbdistcodename] = 'RedHat' if os_facts[:osfamily] == 'RedHat'

      let(:facts) { os_facts.merge(extra_facts) }
      let(:hiera_config) { 'hiera-rspec.yaml' }

      it { is_expected.to compile }
    end
  end
end

Further reading

Samuli Seppänen
Samuli Seppänen
Author archive
menucross-circle