In Puppet, both include
and class
declarations serve to incorporate classes into your manifests, but they have distinct behaviors:
# Class declaration style
class { '::ntp':
servers => ['pool.ntp.org'],
enable => true
}
# Include style
include '::ntp'
The fundamental difference lies in how Puppet processes these statements:
- Class declarations (
class {}
) are resource-like - they can declare parameters and can only be declared once per node - Include statements are include-like - they're idempotent (can be called multiple times) but can't pass parameters directly
# Good use case for class declaration
class { '::apache':
default_vhost => false,
mpm_module => 'prefork'
}
# Good use case for include
include '::stdlib'
include '::stdlib' # Safe to call multiple times
Class parameters can only be set via resource-like declarations or Hiera:
# This works
class { '::mysql::server':
root_password => 'secret',
override_options => {
'mysqld' => { 'max_connections' => '1024' }
}
}
# This won't work
include '::mysql::server'
# Then try to set params elsewhere - they'll be ignored
- Use
include
when you don't need to override default parameters - Use resource-like declarations when you need explicit parameter control
- Never mix both styles for the same class on one node
- For public modules, document whether parameters should be set via Hiera or direct declaration
# Good: Using include for utility classes
include '::firewall'
include '::stdlib'
# Good: Using class declaration for configured services
class { '::postgresql::server':
listen_addresses => '*',
manage_firewall => false,
require => Class['::firewall']
}
Remember that modern Puppet best practices often favor using Hiera for parameter assignment rather than direct resource-like declarations.
In Puppet, both include
and resource-like class declarations achieve class inclusion, but their behaviors differ significantly in three critical aspects:
# Style 1: include
include '::ntp'
# Style 2: Resource-like
class { '::ntp': }
The most important distinction lies in parameter handling. Resource-like declarations allow parameterization, while include
does not:
# Valid parameterized usage
class { '::ntp':
servers => ['pool.ntp.org', 'time.apple.com'],
}
# include CANNOT accept parameters
include '::ntp' # Works
include '::ntp' { servers => [...] } # Syntax error!
Resource-like declarations enforce singleton behavior (can't be declared twice), while include
is safely repeatable:
# Safe multiple includes
include '::apache'
include '::apache' # No conflict
# Dangerous duplicate declaration
class { '::mysql': }
class { '::mysql': } # Compilation error!
Resource-like declarations create explicit ordering relationships, while include
has more flexible evaluation:
# Resource-like creates ordering
Class['::ntp'] -> Package['curl']
# include requires explicit chaining
include '::ntp'
Package['curl']
Class['::ntp'] -> Package['curl']
- Use
include
for simple class inclusion without parameters - Prefer resource-like syntax when parameterization is needed
- For public modules, support both styles through params.pp pattern
- Never mix both styles for the same class in one catalog
# Ideal implementation example
class ntp (
Array[String] $servers = ['pool.ntp.org']
) {
# class body
}