When managing multiple configuration files in Puppet, the traditional approach of declaring each file individually becomes cumbersome:
file { 'conf0':
path => '/etc/foo/conf0',
ensure => file,
source => 'puppet:///modules/module_name/etc/foo/conf0',
}
file { 'conf1':
path => '/etc/foo/conf1',
ensure => file,
source => 'puppet:///modules/module_name/etc/foo/conf1',
}
This method creates maintenance overhead and doesn't scale well with growing numbers of configuration files.
Puppet's file
resource type supports recursive directory management through the recurse
parameter:
file { '/etc/foo':
ensure => directory,
source => 'puppet:///modules/module_name/etc/foo',
recurse => true,
purge => false,
force => false,
}
This single resource declaration will:
- Create the /etc/foo directory if it doesn't exist
- Mirror all files from puppet:///modules/module_name/etc/foo
- Maintain the same directory structure as in the source
For more control over the recursive copy operation, consider these additional parameters:
file { '/etc/foo':
ensure => directory,
source => 'puppet:///modules/module_name/etc/foo',
recurse => remote,
recurselimit => 5,
purge => true,
force => true,
owner => 'root',
group => 'root',
mode => '0644',
}
Key parameters explained:
recurse => remote
: Only copy files from the Puppet masterrecurselimit
: Controls depth of recursionpurge
: Remove unmanaged files from directoryforce
: Allow purging of subdirectories
Here's a complete module example for managing Apache configuration files:
class apache::config {
file { '/etc/apache2':
ensure => directory,
source => [
"puppet:///modules/site_apache/${::fqdn}/etc/apache2",
"puppet:///modules/site_apache/etc/apache2",
"puppet:///modules/apache/etc/apache2"
],
recurse => remote,
recurselimit => 3,
purge => false,
owner => 'root',
group => 'root',
mode => '0644',
}
}
This implementation:
- Uses multiple source locations with failover
- Limits recursion depth to 3 levels
- Preserves existing unmanaged files
- Sets proper permissions
When implementing recursive directory management, watch for these potential problems:
- Permission errors: Ensure the Puppet agent can read the source files
- Performance impact: Large directories may slow catalog application
- File conflicts: Multiple sources may cause unexpected results
For debugging, use Puppet's --debug
flag to see file operations in detail.
When managing multiple configuration files in Puppet, declaring each file individually becomes tedious quickly. Consider this typical scenario:
file { 'conf0':
path => '/etc/foo/conf0',
ensure => file,
source => 'puppet:///modules/module_name/etc/foo/conf0',
}
file { 'conf1':
path => '/etc/foo/conf1',
ensure => file,
source => 'puppet:///modules/module_name/etc/foo/conf1',
}
Puppet's file
resource type has built-in capabilities for recursive directory management. Here's the solution you're looking for:
file { '/etc/foo':
ensure => directory,
recurse => true,
purge => false,
source => 'puppet:///modules/module_name/etc/foo',
owner => 'root',
group => 'root',
mode => '0644',
}
Let's break down the important parameters:
- recurse => true: Enables recursive directory copying
- purge => false: Prevents deletion of unmanaged files (set to true for strict mirroring)
- source: Points to the module's files directory structure
For more complex scenarios, consider these additional parameters:
file { '/etc/foo':
ensure => directory,
recurse => true,
recurselimit => 5, # Limit recursion depth
purge => true, # Remove unmanaged files
force => true, # Overwrite directories with files
ignore => ['temp*','.bak'], # Patterns to ignore
sourceselect => 'first', # Source selection behavior
show_diff => true, # Show file differences
}
You can combine multiple source locations:
file { '/etc/foo':
ensure => directory,
recurse => true,
source => [
'puppet:///modules/module_name/etc/foo',
'puppet:///files/global_configs/foo'
],
}
For systems requiring specific permissions:
file { '/etc/foo':
ensure => directory,
recurse => true,
source => 'puppet:///modules/module_name/etc/foo',
owner => 'appuser',
group => 'appgroup',
mode => '0750',
}
If files aren't being copied as expected:
- Verify the source path exists in your module's files directory
- Check Puppet server file permissions
- Test with
puppet agent --test --debug
for detailed output - Ensure the target directory isn't managed by another resource