Ask Your Question

How to conditionally import a class

asked 2014-07-28 13:33:31 -0600

spuder gravatar image

How would you conditionally include a class and set an order?


cat init.pp
class foo ( $jenkins_slave=false ) {
  case ${::osfamily} {
    'RedHat': { include foo::RedHat } 
    'Debian': { include foo::Debian }

  if $jenkins_slave == true {
    include foo::jenkins

cat jenkins.pp
class foo::jenkins inherits foo {

  package { 'some-package':
    ensure => present,
    source => "http://some-private-repo-defined-in-redhat.pp"

The problem is that Jenkins.pp is included before Redhat.pp / Debian.pp. The latter two classes set up the appropriate repos that are required by jenkins.pp

I don't see any way to make jenkins.pp run after the redhat/debian classes without a whole bunch of if else statements.

Options that I see:

Move the entire jenkins.pp inside redhat and debian.pp. The downside to this is there will be a lot of code duplication. Aslo jenkins.pp is relativly large


Put a require on the 'some-package' resource.

  package { 'some-package':
    ensure => present,
    source => "http://some-private-repo-defined-in-redhat.pp"
   require => Class["foo::${osfamily}]

The downside to this is that putting dependencies inside classes is frown upon.


Use the anchor pattern. Unfortunately this also will require a collection of if else statements, and variables for class names

Are there any alternatives? If not, what would be the best way to approach this problem?

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted

answered 2014-07-28 15:01:29 -0600

ramindk gravatar image

If you must have classes named after the OS, which isn't my favorite way to deal with this, you can do the following. Also don't capitalize the classes unless you're referring to the namespace in the DSL.

class foo ( $jenkins_slave=false ) {

  include foo::$osfamily # you might need to quote osfamily in someway, I forget.

  if $jenkins_slave == true {
    include foo::jenkins
    Class ["foo::${osfamily}"] -> Class['foo::jenkins'] # same thing with the quoting

That said I'd put it all into Hiera where the logic belongs.

node some node {
   include profile::$osfamily

and then

class profile::debian {
  include ::apt

  # use hiera_hash and count on merging as well.
  $mypins = hiera_hash('apt::pins', {})
  create_resources('apt::pin', $mypins)
  $myrepos = hiera_hash('apt::repos', {})
  create_resources('apt::repo', $myrepos)
  # etc etc
edit flag offensive delete link more


Thanks, this is pretty much what I ended up doing. Since this is a masterless puppet module, I'm not sure I can use hiera.

spuder gravatar imagespuder ( 2014-07-29 09:44:40 -0600 )edit

Hiera works fine with masterless, but you'll need to push the data to the nodes when you sync code.

ramindk gravatar imageramindk ( 2014-07-30 13:00:32 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2014-07-28 13:33:31 -0600

Seen: 4,771 times

Last updated: Jul 28 '14