Search code examples
loopsiterationpuppet

How do I iterate through an array of hashes in puppet 3.8?


I am trying to set up a simple puppet class to loop through an array of hashes, each of which contain configuration for a yum repository. I am using Puppet version 3.8.2 which means that using a .each function is not possible.

Currently my puppet code looks like this:

class ::yum_repos {

      $repos = [
                  {
                    'name'  => 'test_repo1',
                    'base_url' => 'example1.com',
                    'ensure'  => 'present',
                    'gpgcheck' => 'true',
                  },
                  {
                    'name'  => 'test_repo2',
                    'base_url' => 'example2.com',
                    'ensure'  => 'present',
                    'gpgcheck' => 'true',
                  },
               ]

      define add_repo {
        yumrepo { $name:
          ensure   => $ensure,
          name     => $name,
          baseurl  => $base_url,
          gpgcheck => $gpgcheck,
          enabled  => 'true',
        }
      }
      add_repo { $repos: }
    }

Unfortunately, this is throwing the following error:

Error: Could not retrieve catalog from remote server: Could not intern from text/pson: Could not intern from data: Could not find relationship source "::yum_repos::Add_repo[nametest_repo2ensurepresentgpgchecktruebase_urlexample2.com]"

Is anybody able to explain the correct method of doing this?

Thanks very much in advance!


Solution

  • To iterate over resource declarations (or larger blocks of code) in Puppet < 4 without the future parser, we need to make use of hashes, a defined resource type (if not iterating over an intrinsic type), and the create_resources function. The usage is documented here.

    For your specific case, the code would look like:

    # hash of resources
    $repos = {
      'test_repo1' => { 'base_url' => 'example1.com',
                        'ensure'   => present,
                        'gpgcheck' => true,
      },
      'test_repo2' => { 'base_url' => 'example2.com',
                        'ensure'   => present,
                        'gpgcheck' => true,
      },
    }
    
    # iterate over resource declarations
    create_resources(yumrepo, $repos)
    

    If you wanted to iterate over a larger block of resources, then using your defined resource type as an example, we would modify the above accordingly:

    # defined resource type encapsulating code to iterate over
    define add_repo($ensure, $base_url, $gpgcheck) {
      yumrepo { $title:
        ensure   => $ensure,
        baseurl  => $base_url,
        gpgcheck => $gpgcheck,
        enabled  => true,
      }
    }
    
    # iterate over resource declarations
    create_resources(add_repo, $repos)