On Github catalyst-training / puppet-intermediate
Presented by Evan Giles / Alex Lawn
http://PRESENTER_IP/files/puppet_int_lab_nodes.ova
You can view these slides at http://catalyst-training.github.io/puppet-intermediate/
There'll be quite a lot of copy/pasting coming up, so take the time to load them up now...
puppet# rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm puppet# yum install puppet-server
node-a# rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm node-a# yum install puppet
node-b# rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm node-b# yum install puppet
node-d# wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb node-d# dpkg -i puppetlabs-release-trusty.deb node-d# apt-get update node-d# apt-get install puppet node-d# service puppet stop
puppet# chkconfig puppetmaster on puppet# /etc/init.d/puppetmaster start
Repeat for all nodes:
node-x# puppet agent -tv --waitforcert=300 puppet# puppet cert --list puppet# puppet cert --sign node-x.localdomain node-x# puppet agent -tv
/etc/puppet/manifests/site.pp:
import 'nodes.pp'
/etc/puppet/manifests/nodes.pp:
node 'node-a.localdomain' { } node 'node-b.localdomain' { } node 'node-d.localdomain' { }
<html> <head> <title>Test Page</title> </head> <body> <h1>Hello World!</h1> </body> </html>
package { 'httpd': ensure => 'installed', } user { 'web': ensure => present, managehome => true, } file { "/var/www/index.html": ensure => present, owner => "www", group => "apache", mode => "444", source => "puppet:///modules/web/var/www/index.html", require => [ User["web"], Package['httpd'], ], } service { 'httpd': enable => true, ensure => 'running', require => [ Package["httpd"], File["/etc/httpd/conf/httpd.conf"] ], } file { "/etc/httpd/conf/httpd.conf": ensure => present, owner => "www", group => "apache", mode => "444", source => "puppet:///modules/web/etc/httpd/conf/httpd.conf", require => User["web"], notify => Service["httpd"], }
if $osfamily == 'RedHat' { $http_pkg = 'httpd' } elsif $osfamily == 'Debian' { $http_pkg = 'apache2' } else { warning( 'OS not supported.' ) }
$http_pkg = $osfamily ? { 'RedHat' => 'httpd', 'Debian' => 'apache2', }
notify { 'Whassup my homies.': }
notify { "http_pkg is $http_pkg": }
source => [ "puppet:///modules/web/etc/httpd/conf/httpd.conf-$osfamily", "puppet:///modules/web/etc/httpd/conf/httpd.conf", ],
We must ensure that one option ALWAYS matches otherwise the catalogue compilation will fail.
unless $fqdn == 'node-d.localdomain' { package { 'tree': ensure => 'installed', } }
/etc/puppet/puppet.conf
[master] environmentpath = $confdir/environments
A new directory structure:
mkdir /etc/puppet/environments/{production,dev} mv /etc/puppet/manifests /etc/puppet/environments/production/ mv /etc/puppet/modules /etc/puppet/environments/production/- This 'production' is the default...
Place node-b in the dev environment: /etc/puppet/puppet.conf (on node-b)
[agent] environment = dev
$http_port = $environment ? { 'production' => '80', 'dev' => '8080', }
content => template("httpd/httpd.conf.erb"),
Listen <%= @http_port %>
class web { . . . } class web::infrastructure { . . . } class web::application { . . . }
include web::infrastructure include web::application
include web::infrastructure class { 'web::application': require => Class['web::infrastructure'], }
<%= scope['web::http_port'] %>
node-a# puppet-agent -tv --tags web node-a# puppet-agent -tv --tags note
class 'web::application' { tag 'app' }
node-a# puppet-agent -tv --tags app
$hour = fqdn_rand( max - min ) + min
<% if @osfamily == 'Debian' %> I'm a bit different to the others. <% end %>
(Because we are diligent at indenting.)
<%- if @osfamily == 'Debian' %> I'm a bit different to the others. <% end %>
$colours = [ 'red', 'yellow', 'pink', 'green', 'purple', 'orange', 'blue', ]
I can sing a rainbow: <% @colours.each do |c| %> Colour: <%= c %> <% end %>
I can sing a rainbow:
<% @colours.each do |c| -%> Colour: <%= c %> <% end -%>
<% # Establish an empty array. @cmd = [] # Push a string onto the array. @cmd << 'mk.rainbow' # Add my commandline parameters for colours (interpolate quotes). @colours.each do |c| cmd << --include cmd << "'#{c}'" end -%> <%= @cmd.join(' ') %>
erb -P -x -T '-' mytemplate.erb | ruby -c
environments/XXX/modules/web/lib/facter/pkg_count.rb
Facter.add( 'pkg_count' ) do setcode 'rpm -qa | wc -l' end- This magically deploys the fact to the nodes - you need to run facter -p to see it
environments/dev/web/lib/facter/pkg_count.rb
Facter.add( 'pkg_count' ) do confine :kernel => "Linux" setcode 'rpm -qa | wc -l' end
environments/dev/web/lib/facter/pkg_count.rb
Facter.add( 'pkg_count' ) do confine :kernel => "Linux" setcode do osfamily = Facter.value(:osfamily) case osfamily when 'RedHat' Facter::Core::Resolution.exec('rpm -qa | wc -l') when 'Debian' Facter::Core::Resolution.exec('dpkg -l | wc -l') end end
On the client node: /etc/facter/facts.d/lab_facts.txt
product_key=DIndiwnsklIndk thingee=mawhatsit
facter --debug
class web::infrastructure ( $http_port = '80', $server_name, ) { . . . }
node 'node-a.localdomain' { class { web::infrastructure: server_name => "I am node A.", } } node 'node-a.localdomain' { class { web::infrastructure: server_name => "I am node B.", } }
node 'node-a.localdomain' { class { web::infrastructure: server_name => "I am node A.", } class { web::application: require => Class['web::infrastructure'], } } node 'node-a.localdomain' { class { web::infrastructure: server_name => "I am node B.", } class { web::application: require => Class['web::infrastructure'], } }
class web ( $http_port = '80', $server_name, ) { class { 'web::infrastructure': server_name => $server_name, http_port => $http_port, } class { 'web::application': require => Class['web::infrastructure'], } }
class web::infrastructure ( $http_port = '80', $server_name, ) { . . . }
class web::infrastructure::params { $http_port = '80' $server_name = $::fqdn # Could include package selection logic here. } class web::infrastructure ( $http_port = $web::infrastructure::params::http_port, $server_name = $web::infrastructure::params::server_name, ) inherits web::infrastructure::params { . . . }
node 'node-a.localdomain': class { 'web::infrastructure::params': server_name = "I am node A." } class { 'web': } }
class dudes { define dude ( $ensure, $dude_meter = true, ) { user { $name: ensure => $ensure, managehome => true, } $ensure_dude_meter = $dude_meter ? { true => 'present', false => 'absent', } file { "/home/$name/dude_level.txt": ensure => $ensure_dude_meter, owner => $name, group => 'root', mode => '444', content => fqdn_rand(10, $name), } } dude { 'dude1': ensure => 'present', } dude { 'dude2': ensure => 'present', } dude { 'dude3': ensure => 'present', dude_meter => false, } }
puppet# yum -y install httpd mod_ssl mod_passenger puppet# chkconfig puppetmaster off puppet# /etc/init.d/puppetmaster stop puppet# mkdir -p /srv/rack/puppetmasterd/{tmp,public} puppet# cp /usr/share/puppet/ext/rack/config.ru /srv/rack/puppetmasterd puppet# chown -R puppet:puppet /srv/rack/puppetmasterd
/etc/httpd/conf.d/passenger.conf:
# And the passenger performance tuning settings: PassengerHighPerformance On # Set this to about 1.5 times the number of CPU cores in your master: PassengerMaxPoolSize 12 # Recycle master processes after they service 1000 requests PassengerMaxRequests 1000 # Stop processes if they sit idle for 10 minutes PassengerPoolIdleTime 600
/etc/httpd/conf.d/puppetmasterd.conf:
Listen 8140 <VirtualHost *:8140> SSLEngine On SSLProtocol All -SSLv2 SSLCipherSuite HIGH:!ADH:RC4+RSA:-MEDIUM:-LOW:-EXP SSLCertificateFile /var/lib/puppet/ssl/certs/puppet.<domain>.pem SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet.<domain>.pem SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem SSLVerifyClient optional SSLVerifyDepth 1 SSLOptions +StdEnvVars +ExportCertData # These request headers are used to pass the client certificate # authentication information on to the puppet master process. RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e DocumentRoot /srv/rack/puppetmasterd/public <Directory /srv/rack/puppetmasterd/> Options None AllowOverride None Order allow,deny Allow from all </Directory> </VirtualHost>
puppet# /etc/init.d/httpd start puppet# chkconfig httpd on node-a# puppet agent -tv
yum -y install http://yum.theforeman.org/releases/1.1/el6/x86_64/foreman-release.rpm yum -y install foreman-installer ruby /usr/share/foreman-installer/generate_answers.rb
open source technologists