Ask Your Question
2

Containment with Role and Profile pattern

asked 2015-08-26 06:10:33 -0500

We're using the role/profile pattern for our nodes, and I've come across something that I'm having trouble getting my head around when it comes to class containment and resource ordering.

I have a role for a particular node, and due to the way that the profiles work, I need to ensure the ordering of some of them - I'm using LVM to create a volume group that needs to be in place before myapp is configured since it depends on the volume being mounted first.

This is what I'm doing:

class role::foorole {
  contain '::profile::default'
  contain '::profile::lvm'
  contain '::profile::myapp'

  Class['::profile::lvm'] ->
  Class['::profile::myapp']
}

Both the ::profile::lvm and ::profile::myapp classes contain the classes that they're managing, i.e.:

::role::foorole contains ::profile::lvm contains ::lvm

The problem I'm having is that the containment doesn't seem to be working for the subclasses of the various modules. Looking at the dependency graph from a node, I see the dependency between the role, profile and the base class for each module. However, the subclasses of each module (i.e. lvm::config, myapp::install etc) are floating off on their own, with only a dependency on Stage['main'] and not the profile class that contains them.

I refactored the various modules to follow R. I. Pienaar's simple Puppet module structure, to create dependencies between the subclasses and the outer class that the profile declares. However, this did not seem to affect the dependencies between the profile and the subclasses of the modules.

In the end I resolved the issue by changing the module to explicitly contain its subclasses, i.e.:

class myapp (
  # bunch of params#
) inherits myapp:params {
    contain '::myapp::repository'
    contain '::myapp::install'
    contain '::myapp::config'
    contain '::myapp::service'

    Class ['::myapp::repository'] ->
    Class ['::myapp::install'] ->
    Class ['::myapp::config'] ~>
    Class ['::myapp::service']
}

This has resolved the containment and therefore the resource ordering, but I suspect that this is the wrong way to resolve this problem. Any advice?

Puppet Master Open Source version 3.7.4, Future Parser disabled.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2015-08-27 18:04:13 -0500

lavaman gravatar image

This is not the wrong way to resolve the issue.

Ordering of resources in puppet is based on tags. All resources in a class get tagged with the name of the class, so when you order a class, all resources with a tag of that class name get ordered. Subclasses do not tag their resources with the parent class name, so you must contain the subclasses in the parent class to be able to order things without resources from the subclasses "floating" out.

edit flag offensive delete link more

Comments

Very, very interesting, and now it makes sense! Thank you for that. Do you know if this behaviour is by design? Someone like me wanting to ensure that all the classes in a module are completed before some other class has to fork and refactor those modules? Is this the same in Puppet 4?

Chris McKeown gravatar imageChris McKeown ( 2015-08-27 18:26:58 -0500 )edit

It is by design to make the layout and use of modules as flexible as possible. The trend now is to make modules more data-driven, which allows for the encapsulation you're after, but there are many modules in heavy use that weren't written that way (like puppetlabs-apache).

lavaman gravatar imagelavaman ( 2015-08-28 14:45:55 -0500 )edit

Not sure how future parser affects this yet.

lavaman gravatar imagelavaman ( 2015-08-28 14:46:09 -0500 )edit

@lavaman can you elaborate on the 'data driven' design of modules (any examples?) and how that improves encapsulation? Thanks for your responses!

Chris McKeown gravatar imageChris McKeown ( 2015-08-28 15:03:20 -0500 )edit

Data driven means that all the config can be passed via the main class. In the puppetlabs-apache module, the main class only handles global configs. You have to write code to install mods and vhosts. This nginx module is a good example of a data driven module:

lavaman gravatar imagelavaman ( 2015-08-28 18:19:56 -0500 )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

Stats

Asked: 2015-08-26 06:10:33 -0500

Seen: 657 times

Last updated: Aug 27 '15