Puppet Book Pro second edition

Chapter 1 Getting Started

in the first pages there are some interesting things about definition of puppet how works with client server mode.

after install the puppet master in puppet.conf file must be

[master]
certname=puppet.example.c

create this host in a dns server on in

# /etc/hosts
127.0.0.1 localhost
192.168.0.1 puppet.example.com puppet

in the file site.pp are described where puppet find the configuration file

root@ops-master:/etc/puppet/manifests# ls
development  production  site.pp  test
root@ops-master:/etc/puppet/manifests# cat site.pp 
import 'production/*'
import 'development/*'
import 'test/*'

this is the firewall configuration needed

-A INPUT -p tcp -m state --state NEW -s 192.168.0.0/24 --dport 8140 -j ACCEPT

the deamon is

service puppetmaster start

the log files for this are /var/log/messages on Red Hat-based hosts and /var/log/daemon.log on Debian and Ubuntu hosts.

is possible at the starup configure the ssl

you can run puppet instead like a daemon with command

puppet master --verbose --no-daemonize

Connecting Our First Agent

install the program in the client machines
and runs with command line

puppet agent --server=puppet.example.com --no-daemonize --verbose
info: Creating a new certificate request for node1.example.com
info: Creating a new SSL key at /var/lib/puppet/ssl/private_keys/node1.example.com
.pem
warning: peer certificate won't be verified in this SSL session
notice: Did not receive certificate

we can specify the server either in the config file /etc/puppet/puppet.conf

[main]
server=puppet.example.com

to complete the connection of the client connect to the server

puppet# puppet cert --list
node1.example.com

puppet# puppet cert --sign node1.example.com
Signed node1.example.com

you can also enable “autosign” mode. In this mode, all incoming connections from specified IP addresses or address ranges are automatically signed.

On the client, two minutes after we’ve signed our certificate, we should see the following entries (or you can stop and restart the Puppet agent rather than waiting two minutes):

notice: Got signed certificate
notice: Starting Puppet client version 2.6.1

if appears

err: Could not retrieve catalog: Could not find default node or by name with 
'node1.example.com, node1' on node node1.example.com

is because there is not configuration for the client on the server machines.

If client and server are not synchronized you can have some problems with the authentication of the certificates.

Creating Our First Configuration

in file site.pp we can have

import 'nodes.pp'
$puppetserver = 'puppet.example.com'
import 'nodes/*'
import 'classes/*'

Puppet manifest files are traditionally suffixed with .pp. If your manifest file has the .pp suffix, you can
drop the suffix when importing files.

$puppetserver statement sets a variable. In Puppet, configuration statements starting with a
dollar sign are variables used to specify values that you can use in Puppet configuration.

with single quote the variable will defined with double quote no more details here http://docs.puppetlabs.com/guides/more_language.html#quoting.

define an agent

touch /etc/puppet/manifests/nodes.pp.
node 'node1.example.com' {
include sudo
}

or with a reqular expression
node /^www\d+\.example\.com/ {
include sudo
}

example.com with the hostname www1, www12,
www123, etc.

Creating our first module

A single module would contain everything required to configure a particular application.
Each module needs a specific directory structure and a file called init.pp

to use module in a server it's necessary in puppet.conf

[main]
moduledir = /etc/puppet/modules:/var/lib/puppet/modules:/opt/modules

the first two directory are by default

create the module

# mkdir –p /etc/puppet/modules/sudo/{files,templates,manifests}
# touch /etc/puppet/modules/sudo/manifests/init.pp

initi.pp

class sudo {
  package { sudo:
      ensure => present,
  }
  if $operatingsystem == "Ubuntu" {
    package { "sudo-ldap":
    ensure => present,
    require => Package["sudo"],
  }
  }
  file { "/etc/sudoers":
     owner => "root",
     group => "root",
     mode => 0440,
     source => "puppet://$puppetserver/modules/sudo/etc/sudoers",
     require => Package["sudo"],
}
}
nop parameter
puppet# puppet agent --server=puppet.example.com --no-daemonize --verbose --onetime

with the command upstairs you see at console whats happens, but with —noop mode runs Puppet but doesn’t make any changes on your host
to view the logs without apply changes

Chapter 2 Building Hosts with Puppet

Configuring Nodes

many ways to define a node
single file node.pp

node 'puppet.example.com' {
}
node 'web.example.com' {
}
node 'db.example.com' {
}
node 'mail.example.com' {
}

node similars

node 'web1.example.com', 'web2.example.com', 'web3.example.com' { }

node similars with regexp

node /^web\d+\.example\.com$/ { }

default node, if no other can be choosen

node default {
include defaultclass
}

Node Inheritance Structure

node base {
include
}
sudo, mailx
node 'web.example.com' inherits base {
...
}

Inheritance is cumulative and you can specify an inheritance structure

Variable Scoping

you must define the variable one time you can't rewrite

class ssh_sudo {
$package = "openssh"
package { $package: ensure => installed }

Creating a module to Manage SSH

# ssh/manifests/install.pp
class ssh::install {
package { "openssh":
ensure => present,
}
}

# ssh/manifests/config.pp
class ssh::config {
file { "/etc/ssh/sshd_config":
ensure = > present,
owner => 'root',
group => 'root',
mode => 0600,
source => "puppet:///modules/ssh/sshd_config",
require => Class["ssh::install"],
notify => Class["ssh::service"],
}
}

#ssh/manifests/service.pp
class ssh::service {
service { "sshd":
ensure => running,
hasstatus => true,
hasrestart => true,
enable => true,
require => Class["ssh::config"],
}
}

#ssh/manifests/init.pp
class ssh {
include ssh::install, ssh::config, ssh::service
}

We use the :: namespace syntax as a way to create structure and organization in our modules. The ssh prefix tells Puppet that each class belongs in the ssh
module, and the class name is suffixed.

use a selector

install the class look at the o.s.

package { "ssh":
name => $operatingsystem ? 
/(Red Hat|CentOS|Fedora|Ubuntu|Debian)/ => "openssh-server",
Solaris => "openssh",
},
ensure => installed,
}

if the o.s. is Red Hat or Fedora or Ubuntu or Debian install openssh-server if it's Solaris install openssh
it' possible specify a default => "ssh",
alias

we can define

file { "passwd":
path => "/etc/passwd",
...
}

we can now refer to this resource as File["passwd"] as an aliased
mode parameter
class ssh::params {
case $operatingsystem {
Solaris: {
$ssh_package_name = 'openssh'
}
/(Ubuntu|Debian)/: {
$ssh_package_name = 'openssh-server'
}
/(RedHat|CentOS|Fedora)/: {
$ssh_package_name = 'openssh-server'
}
}
}

and we can include with
class ssh {
include ssh::params, ssh::install, ssh::config, ssh::service
}

and use with
package { $ssh::params::ssh_package_name:
ensure => installed,
}

in this way we used the variable ssh_package_name of the class ssh::params
config class e metaparameters
class ssh::config {
file { "/etc/ssh/sshd_config":
ensure = > present,
owner => 'root',
group => 'root',
mode => 0440,
source => "puppet:///modules/ssh/sshd_config",
require => Class["ssh::install"],
notify => Class["ssh::service"],
}
}

there are two metaparameters, require and notify, they interact with other class and it's convenient interact with a class e not with a resource of a class because in this way is more easily change the class.
  • require says before install ssh and after manage the config file
  • notify create a relation if the config file will be changed , the service will be notify and in this case restarted to take the new configuration
ssh service class
class ssh::service {
service { $ssh::params::ssh_service_name:
ensure => running,
hasstatus => true,
hasresstart => true,
enable => true,
require => Class["ssh::config"],
}
  • ensure specifies whether the service is running or stopped
  • enable specifies whether it is to be started at boot

Creating a Module to Manage Postfix

class postfix::config {
File {
owner => "postfix",
group => "postfix",
mode => 0644,
}
file { "/etc/postfix/master.cf":
ensure = > present,
source => "puppet:///modules/postfix/master.cf",
require => Class["postfix::install"],
notify => Class["postfix::service"],
}
file { "/etc/postfix/main.cf":
ensure = > present,
content => template("postfix/main.cf.erb"),
require => Class["postfix::install"],
notify => Class["postfix::service"],
}
}

File type is called a resource default. Resource defaults only apply to the current scope, but you
can apply global defaults by specifying them in your site.pp file

with this syntaxt

class postfix::config {
$require = Class["postfix::install"]
...
}

we can remove all require => Class["postfix::install"] because become the default of the class

to fill a file with a template content we have used

content => template("postfix/main.cf.erb"),

it knows in the module postifx in the directory template in the file main.cf.erb

THE REQUIRE FUNCTION

The require function works just like the include function except that it introduces some order to the inclusion of resources. With the include function, resources are not included in any sequence.

class ssh {
require ssh::params
include ssh::install, ssh::config, ssh::service
}

the contents of ssh::params would be processed before any other includes or resources in the ssh
class. BUT IT'S NOT A RECOMMENDED USE can introduce cyclical dependencies.
It’s cleaner, more elegant and simpler to debug if you use metaparameters to specify the relationships between resources.

in the template file you can specify

myhostname = <%= hostname %>
mydomain = <%= domain %>
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

two ERB variables that use Facter facts to correctly populate the file. Each variable is enclosed in <%= %>

You can easily check the syntax of your ERB templates for correctness using the following command:

erb - x -T '-' mytemplate.erb | ruby –c

CLASS INHERITANCE

continue pag 52

Salvo diversa indicazione, il contenuto di questa pagina è sotto licenza Creative Commons Attribution-ShareAlike 3.0 License