Search code examples
puppet

Puppet: declare resource without containment


Puppet will contain all defined types declared inside another defined type (or class). As far as I understand, this implies that any declared source will depend on the container. This will result in a dependency loop:

define user {
}
define bar {
  user { $name: }
  ->
  Bar[$name]
}

bar { 'foo': }
Error: Could not apply complete catalog: Found 1 dependency cycle:
(User[foo] => Bar[foo] => User[foo])

Is there any way to avoid this? I ahve one specific instance where I would prefer that when Bar[$name] is declared, User[$name] be declared as well, but have Bar[$name] depend on User[$name], not the other way around. Basically the same behavior as require, but for a defined type dependency.

Is there any way to accomplish this or is the only solution to have the manifest declaring Bar[$name] declare User[$name] as well (and then add the dependency on either the body of bar or in the declaring manifest?


A more realistic example:

define servize {}
define appserver {
  user { $name: }
  ->
  servize { $name: }
}

appserver { 'app': }

# the deploy application needs a directory owned by itself on startup
file { '/tmp/foobar':
  ensure => directory,
  owner  => 'app', # auto-require
}
->
Appserver['app']

Solution

  • First of all, please do not redefine built-in types. List of all built-in types: https://docs.puppetlabs.com/references/latest/type.html.

    If you have only one specific instance where $Bar[$name] depends on User[$name] you can remove user from bar definition and create ordered_bar

      define ordered_bar {
        user { $name: }
        ->
        bar {$name : }
      }
    

    That you only need to create an instance of ordered_bar.
    Please also read document about resource ordering in puppet: https://docs.puppetlabs.com/learning/ordering.html