Extra reading
Puppet type reference
https://docs.puppetlabs.com/references/latest/type.html
- very valuable lookup for type information
Puppet Visual Index
https://docs.puppetlabs.com/puppet/latest/reference/lang_visual_index.html
- great examples of code syntax
Puppet On The edge
http://puppet-on-the-edge.blogspot.be
- good for bleeding-edge information
Roles and Profiles
This looks at the modular association of nodes with classes via role definitions.
Roles
There's a module called "role". We can then reference the roles in sites.pp or nodes.pp.
A node can only be associated with one role.
node blah.company.com {
include role::prod-phoenix-webserver
}
Each role can declare multiple profiles
class role::webapp {
include profile::base
include profile::webserver
include profile::monitoring
}
Profiles
Function-specific wrappers to apply consistent settings across multiple nodes/environments
Inheritance
Inherited classes override all resources with whatever is defined in the inherited class
inherited params are used for attributes which will be used by any company/user (e.g. redhat package management is always yum, debian is always apt-get etc). Company/user-specific data should sit in hieradata
General rule of thumb, the only place you would use inheritance is for params.
Module Testing
RSPEC module tests generally don't mock external values such as hieradata lookups.
Unit Testing
require 'spec_helper'
describe('motd', :type => :class) do
let(:node) { 'testhost.example.com' }
describe 'when called with no parameters on redhat' do
let(:facts) { { :osfamily => 'Redhat' } }
it {
should contain_file('/etc/motd').with({
'ensure' => 'file',
'owner' => 'root',
}).with_content(/^Welcome to #{node}.*$/)
}
end
end
We can mock values such as facts (let(:facts) { { :osfamily => 'Redhat'} }
, etc to evaluate them against the puppet code.
Note - unless environment variables (node, facts etc) are explicitly defined in the rspec test, it will not be available for the test. The rspec test does not actually simulate the environment of the node on which it executes, it explicity follows the instructions in the test.
Some example output from a unit test (different to the above example) is below
[master]root@robbie:~/puppetcode/modules/apache # /opt/puppetlabs/puppet/bin/rake spec
/opt/puppetlabs/puppet/bin/ruby -I/opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-support-3.3.0/lib:/opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-core-3.3.2/lib /opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration\}/\*\*/\*_spec.rb --color
F
Failures:
1) apache when called with no parameters on redhat should contain File[apache_config] with ensure => "file" and source => "puppet:///modules/apache/Redhat.conf"
Failure/Error: should contain_file('apache_config').with({
expected that the catalogue would contain File[apache_config] with source set to "puppet:///modules/apache/Redhat.conf" but it is set to "puppet:///modules/apache/.conf"
# ./spec/classes/apache_spec.rb:16:in `block (3 levels) in <top (required)>'
Finished in 1.24 seconds (files took 0.8289 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/classes/apache_spec.rb:11 # apache when called with no parameters on redhat should contain File[apache_config] with ensure => "file" and source => "puppet:///modules/apache/Redhat.conf"
/opt/puppetlabs/puppet/bin/ruby -I/opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-support-3.3.0/lib:/opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-core-3.3.2/lib /opt/puppetlabs/puppet/lib/ruby/gems/2.1.0/gems/rspec-core-3.3.2/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration\}/\*\*/\*_spec.rb --color failed
Acceptance Testing
Validation that the end result meets the requirements of the puppet code.
"Beaker" is a recommended platform for acceptance testing, although difficult to use so be careful.
"serverspec" can be used to validate that the desired state has been achieved. To use serverspec:
- puppet agent -t
- cd (module); rake spec
Note - to properly test the puppet code, best to use a new server instance (e.g. a newly generated VM, docker container etc), to ensure you aren't generating false positives or false negatives from previous iterations of code execution.
mcollective
Used for initiating tasks (e.g. puppet runs) on remote systems. instead of scheduling it on each node's crontab, these tasks can be centrally batched/scheduled and executed using the mcollective system.
Puppet Enterprise - mcollective is set up for you
Puppet Opensource - you need to configure this manually
ActiveMQ is used for messaging
mco
is the mcollective admin client
mco ping
can be used to show which systems it can communicate with using mcollective (i.e. application-level ping)
mco rpc service apache stop
to stop apache
mco puppet stop
to stop the puppet client (this doesn't stop mcollective, just puppet)
mco package install sl
to install the steam locomotive package
You can also control which clients/nodes this applies to (i.e. default is to run it on all mcollective clients the system can connect to - this could be bad).