Many areas in the puppetlabs/apache module such as vhost.pp you can see error handling that requires the base class to be included first because the class in question uses the base class in its' parameter defaults.
Here in dev.pp there are no parameters though you can see the reference to $::apache::dev_packages
which is declared by the ::apache::params
class when ::apache
is initialized.
However, in vhosts.pp you can see that the base class is included explicitly without an expectation that it was previously included.
My understanding of this is that apache::vhosts
is designed to be used as a standalone class and it's inclusion of ::apache
initializes Apache's default configuration as determined by the module. However, if Apache is declared elsewhere such as:
class { '::apache':
*params*
}
Then the inclusion of the base class utilizes whatever values were passed as arguments to the base class. Is that correct? Why would two public classes apache::vhosts
and apache::dev
have two different requirements for usage?
First of all, these are not base and subclasses. Puppet does have class inheritance, but
apache::dev
does not use it, andapache::vhost
isn't even a class (it's a defined type). Theapache
class is the module's "main" class, andapache::dev
is simply another class in the same module.Pretty much the only good use for class inheritance is to support obtaining class parameter defaults from another class's variables, but evidently, the people in control of Puppet's online docs no longer think that's a good idea either (though you can still see an example in class
apache
). Hiera support for data in modules is a decent alternative, but I sometimes think that Puppet, Inc. is too fascinated with their shiny new goodies, and too dismissive of older features that work fine when used as documented, but break unfortunately when misused.... and no inclusion of class
apache
. But there is code that will cause catalog building to fail in the event thatapache
has not already been declared, separately.Yes, that's fairly normal. More normal, indeed, than
apache::dev
's behavior.apache::vhost
is intended for public use, so if you declare an instance then it ensures that everything it needs is included in the catalog, too.Not exactly.
apache::vhost
is intended to be a public type, and it does declare::apache
to ensure that everything needed to support it is indeed managed. You can characterize that as "standalone" if you like. But the inclusion of::apache
there is no different from the same anywhere else. If that class has already been added to the catalog then it it has no additional effect. Otherwise, it is added, with parameters drawn from Hiera data where such parameter data are defined, and hard-coded defaults where not. Hiera is how one should, generally, customize class parameters, and where that is done, the resulting apache configuration is not accurately characterized as "default" or defined by the module.If such a resource-like class declaration has already been evaluated then, as I already said,
apache::vhost
's include-like declaration has no additional effect. But if such a resource-like class declarations is evaluated later then catalog building will fail. This is one of the major reasons to avoid resource-like class declarations and rely on data binding via Hiera for class parameter customization.Because the module was developed over multiple years by hundreds of contributors. It is not surprising that that produced some inconsistency. Especially so because even Puppet developers who contribute to modules are at different points on the road to enlightenment.
The only plausible justification for preferring the approach of
apache::dev
is to avoid interfering with a resource-like declaration of classapache
that is evaluated later, but avoiding such a failure by forcing a different failure is not a major gain. It does afford the opportunity to provide a clearer diagnostic in cases that would fail anyway, but at the expense of failing arbitrarily in other cases where it could just work instead.