Ask Your Question

Can I ensure profile ordering within a role using only includes?

asked 2017-04-17 22:42:28 -0600

wfsaxton gravatar image

updated 2017-04-18 10:12:30 -0600

According to Puppet's role best practices

1. The only thing roles should do is declare profile classes with include. Don’t declare any component classes or normal resources in a role.

Yet I find myself needing various profiles to be in a certain order and using include does not allow that. For example, I have a server the needs a base profile which configures LDAP/yum repos, a middle profile containing database software installation (which relies on LDAP/yum), and a final profile for creating a database schema (which relies on the database software to be installed). The only way I can see to do this is:

class role::mydbserver {
    class { 'profile::base': } ->
    class { 'profile::oracle::dbserver': } ->
    class { 'profile::mysoftware::dbmaster': }

Am I missing something?

EDIT: Okay, yeah this is really confusing because the Puppet documentation contradicts itself. In the first link, it explicitly says to ONLY use includes. But then, this example shows that in order to order profiles within a class, you should use "contain" followed by class ordering:

So is only using includes really a best practice or should that be ignored?

edit retag flag offensive close merge delete

3 Answers

Sort by » oldest newest most voted

answered 2017-04-18 08:03:39 -0600

DarylW gravatar image

updated 2017-04-18 10:44:08 -0600

I would be cautious of using run stages for ordering.... From the official docs...

Limitations and known issues

•In order to assign a class to a stage, you must use the resource-like class declaration syntax and supply the stage explicitly. You cannot assign classes to stages with the include function, or by relying on automatic parameter lookup from hiera while using resource-like class declarations.

•You cannot subscribe to or notify resources across a stage boundary.

•Classes that contain other classes (with either the contain function or the anchor pattern) can sometimes behave badly if declared with a run stage — if the contained class is only declared by its container, it will work fine, but if it is also declared anywhere outside its container, it will often create a dependency cycle that will prevent the involved classes from being applied.

Due to these limitations, stages should only be used with the simplest of classes, and only when absolutely necessary. Mass dependencies like package repositories are effectively the only valid use case.

I would use a combination of the direct class ordering (either directly using the 'require' and 'before' metaparms, how you showed it, or in a separate ordering section using with Class['class1'] -> Class['class2'] style with either class style or include style defines.

Showing the example using includes is as follows, which is slightly more verbose than your example, but allows multiple declarations of classes using the 'include' style

class role::mydbserver {
    include 'profile::base'
    include 'profile::oracle::dbserver'
    include 'profile::mysoftware::dbmaster'

    Class [ 'profile::base' ] ->
    Class [ 'profile::oracle::dbserver' ] ->
    Class [ 'profile::mysoftware::dbmaster' ]

Also be aware of how to properly create your profiles to limit 'float' that can occur.. ( ) ( ) ( )

edit flag offensive delete link more


The points you made here are clear and I agree, however in this case he is using them in the simplest of uses. Especially since he is using multiple profiles, there shouldn't be a need to cross the stage boundaries. Good points though.

puser gravatar imagepuser ( 2017-04-18 08:05:38 -0600 )edit

The main reason is that I don't think of a profile as 'the simplest of classes', they are a complex combination of multiple different classes. If anything uses a resource collector (gathering all Yumrepo before packages), that could easily break the stage limitations

DarylW gravatar imageDarylW ( 2017-04-18 09:25:53 -0600 )edit

So you are saying that using includes and then ordering them via "Class" isn't necessarily "cheating" the recommended best practice?

wfsaxton gravatar imagewfsaxton ( 2017-04-18 11:03:28 -0600 )edit

instead of include profile::mysoftware::dbmaster it would be class { 'profile::mysoftware::dbmaster': stage => first, } Puppet supports this functionality there are just caveats.

puser gravatar imagepuser ( 2017-04-18 12:02:23 -0600 )edit

answered 2017-04-18 03:37:47 -0600

that's because By default, Puppet applies resources in the order they’re declared in their manifest.

edit flag offensive delete link more

answered 2017-04-18 06:14:09 -0600

puser gravatar image

updated 2017-04-18 06:39:38 -0600

Check out Run stages.

stage { 'first':
  before => Stage['main'],
stage { 'last': }
Stage['main'] -> Stage['last']

Now you can do

 class { 'profile::base':
  stage => first,

 class { 'profile::oracle::dbserver':
  stage => main,

 class { 'profile::mysoftware::dbmaster':
  stage => last,

This will ensure the ordering that you want.

edit flag offensive delete link more


It doesn't look like your answer is any different than mine. Again, the best practice explicit calls for using includes which don't support ordering. I was asking whether or not there was a way to do this with only includes.

wfsaxton gravatar imagewfsaxton ( 2017-04-18 09:31:36 -0600 )edit

Don't use run stages for this. It will very quickly become unwieldy.

ramindk gravatar imageramindk ( 2017-05-16 23:14:42 -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: 2017-04-17 22:42:28 -0600

Seen: 273 times

Last updated: Apr 18 '17