Include vs. Class Declaration in Puppet: Key Differences and When to Use Each


2 views

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
}