r26D

Puppet Class Scope Gotcha

I’m in the process on refactoring our puppet mainfests based on the Node/Role/Profile/Module model from Craig Dunn’s article. I’m working with puppet 3.2 - so I don’t know if this applies to older versions.

I hit a terrible gotcha today. Basically you have to be very explicit in the way you setup the includes or puppet gets very confused about which module you mean to include.

I’m going to use Zamboni as the name for my module I want to wrap (can you tell I just got back from Canada?).

class zamboni {
  notice("Class zamboni included")
}

class role::zamboni {
  notice("Class role::zamboni included")
  include zamboni
}

class role::server { 
 notice("Class role::server included") 
 include role::zamboni
}
`</pre>

If you run this you will see (Your ip will depend on the box you are working with):

<pre>`* [192.168.10.7] Notice: Scope(Class[Role::Server]): Class role::server included
* [192.168.10.7] Notice: Scope(Class[Role::Zamboni]): Class role::zamboni included
`</pre>

You can see that the role::server is included. So is role::zamboni.  What is missing is the final include of the zamboni class itself.  This was really confusing.  I spent a while trying to get the dependencies to sort out before stumbling on the source of the problem.

I opened a [bug](http://projects.puppetlabs.com/issues/22219)  with Puppet to see if they will add a warning for this case (since it doesn't make sense to include a class in itself - or at least I don't think that makes sense).

In the mean time I can fall back on explicit scoping to get things to work -</pre>

<pre>`class zamboni {
  notice("Class zamboni included")
}

class role::zamboni {
  notice("Class role::zamboni included")
  include ::zamboni
}

class role::server {
  notice("Class role::server included")
  include role::zamboni
}

By referring to it with the explicit scope (:: is the base scope), the class will get included correctly.