Weitere Module- / Manifestbeispiele

Mit folgendem Module kann ein User incl. Gruppe und Gruppenzugehörigkeit angelegt werden. Außerdem wird ihm direkt ein ssh-key hinterlegt:
Zuerst muss der entsprechende Ordner angelegt werden:

class user_shellmann {
        group { 'shellmann':
                ensure => present,
                gid => 1000
        }
        user { 'shellmann':
                ensure => present,
                require    => Group['shellmann'],
                gid => 'shellmann',
                groups => ['sudo', 'cdrom', 'floppy', 'audio', 'dip', 'video', 'plugdev', 'netdev', 'bluetooth',],
                shell => '/bin/bash',
                home => '/home/shellmann',
                purge_ssh_keys => true,
        }
        ssh_authorized_key { 'private':
                user => 'shellmann',
                type => 'ssh-rsa',
                key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDSNp/edM111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
        }
}

Damit man dem Benutzer z.B. eigene Config Dateien zur Verfügung zu stellen, sollte vorher der Fileserver in Puppet konfiguriert werden.

# This file consists of arbitrarily named sections/modules
# defining where files are served from and to whom

# Define a section 'files'
# Adapt the allow/deny settings to your needs. Order
# for allow/deny does not matter, allow always takes precedence
# over deny
[dotfiles]
        path /mnt/puppet_dotfiles
        allow puppetclient.home

[plugins]
#  allow *.example.com
#  deny *.evil.example.com
#  allow 192.168.0.0/24

Über die allow Direktive kann man den Zugriff reglementieren. Bisher habe ich noch keine Möglichkeit gefunden ganze Netze frei zugeben. Im Netz taucht hier oft allow_ip auf. Dies funktionierte bei meinen Tests aber genau so wenig wie allow.
Die Manifest wird dann wie folgt erweitert:

class user_shellmann {
        group { 'shellmann':
                ensure => present,
                gid => 1000
        }
        user { 'shellmann':
                ensure => present,
                require    => Group['shellmann'],
                gid => 'shellmann',
                groups => ['sudo', 'cdrom', 'floppy', 'audio', 'dip', 'video', 'plugdev', 'netdev', 'bluetooth',],
                shell => '/bin/bash',
                home => '/home/shellmann',
                purge_ssh_keys => true,
        }
        ssh_authorized_key { 'private':
                user => 'shellmann',
                type => 'ssh-rsa',
                key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDSNp/edM111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
        }
        file {'/home/shellmann/.vimrc':
                ensure => 'file',
                mode => '0660',
                owner => 'shellmann',
                group => 'shellmann',
                source => 'puppet:///dotfiles/user_shellmann/.vimrc',
        }
}

In meiner persönlichen vim config sind ein paar Ordner definiert, die noch nicht existieren. Auch dabei kann uns puppet helfen.

class user_shellmann {
        group { 'shellmann':
                ensure => present,
                gid => 1000
        }
        user { 'shellmann':
                ensure => present,
                require    => Group['shellmann'],
                gid => 'shellmann',
                groups => ['sudo', 'cdrom', 'floppy', 'audio', 'dip', 'video', 'plugdev', 'netdev', 'bluetooth',],
                shell => '/bin/bash',
                home => '/home/shellmann',
                purge_ssh_keys => true,
        }
        ssh_authorized_key { 'private':
                user => 'shellmann',
                type => 'ssh-rsa',
                key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDSNp/edM111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
        }
        file {'/home/shellmann/.vimrc':
                ensure => 'file',
                mode => '0660',
                owner => 'shellmann',
                group => 'shellmann',
                source => 'puppet:///dotfiles/user_shellmann/.vimrc',
        }
        file { '/home/shellmann/.vim':
                ensure => 'directory',
                owner  => 'shellmann',
                group  => 'shellmann',
                mode   => '0660',
        }
        file { '/home/shellmann/.vim/backup':
                ensure => 'directory',
                owner  => 'shellmann',
                group  => 'shellmann',
                mode   => '0660',
        }
        file { '/home/shellmann/.vim/swap':
                ensure => 'directory',
                owner  => 'shellmann',
                group  => 'shellmann',
                mode   => '0660',
        }
}

Konfiguration von puppet (nodes und manifest)

Weiter geht es mit der Konfiguration der einzelnen Nodes.
Zuerst müssen die Nodes eingetragen werden:

node 'puppetclient.home' {
}

node 'puppetserver.home' {
}

Das bewirkt aber erst mal noch garnichts. Die erste Aufgabe, die wir per puppet erledigen wollen, ist z.B. das Installieren von diversen “Admin Tools”. Dazu müssen wir als erstes ein neues Modul anlegen.

mkdir -p /etc/puppet/modules/admintools/manifests

In dem neu angelegten Verzeichnis erstellen wir nun ein Manifest:

class admintools {
        package { 'tmux': ensure => 'installed' }
        package { 'multitail': ensure => 'installed' }
        package { 'htop': ensure => 'installed' }
        package { 'vim': ensure => 'installed' }
        package { 'sudo': ensure => 'installed' }
        package { 'openssh-server': ensure => 'installed' }
        package { 'vim-puppet': ensure => 'installed' }
}

Das neue Module kann danach dann eingebunden werden:

node 'puppetclient.home' {
    include admintools
}

node 'puppetserver.home' {
    include admintools
}

Weiter geht es im 3. Teil

Installation von puppet

Zum Testen und für erste Gehversuche mit Puppet habe ich mir zwei VMS mit Debian Jessie installiert.
Die Installation von Puppet selbst ist dann sehr einfach.
Auf dem Server muss folgender Befehl ausgeführt werden:

root@puppetserver:~# apt-get install puppetmaster puppet

Das Paket puppet installiere ich mit, da der Server selber auch Client sein sollen.
Auf dem Client muss dann folgendes installiert werden:

root@puppetclient:~# apt-get install puppet

Damit der Client dann den Server auch erreicht muss muss die puppet.conf angepasst werden (gleiches gilt für den Server, wenn er gleichzeitig auch Agent sein soll)

[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
prerun_command=/etc/puppet/etckeeper-commit-pre
postrun_command=/etc/puppet/etckeeper-commit-post
server=puppetserver.home

[master]
# These are needed when the puppetmaster is run by passenger
# and can safely be removed if webrick is used.
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY

Der Agent muss dann aktiviert werden:

root@puppetclient:~# puppet agent --enable

Um für den Client jetzt einen neuen SSL Key und einen Request zu generieren muss folgender Befehl ausgeführt werden:

root@puppetclient:~# puppet agent -t
Info: Creating a new SSL key for puppetclient.home
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for puppetclient.home
Info: Certificate Request fingerprint (SHA256): 74:FC:D5:F1:1D:94:48:14:8D:44:69:00:F4:F2:08:46:42:3E:25:8F:1A:81:EA:AF:44:98:33:21:0B:AD:AE:18
Exiting; no certificate found and waitforcert is disabled

Zur Erklärung:
Auf dem Puppetserver läuft eine CA. Aus Sicherheitsgründen muss deshalb zuerst am Server ein Zertifikat ausgestellt werden.
Die Wortwahl der Befehle ist im nachfolgenden Beispiel etwas ungüstig.
Mit dem ersten Befehl werden all Request und “Zertifikate” bzw. deren Fingerprint angezeigt. Zertifikate haben ein + als erstes Zeichen
Mit dem zweiten Befehl wird dann ein Request signiert. Befehl drei zeigt dann noch mal alle Zertifikate an.

root@puppetserver:~# puppet cert --list --all
  "puppetclient.home" (SHA256) 74:FC:D5:F1:1D:94:48:14:8D:44:69:00:F4:F2:08:46:42:3E:25:8F:1A:81:EA:AF:44:98:33:21:0B:AD:AE:18
+ "puppetserver.home" (SHA256) A6:17:03:8D:F8:2E:C0:E5:76:49:24:E8:84:4D:EB:91:DB:63:82:45:75:2F:33:60:F6:79:A9:AF:D2:06:1B:E1 (alt names: "DNS:puppet", "DNS:puppet.home", "DNS:puppetserver.home")
root@puppetserver:~# puppet cert sign "puppetclient.home"
Notice: Signed certificate request for puppetclient.home
Notice: Removing file Puppet::SSL::CertificateRequest puppetclient.home at '/var/lib/puppet/ssl/ca/requests/puppetclient.home.pem'
root@puppetserver:~# puppet cert --list --all
+ "puppetclient.home" (SHA256) F2:7A:B7:54:0D:F9:18:EE:0E:17:E5:CF:EB:44:E7:D4:CE:68:75:B9:4D:1E:65:0B:E8:05:A8:5D:97:C8:7D:A8
+ "puppetserver.home" (SHA256) A6:17:03:8D:F8:2E:C0:E5:76:49:24:E8:84:4D:EB:91:DB:63:82:45:75:2F:33:60:F6:79:A9:AF:D2:06:1B:E1 (alt names: "DNS:puppet", "DNS:puppet.home", "DNS:puppetserver.home")

Am Client kann nun das Zertifikat abgeholt werden:

root@puppetclient:~# puppet agent -t
Info: Caching certificate for puppetclient.home
Info: Caching certificate for puppetclient.home
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetclient.home
Info: Applying configuration version '1455277912'
Notice: Finished catalog run in 0.06 seconds

Damit ist die Grundinstallation fertig. Per default meldet sich der Client alle 30 Minuten am Server. Der Client kann von Hand ausgeführt werden, mit entsprechendem Verbose / Debug Output:

root@puppetclient:~# puppet agent --no-daemonize --onetime --verbose --debug

Gleiches kann man natürlich auch mit dem Server / Daemon machen:

root@puppetserver:~# puppet master --no-daemonize --verbose --debug

Um das vim Plugin zu aktivieren, muss es zuerst in den Plugin Ordner des Homesverzeichnisses verlinkt werden:

root@puppetserver:~# mkdir -p /root/.vim/plugin
root@puppetserver:~# ln -s /usr/share/vim/addons/syntax/puppet.vim .vim/plugin/puppet.vim

Außerdem muss die vimrc noch angepasst werden:

syntax on

Weiter gehts im 2. Teil