Forget Object Oriented Programming.
Class
, Module
, Inheritance
, the terminology sounds the same, but the meanings in Puppet are different. From slightly different to wildly different.
Trying to connect the Puppet meanings to the OOP meanings may just slow you down.
Relationships (require, notify etc) to a class extend to its resources, but not to its subclasses. So use the anchor pattern to extend them further to the subclasses:
class container { anchor { 'container:begin': before => Class['c1', 'c2'], } include c1 include c2 anchor { 'container:end': require => Class['c1', 'c2'], } }
Yes, it seems you have to list the contained classes thrice.
Basically a list.
foo = ['/tmp/foo', '/tmp/bar', '/tmp/baz'] notify{ "$foo[0]" }
Some resource attributes can be lists. Metaparameters take lists. Resource titles can be lists as well. In that case, multiple independent resources are defined, only differring from one another in their titles.
A property of a resource.
Specifies how a node should be configured.
A collection of resources, managed together as a single unit. Like this:
class ssh { package { 'openssh-server': ensure => present, } service { 'sshd': ensure => running, } }
Classes are the unit of software reuse, but for a single node, they can only be declared once.
Classes can be inherited:
class ssh { ... } class ssh::server inherits ssh { ... }
This is most only used with parameter classes
though.
There is no such things as C++'s late binding in Puppet.
The code of a class defines it.
A predefined, repeatable chunk of code, a bit like a user-provided resource. Could be compared to a C record.
define apache::vhost ( $docroot, $port, <snip> ) { file { "/etc/apache2/sites-available/${name}.conf" : ensure => 'present', owner => 'apache', <snip> } <snip> }
Defined types cannot be inherited
Including (or instantiating) a class in a host definition.
Note | |
---|---|
Including a class is the same as instantiating it with default parameters (or with none). And classes are singletons, so there cannot be multiple instantiations of any class inside the same node definition. |
Embedded RuBy Templating, used in puppet templates:
This is plain text <% This Ruby code is executed %>
Modifiers can be used with then <% %> delimiters of the Ruby tags:
<%= - replace tag with its output
<%# - suppress all output in this tag
<%% %%> - literal <% and %>
<%- -%> - suppress leading resp. trailing whitespace
Variables, out-of-scope variables:
<%= @myname %> <%= scope.lookupvar ('::operatingsystem') %>
Conditionals, testing for variable being defined:
<% if @myvar %> myvar has value <%= @myvar %> <% end %>
Loop:
<% @values.each do |val| %> Some text <% val %> <% end %>
Resources that are reported back to the master, and become available on all hosts.
Data about the state of a node. May or may not be sent to the master.
Custom fact in $module/lib/facter/krb_realm.rb
:
# krb_realm.rb Facter.add("krb5_realm") do setcode do Facter::Util::Resolution.exec('sed -n "/^\[libdefaults\]/,/^\[.*\]/ s/[\ \t]//g ; { /^default_realm=/ s/[^=]*=//g p }" /etc/krb5.conf') end end
As in programming languages. Executed on Puppet Server. Come in two flavours. statement:
notification("${::operatingsystem} not supported by this module")
and rvalue:
template('apache/apache.conf')
Examples of statement functions: tag, include, realize, require, fail. Examples of rvalue functions: defined, file, generate, tagged, regsubst, sha1.
Perl-like:
$surnames = { donald => 'duck', mickey => 'mouse' } notify {" $surnames['donald'] "}
Arrays and hashes can be nested to give arbitrarily complex and hard to navigate data structures.
Using the function create_resources ('user', $users), a hash of the pattern
$users = { root => { uid = 0, gid = 0, home = '/root', ... } joe => { uid = 3000, gid = 3000, home = '/home/joe', ... } }
can be used to instantiate many resources from a single data structure. M.m. for other resource types. Another suitable data structure, the resource defaults, may be used.
A server that compiles catalogs for nodes.
Not-quite-a-parameters, work with any resource type (hence the 'meta'). Ordering metaparameters come in four flavours:
require
- if X requires Y, Y will be handled before X
before
- if X is before Y, X will be handled before Y (duh)
subscribe
- if X subscribes to Y, then when Y causes change, X will be refreshed
subscribe
implies require
notify
- if X notifies Y, then when X causes change, Y will be refreshed
notify
implies before
Other metaparameters:
alias
- to create an alternative name for the resource
audit
noop
- tells the resource not to do anything
loglevel
- values debug, info, notice, warning, err, alert, emerg, crit, verbose
tag
notify
- to send a message to the logs. This is the odd man out if you ask me.
filebucket
- storage to put other resources in an retrieve them from
E.g. to back files up before they get overwritten.
schedule
- to prevent other resources from being applied too often.
A resource type that accepts a type as its namevar, and propagate its other parameters to all other resources of that type, except for some that are used to limit the resources that fall under its working. Examples:
resources { 'resource title': name => # (namevar) The name of the type to be... purge => # Purge unmanaged resources. This will delete any unless_system_user => # This keeps system users from being purged. By... # ...plus any applicable metaparameters. }
Warning | |
---|---|
Sometimes used as a confusing term for metaparameter. Confusing enough even without that. |
A directory containing related configuration code: classes, files, templates, Puppet extensions, perhaps even more.
Puppet autoloads classes and converts paths to namespaces.
A class found in ${MODULEPATH}/apache/manifests/server/https.pp
would automatically be called apache::server::https
.
An exception is the class apache
itself. It would be looked for in ${MODULEPATH}/apache/manifests/init.pp
.
Special attribute that identifies a resource to the provider. To Puppet, a resource is identified by its title.
The namevar is defined per type.
For package
, it's name
:
package { 'ssh': name => 'openssh', ensure => 'present', }
This way, Puppet can call the class by its title, which need not be a variable, but it can have different names to different providers of 'package'.
A machine, a computer.
Nodes may inherit:
node 'base'{ ... } node 'particular' inherits 'base' { ... }
A description of the desired state of a node. May contain multiple classes. Example:
node 'vhost2.xennet' { include ssh include defaultusers }
Class that takes parameters:
class ssh ( $port = 22, $run_server = true ) { file { '/etc/ssh/sshd_config': ... } ... }
... then in the node definition, put:
class { 'ssh': $port = 23 }
Note | |
---|---|
There cannot be more than one instance of a parameterized class per node. |
The interface between the underlying OS and the Puppet resource type. E.g. 'yum' and 'apt' are providers for 'package'.
An event, particularly associated with changes applied.
See Also Metaparameter .
Building block of an OS that can be managed by Puppet. E.g. files, users, services.
A resource is declared like this:
package { 'emacs': ensure => present, }
Where the type of resource is 'package', its name is 'emacs' and the attribute 'ensure' has value 'present'.
When referencing an existing (already defined) resource, capitalize the first character, and put the title in square brackets:
require Package['emacs']
Resources can be listed:
puppet resource user root
user { 'root':
ensure => 'present',
comment => 'root',
gid => '0',
home => '/root',
password => '$6$eCzPTp2g$ZGq1d7K29AJQaixSrBlIlu7GMY7vBhHkHQD2j47DdYVP3k3mkFpZiEV.uhnTeMigKxAIjhJx0jlbeJ3nUZ2Ph1',
password_max_age => '99999',
password_min_age => '0',
shell => '/bin/bash',
uid => '0',
}
Default value(s) for one type of resource in a class, like so:
File { owner => 'www-data', group => 'www-data', mode => '0644', }
The area of code in which a variable is known. The '::' is the scope operator. There's top scope (reached by the empty string), node scope and class scope.
Closer scope overrides broader scope. Facts are 'global variables', which just means they have top scope. They can still be overridden with more local scope.
One of the three conditional expressions.
user { 'apache', name => $::operatingsystem ? { 'ubuntu' => 'www-data', default => 'apache', }, }
If the selector gives its value to a variable, it is called an out-selector
, otherwise it's an in-selector
.
Like in programming languages, but once determined, cannot be reassigned. The syntax is with a dollar sign, and as in e.g. many shell scripts, double quotes do variable substitution while single quotes do not. According to some docs, curlies ('{''}') should be used to prevent the wrong part of the string from being substituted. But in practice, Puppet often fails to parse the curlies.
Resource titles can be variables. Resource attributes can (of course) be variables.
Resource with delayed instantiation: is sent to the client only when explicitly realized. Offers a way to define resources in a single place, then use them in multiple classes.