mattwise
mattwise

Reputation: 1506

How do I make a puppet class dependent on all of the resources it defines?

I am working on a rather large and complicated puppet module, and I ran into an issue where declaring a dependency on a class does not translate to a dependency on class resources defined in that class. I have created an example.

node default {
  notify {'This is my notification':
    require => Class['big_class'],
  }
  class {'big_class':}
}

class big_class {
  notify {'This is my big class':}
  class {'little_class':}
}

class little_class{
  notify {'This is my little class':}
  class {'smallest_class':}
}

class smallest_class {
  notify {'This is my smallest class':}
}

My desired behavior is for smallest, little, and big to all resolve before the notification. But Puppet doesn't work this way. The result of the run is as follows:

Notice: This is my little class
Notice: /Stage[main]/Little_class/Notify[This is my little class]/message: defined 'message' as 'This is my little class'
Notice: This is my big class
Notice: /Stage[main]/Big_class/Notify[This is my big class]/message: defined 'message' as 'This is my big class'
Notice: This is my notification
Notice: /Stage[main]//Node[default]/Notify[This is my notification]/message: defined 'message' as 'This is my notification'
Notice: This is my smallest class
Notice: /Stage[main]/Smallest_class/Notify[This is my smallest class]/message: defined 'message' as 'This is my smallest class'
Notice: Finished catalog run in 0.05 seconds

The smallest class resolved after the 'This is my notification' even though it is defined effectively 'within' a requirement on the notification. What is the best practice for handling this type of senario? If this is the desired behavior, is there a way to declare that resources defined within a class are requirements of that class? Do all of the resources inside of class class_name need to have a meta-parameter before => Class['class_name'],?

Edit: The following results in puppet complaining about dependency cycles.

class smallest_class {
  notify {'This is my smallest class':
    before => Class['smallest_class'],
  }
}

Upvotes: 1

Views: 1234

Answers (1)

ruckc
ruckc

Reputation: 543

So, generating a dot graph over your manifest, we can see there are no actual dependencies between classes.

There are a few options to address this.

  1. Create precise dependencies within the classes between the notify statements (non-ideal).
  2. Use run stages
  3. Use puppetlabs-stdlib anchor pattern
  4. If running puppet >= 3.4, they have a new contain function

Upvotes: 3

Related Questions