Puppet does not directly support automatic declaration of parent directories, but it should not be too hard to implement using (again) a defined type. Something along these lines could probably be made to work:
define mymodule::recursive_file ($ensure => 'directory') {
$parent = regsubst($title, '^(.*)/[^/]+$', '\1')
file { $title: ensure => $ensure }
if $parent {
mymodule::recursive_file { $parent: }
}
}
You then use it in any class or definition, like so:
mymodule::recursive_file { '/grandparent/parent/file':
ensure => 'file'
}
That could be gussied up with additional attributes (mode, owner, etc.). The problem with that is it easily lends itself to creating duplicate declarations. Consider:
file { '/etc': ensure => 'directory' }
mymodule::recursive_file { '/etc/somepackage/somepackage.conf':
ensure => 'file'
}
You end up with File['/etc'] being declared twice, which Puppet will not accept.
Using an Exec to run 'mkdir -p' is in some ways better, but in other ways worse. It reduces your exposure to duplicate declaration issues, but at the price of exposing you to the possibility of an inconsistent catalog. Consider this, for example:
exec { 'mkdir -p /etc/somepackage':
creates => '/etc/somepackage'
}
->
file { '/etc/somepackage/somepackage.conf':
ensure => file
}
[... somewhere else ...]
file { '/etc/somepackage':
ensure => 'absent'
}
That still suffers from the problem that you are attempting to manage the same physical resource (directory /etc/somepackage) via two different Puppet resources, but Puppet can no longer recognize the problem because you have disguised it. Your catalog will be compiled, but Puppet cannot reliably apply it because it is internally inconsistent.
If you are careful to avoid inconsistencies then you can nevertheless make something like that work for you, but in that case you are on your own.
The alternative, and in many respects the true Puppet way, is to explicitly manage those files and directories you intend to manage, and only those. Remember always that building Puppet manifests is an exercise in modeling, not in scripting.
John