title: How to use Puppet parameterized classes to force order of resources applied?
body: <p>The Puppetlabs docs state that in order for one class to require another class you should use the relationship chaining syntax and declare both classes in your outer nodes.</p>
  
  <p>I have a repo class which creates the yum repo definition that many packages in each modole depend on. In each module I have a Class['repo'] -> Class['modulename'] statement and both classes are declared in the node. However, when puppet runs it doesn't always execute the repo class before the module class as expected. Why not? Example below (puppet 2.6.16):</p>
  
  <p><strong>EDIT:</strong> It appears there are 3 basic solutions to this problem. </p>
  
  <ol>
  <li>Replace the class dependencies with resources dependencies using
  before/require metaparameters (as shown in turingmachine's answer).</li>
  <li>Remove exterior class dependencies and explicitly state dependencies
  between inner classes.</li>
  <li>Use anchor type as provided by Puppetlabs in the stdlib module to
  contain a class allowing the depending class to create a reference
  to the external class using the chaining syntax.</li>
  </ol>
  
  <p>So which of these approaches is best, considering Puppet v3 and the desire to keep refactoring to a minimum going forward'?</p>
  
  <p>Manifest <code>puppettest.pp</code>:</p>
  
  <pre><code>class { 'repo': }
  class { 'maradns': }
  
  class repo {
    class { 'repo::custom': }
  }
  
  class repo::custom {
    yumrepo {'custom':
      enabled  =&gt; 1,
      gpgcheck =&gt; 0,
      descr    =&gt; "Local respository - ${::architecture}",
      baseurl  =&gt; 'http://repo.nike.local/CentOS/\$releasever/\$basearch';
    }
  }
  
  class maradns {
    Class['repo'] -&gt; Class['maradns::install']
    Class['maradns::install'] -&gt; Class['maradns::config']
    Class['maradns::config'] ~&gt; Class['maradns::service']
    class { 'maradns::install': }
    class { 'maradns::config':  }
    class { 'maradns::service': }
  }
  
  class maradns::install {
    package { 'maradns':
      ensure  =&gt; present,
    }
  }
  
  class maradns::config {
    file { 'mararc':
      ensure  =&gt; present,
      path    =&gt; '/etc/mararc',
      mode    =&gt; '0644',
      owner   =&gt; root,
      group   =&gt; root,
    }
  }
  
  class maradns::service {
    service { 'maradns':
      ensure     =&gt; running,
      enable     =&gt; true,
      hasrestart =&gt; true,
    }
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>puppet apply puppettest.pp    
  err: /Stage[main]/Maradns::Install/Package[maradns]/ensure: change from absent to present failed: Execution of '/usr/bin/yum -d 0 -e 0 -y install maradns' returned 1: Error: Nothing to do
  
  notice: /Stage[main]/Maradns::Config/File[mararc]: Dependency Package[maradns] has failures: true
  warning: /Stage[main]/Maradns::Config/File[mararc]: Skipping because of failed dependencies
  notice: /Stage[main]/Maradns::Service/Service[maradns]: Dependency Package[maradns] has failures: true
  warning: /Stage[main]/Maradns::Service/Service[maradns]: Skipping because of failed dependencies
  notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/descr: descr changed '' to 'Local respository - x86_64'
  notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/baseurl: baseurl changed '' to 'http://repo.test.com/CentOS/\$releasever/\$basearch'
  notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/enabled: enabled changed '' to '1'
  notice: /Stage[main]/Repo::Custom/Yumrepo[custom]/gpgcheck: gpgcheck changed '' to '0'
  notice: Finished catalog run in 2.15 seconds
  </code></pre>