1. Prêtez vos poupées !
Vous avez installé Puppet qui VOUS permet de déployer et gérer vos systèmes. En plus d'être le seul à en connaître la syntaxe, il faut en passer par vous pour déployer une nouvelle machine, lui assigner des classes. Nous allons voir comment Puppet Dashboard [1], dans un premier temps, puis Foreman [2], vont vous permettre de faciliter l'audit de votre installation Puppet et même de confier le déploiement des machines à un tiers. Une petite piqûre de rappel sur le concept d'external node s'impose.
1.2. L'external node
Pour faire court et ne pas paraphraser ce qui a déjà été évoqué dans ces colonnes, un external node vous permet d'externaliser la définition de vos clients [4]. Au lieu de configurer de A à Z vos nodes dans votre puppetmaster, comme ceci :
node webserver.exemple.fr {
include apache_class
...
}
Vous pouvez utiliser un SGBD ou LDAP pour contenir la configuration et avoir un fichier manifest aussi épuré que ça :
node default {
}
Plus besoin de déclarer chaque hôte, de lui rajouter les classes, en passant par l'édition des fichiers de configuration de votre puppetmaster et de redémarrer le démon. Puppet Dashboard et Foreman peuvent servir d'external node. Par leur interface web, ils offrent un moyen simple d'ajouter une classe, un environnement à un client. Une fois que vous avez défini les classes dans Puppet, vous pouvez dès lors déléguer le déploiement ou la réinstallation de vos nodes. Tout ça à une personne n'ayant pas de compétences dans la syntaxe de Puppet, ni les privilèges pour modifier les fichiers et redémarrer le démon. Trêve de bavardage, préparons d'abord notre environnement de travail.
1.3. Pré-requis
1.3.1. Dépôt
Par facilité, nous utiliserons plusieurs paquets récents, présents dans le dépôt backports :
$> cat << EOF | sudo tee /etc/apt/sources.list.d/backports.list
> deb http://www.backports.org/debian lenny-backports main contrib non-free
> EOF
On met à jour la liste des paquetages :
$> sudo aptitude update
Par défaut, les paquetages des backports ne sont pas activés, il faut forcer leur installation :
$> sudo aptitude -t lenny-backports install Nom_Du_Paquetage
Donc, pour les paquets installés par cette méthode, si vous voulez que leur mise à jour soit effectuée, il faut modifier votre fichier /etc/apt/preferences :
$> cat << EOF | sudo tee -a /etc/apt/preferences
> Package: *
> Pin: release a=lenny-backports
> Pin-Priority: 200
> EOF
1.3.2. Configuration Puppet des clients et du Master
Pendant le reste de cet article nous prendrons comme assertion que vous utilisez la version 0.25 de Puppet, depuis les backports.
Par simplicité, je vous invite également à exécuter Puppet sur vos clients à distance, depuis votre puppetmaster, à l'aide de la commande puppetrun. Pour ce faire, il faut que le daemon puppetd tourne sur vos clients et qu'il accepte les connexions en activant le paramètre listen :
[puppetd]
…
listen = true
report = true
...
Vous avez noté l'utilisation de la directive listen = true, qui permet au master de recevoir un rapport d'exécution depuis le client, qui nous sera utile plus tard.
Vous devrez aussi spécifier dans le fichier /etc/puppet/namespaceauth.conf de chaque client et du master, quel(s) espaces de nom est (sont) autorisé(s) à se connecter au démon puppetd :
#fichier /etc/puppet/namespaceauth.conf
...
#Obligatoire uniquement sur le master
[fileserver]
allow *.exemple.fr
#Obligatoire uniquement sur le master
[puppetmaster]
allow *.exemple.fr
#Sur toutes les machines
[puppetrunner]
allow puppetmaster.exemple.fr
...
Redémarrez le démon puppetd sur chaque machine. Vous pourrez dès lors lancer depuis votre master :
$> sudo puppetrun --host remote.exemple.fr -d
Triggering remote.exemple.fr
remote.exemple.fr finished with exit code 0
Finished
2. Puppet Dashboard
Puppet Dashboard est l'interface web officielle de votre infrastructure Puppet, développée par Puppet Labs. Grâce à elle, vous avez un point central pour monitorer le statut de vos clients Puppet, quels changements ont été appliqués, lesquels sont en erreur, etc.
2.1. Installation
Récupérez et décompressez l'archive du projet :
$> cd /usr/share/
$> sudo wget wget http://puppetlabs.com/downloads/dashboard/puppet-dashboard-1.0.3.tgz
$> sudo tar xzf puppet-dashboard-1.0.3.tgz
$> sudo mv puppet-dashboard-1.0.3 puppet-dashboard
On crée ensuite la base :
$> sudo mysql -e "CREATE DATABASE dashboard CHARACTER SET utf8;"
$> sudo mysql -e "CREATE USER 'dashboard'@'localhost' IDENTIFIED BY 'my_password';"
$> sudo mysql -e "GRANT ALL PRIVILEGES ON dashboard.* TO 'dashboard'@'localhost';"
$> sudo mysqladmin flush-privileges
Avant de peupler la base, il faut modifier le fichier de configuration de connexion à MySQL :
$> cd /usr/share/puppet-dashboard
$> cat << EOF | sudo tee config/database.yml
> #fichier config/database.yml
> production:
> adapter: mysql
> encoding: utf8
> database: dashboard
> username: dashboard
> password: my_password
> EOF
..
$> sudo chmod 640 config/database.yml
On crée les tables :
$> sudo aptitude -y install libopenssl-ruby1.8 rake rubygems ruby
$> sudo rake RAILS_ENV=production db:migrate
Vous pouvez omettre les warnings pouvant être renvoyés par Rake. On teste sommairement notre setup en démarrant le serveur web de test Webrick :
$> sudo ./script/server -e production
=> Booting WEBrick
=> Rails 2.3.5 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-09-22 17:33:49] INFO WEBrick 1.3.1
[2010-09-22 17:33:49] INFO ruby 1.8.7 (2008-08-11) [x86_64-linux]
[2010-09-22 17:33:49] INFO WEBrick::HTTPServer#start: pid=8767 port=3000
Vous pouvez accéder à l'interface web en vous connectant au port 3000 de la machine.
2.2. Apache et Passenger
Webrick c'est bien gentil pour les tests, mais pour la montée en charge, une configuration plus fine du VirtualHost, vous pouvez utiliser les serveurs Web Apache, Nginx, etc. Nous allons procéder à l'installation sous Apache+Passenger, couple plus performant que Webrick et facile à mettre en place. Un bon vieux [Ctrl]+[C] pour tuer Webrick et on attaque :
^C[2010-09-22 17:46:48] INFO going to shutdown …
[2010-09-22 17:46:48] INFO WEBrick::HTTPServer#start done.
Exiting
$> sudo aptitude -y install libapache2-mod-passenger
$> cat << EOF | sudo tee /etc/apache2/sites-available/dashboard
> #Fichier /etc/apache2/sites-available/dashboard
> Listen 3000
>
> # These modules must be enabled : passenger
> # Configuration for http://localhost/puppet-dashboard
> <VirtualHost *:3000>
> # this is the passenger config
> RailsAutoDetect On
> AddDefaultCharset UTF-8
> RailsEnv production
> RailsBaseURI /puppet-dashboard
> SetEnv X_DEBIAN_SITEID "default"
> Alias "/puppet-dashboard/plugin_assets/" /var/cache/puppet-dashboard./default/plugin_assets/
> DocumentRoot /usr/share/puppet-dashboard/public
> <Directory "/usr/share/puppet-dashboard/public">
> Order allow,deny
> Allow from all
> </Directory>
>
> ErrorLog /var/log/apache2/dashboard.error.log
> LogLevel warn
> CustomLog /var/log/apache2/dashboard.access.log combined
> ServerSignature Off
>
> </VirtualHost>
> EOF
…
$> sudo a2enmod passenger # Si le module n’est pas déjà chargé
$> sudo a2ensite dashboard #on charge l’hôte virtuel dans la configuration Apache
$> sudo chown -R www-data log config public # on donne les droits qui vont bien pour l’exécution d’Apache
$> sudo /etc/init.d/apache2 restart
Vous devriez avoir accès à nouveau à l'interface de Puppet-Dashboard sur le port 3000, via Apache désormais. Pour tout changement de configuration, n'oubliez pas de redémarrer le service Apache bien sûr. On va également modifier le fichier logrotate d'Apache pour prendre en compte le fichier de log de Puppet Dashboard et éviter que celui-ci ne grossisse indéfiniment :
#Fichier /etc/logrotate.d/apache2
/usr/share/puppet-dashboard/log/production.log {
weekly
missingok
rotate 52
compress
delaycompress
notifempty
create 640 www-data www-data
}
/var/log/apache2/*.log {
weekly
missingok
rotate 52
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
if [ -f "`. /etc/apache2/envvars ; echo ${APACHE_PID_FILE:-/var/run/apache2.pid}`" ]; then /etc/init.d/apache2 reload > /dev/null
fi
endscript
}
Vous pouvez procéder à des paramétrages supplémentaires de Puppet Dashboard dans config/environment.rb (time zone) et dans le fichier config/environments/production.rb (mode debug).
2.3. Récupération des rapports
Pour ajouter des hôtes et les rapports Puppet associés, vous devez exécuter, toujours depuis le répertoire de Puppet Dashboard :
$> sudo rake RAILS_ENV=production reports:import
(in /usr/share/puppet-dashboard)
Importing 5 reports from /var/lib/puppet/reports/
Importing: 100% |##############################| Time: 00:00:00
5 of 5 reports imported
La commande s'attend à trouver les rapports dans le dossier $reportdir de votre configuration, qui par défaut est /var/lib/puppet/reports. Si vous voulez pointer un autre répertoire :
$> sudo rake RAILS_ENV=production reports:import REPORT_DIR=/chemin/vers/dossier/rapports
Exécutez plusieurs puppetrun pour rajouter des nodes.
Cette commande étant à exécuter régulièrement, il faudrait que vous écriviez un cron. De même, comment faire si le puppetmaster et le Dashboard ne sont pas sur le même système ? La solution est d'envoyer automatiquement les rapports reçus par le master à Puppet Dashboard à l'aide du script fourni. Il vous faut tout d'abord rajouter ce script, le fichier ext/puppet/puppet_dashboard.rb, dans le dossier des reports de votre puppetmaster, le dossier /usr/lib/ruby/1.8/puppet/reports par défaut.
@puppetmaster: $> sudo cp -a ext/puppet/puppet_dashboard.rb /usr/lib/ruby/1.8/puppet/reports
Si votre master et votre dashboard ne sont pas sur le même serveur, en plus d'adapter la commande précédente, vous devrez modifier la variable HOST, voire PORT du fichier :
# fichier /usr/lib/ruby/1.8/puppet/reports/puppet_dashboard.rb
require 'puppet'
HOST = 'dashboard.exemple.fr'
PORT = 3000
...
Maintenant que le processeur est rajouté, vous pouvez indiquer au puppetmaster de l'utiliser, en complément ou non d'autres scripts déjà utilisés :
# fichier /etc/puppet/puppet.conf du master
...
[puppetmasterd]
reports = log, puppet_dashboard
...
Redémarrez le master et exécutez des puppetrun, vous devriez voir les rapports s'ajouter.
2.4. L'interface
2.4.1. Tour d'horizon
Dashboard, pour « tableau de bord », car l'interface vous présente l'ensemble de votre installation Puppet. Vous avez un menu vertical gauche, comportant les sections Nodes, Class et Group. La partie centrale affiche en détail les informations de la section sélectionnée. Enfin, le menu supérieur horizontal ne contient que des liens vers les pages principales des sections précédentes : redondant avec le menu latéral gauche, son utilisation peut être occultée. Même les informations de son menu Reports, qui vous permet d'afficher l'intégralité des rapports reçus, peuvent être retrouvées dans la section Nodes.
Figure 1 : La page d'accueil
2.4.2. Les différentes sections
La page principale de Puppet Dashboard est en fait la page principale de la section Nodes, agrémentée d'un message vous avertissant des nodes ne retournant plus de rapport d'exécution depuis plus d'une heure s'il y a lieu. Elle vous présente un résumé graphique des exécutions par jour, leur nombre, en différenciant réussites et échecs. En dessous, vous pouvez trouver une liste cliquable des différentes machines connues de l'interface. En cliquant un des liens, vous accéderez à des informations détaillées supplémentaires de la machine sélectionnée. À savoir une courbe du temps d'exécution du client Puppet et les différents rapports reçus de ladite machine.
Figure 2 : Le détail d'un node
D'autres liens de la section Nodes du menu vertical vous permettent de filtrer l'affichage des machines suivant leur état d'exécution : actuellement réussie ou en erreur, qui ont toujours réussi ou échoué, qui n'ont pas envoyé de rapport dernièrement, voire carrément jamais. Les deux autres sections du menu vertical gauche Class et Group, vous permettent d'afficher et créer les classes et groupes de votre installation. Nous allons voir plus en détail ces différentes sections dans la prochaine partie. Dans celle-ci, nous allons faire une mise en pratique de la création de node, classe et groupe grâce aux external nodes.
2.5. Puppet Dashboard comme external node
2.5.1. Configuration
Pour que Dashboard agisse comme interface d'external node, il faut utiliser le script /usr/share/puppet-dashboard/bin/external_node. Modifiez l'URL de votre dashboard au besoin :
$> sudo chmod 755 bin/external_node
$> sudo nano bin/external_node
#! /usr/bin/ruby
#
# Sample External Node script for Puppet Dashboard
#
# == puppet.conf Configuration
#
# [main]
# external_nodes = /path/to/external_node
# node_terminus = exec
require ‘yaml’
require ‘uri’
require ‘net/http’
BASE="http://localhost:3000"...
À chaque exécution d'un client, c'est le puppetmaster qui va lancer ce script. Si vos master et dashboard ne sont pas sur le même serveur, n'oubliez pas de copier ce fichier sur votre puppetmaster et de donner les droits d'exécution et de lecture au processus qui exécute le puppetmaster (Puppet, mais généralement Apache si vous avez aussi abandonné Webrick pour déployer les configurations aux clients). Il ne vous reste plus qu'à modifier votre maître pour qu'il exécute le script à chaque connexion d'un client :
$> sudo nano puppet.conf
[main]
...
external_nodes = /usr/share/puppet-dashboard/bin/external_node
node_terminus = exec
...
Si vous obtenez l'erreur suivante à l'exécution de Puppet :
$> sudo puppetrun --host testclient.exemple.fr -d
notice: Ignoring --listen on onetime run
notice: Ignoring cache
err: Could not retrieve configuration: Could not find node ‘testclient.exemple.fr’; cannot compile
warning: Not using cache on failed configuration
C'est que votre node n'a pas été trouvé dans le backend des external nodes (la base MySQL créée précédemment) : pour tous les nouveaux clients qui se connectent pour la première fois à votre puppetmaster, vous devrez au préalable déclarer cette machine dans l'interface de Puppet Dashboard.
2.5.2. Utilisation
Reprenons le manifest épuré évoqué précédemment (cf. 1.2), et créons les déclarations basiques suivantes sur notre master :
class resolv {
file {"/etc/resolv.conf":
owner => root,
group => root,
mode => 644,
content => template("resolv/resolv.conf.erb");
}
host {
$fqdn:
ip => $myip,
ensure => present;
}
}
#template resolv.conf.erb
search <%= mydomain %>
<% mynameservers.split(",").each do |mynameserver| -%>
nameserver <%= mynameserver %>
% end -%>
Pour chaque classe existante de votre installation Puppet, vous êtes malheureusement obligé de la re-déclarer manuellement dans Puppet Dashboard, en respectant scrupuleusement orthographe et casse. Créez donc une classe « resolv » dans l'interface de Puppet Dashboard via le lien Add Class :
Figure 3 : Ajout d'une classe
Cliquez sur Add Group, créez un groupe « netconf », contenant la classe précédente et les paramètres suivants (mynamerservers est une liste d'adresse IP séparées par une virgule) :
Figure 4 : Ajout d'un groupe
Finissez en déclarant la machine testclient.exemple.fr via Add Node, en lui appliquant le groupe « netconf » et le paramètre myip :
Figure 5 : Ajout d'une machine
On exécute Puppet sur testclient et on vérifie si les configurations faites dans Puppet Dashboard lui ont bien été appliquées :
@testclient: $> cat /etc/resolv.conf /etc/hosts
search exemple.fr
nameserver 192.168.1.1
nameserver 192.168.1.2
.....
192.168.1.100 testclient.exemple.fr
Cet exemple démontre bien que l'on peut s'affranchir de la modification répétitive des fichiers du master, suivie de son redémarrage, à chaque ajout d'un node, d'une classe et même d'un module. Il se veut simpliste, mais vous pouvez bien sûr imbriquer les groupes pour retrouver le concept d'héritage qu'offre le puppetmaster dans la configuration de vos nodes.
3. Foreman
Foreman permet de gérer vos nodes et de visualiser les rapports d'erreurs. De plus, à l'instar de Dashboard, il permet aussi d'installer une machine de manière automatisée : système d'exploitation, partitionnement, ... Pour cela, il s'intègre à un serveur PXE et supporte les méthodes Kickstart (RedHat/Fedora), Preseed (Debian/Ubuntu) et Jumpstart (Solaris).
3.1. Installation
On télécharge l'archive et on la décompresse dans /usr/share :
$> cd /usr/share/
$> sudo wget http://theforeman.org/attachments/download/104/foreman-0.1-5.tar.bz2
$> sudo tar xjf foreman-0.1-5.tar.bz2
$> cd foreman/
Comme précédemment, on crée la base de données et le fichier de configuration de connexion de Foreman à celle-ci :
$> sudo mysql -e "create database foreman character set utf8;create user 'foreman'@'localhost' identified by 'my_password'"
$> sudo mysql -e "grant all privileges on foreman.* to 'foreman'@'localhost';"
$> sudo mysqladmin flush-privileges
$> sudo cat << EOF | sudo tee config/database.yml
> production:
> adapter: mysql
> encoding: utf8
> database: foreman
> username: foreman
> password: my_password
> EOF
…
$> sudo chmod 640 config/database.yml # on protége le fichier en lecture
Si vous utilisez les Storeconfigs et que votre serveur PuppetMaster et Foreman sont sur la même machine, ne créez pas de base pour Foreman ! Utilisez la base de données des Storeconfigs pour héberger les tables de Foreman et renseignez les paramètres adéquats dans database.yml. Ainsi, Foreman aura également accès aux tables desStoreconfigs.
On peut maintenant peupler la base de données avec les tables de Foreman :
$> sudo aptitude -y install rake libmysql-ruby
$> sudo aptitude -t lenny-backports -y install rubygems libopenssl-ruby1.8 puppet
$> sudo gem install rack -v=1.0.1
$> sudo RAILS_ENV=production rake db:migrate
== UpdateOsMinor: migrated (0.0035s) =========================================
rake aborted!
undefined method `reenable' for <Rake::Task db:schema:dump => [environment]>:Rake::Task
(See full trace by running task with --trace)
Vous pouvez omettre les messages d'erreurs de fin sans crainte.
On teste :
$> sudo ./script/server -e production
=> Booting WEBrick
=> Rails 2.3.5 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-09-24 16:52:12] INFO WEBrick 1.3.1
[2010-09-24 16:52:12] INFO ruby 1.8.7 (2008-08-11) [x86_64-linux]
[2010-09-24 16:52:12] INFO WEBrick::HTTPServer#start: pid=4020 port=3000
Foreman devient aussi accessible sur le port 3000. On va se passer du serveur Webrick et encore utiliser le couple Apache+Passenger :
$> sudo aptitude -y install libapache2-mod-passenger
$> sudo chown -R www-data: /usr/share/foreman/
$> cat << EOF | sudo tee /etc/apache2/sites-available/foreman
>Listen 80
> <VirtualHost *:80>
> DocumentRoot /usr/share/foreman/public
>
> RailsAutoDetect On
> AddDefaultCharset UTF-8
>
> </VirtualHost>
>
> ErrorLog /var/log/apache2/foreman.error.log
> LogLevel warn
> CustomLog /var/log/apache2/foreman.access.log combined
> ServerSignature Off
>
> <VirtualHost *:443>
>
> RailsAutoDetect On
> DocumentRoot /usr/share/foreman/public
>
> # Use puppet certificates for SSL
>
> SSLEngine On
> SSLCertificateFile /var/lib/puppet/ssl/certs/foreman.exemple.fr.pem
> SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/foreman.exemple.fr.pem
> SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem
> SSLCACertificateFile /var/lib/puppet/ssl/certs/ca.pem
> SSLVerifyClient optional
> SSLOptions +StdEnvVars
> SSLVerifyDepth 3
>
> ErrorLog /var/log/apache2/foreman.error.log
> LogLevel warn
> CustomLog /var/log/apache2/foreman.access.log combined
> ServerSignature Off
>
> </VirtualHost>
> EOF
On a activé un hôte virtuel sous SSL ; adaptez les directives SSLCertificateFile et SSLCertificateKeyFile suivant les certificats que vous avez dans votre répertoire /var/lib/puppet/ssl/certs/. Vous avez besoin d'exécuter le client Puppet puppetd une fois pour que ces certificats soient générés. Vous pouvez maintenant charger les modules et le nouvel hôte virtuel, puis redémarrer Apache pour prendre en compte la configuration :
$>sudo a2enmod passenger
$>sudo a2enmod ssl
$>sudo a2ensite foreman
$>sudo /etc/init.d/apache2 restart
Foreman est maintenant accessible via Apache sur le port 80 (ou tout autre port que vous avez défini bien sûr) et sur le port 443. Reportez-vous à l'installation de Puppet Dashboard pour créer un fichier logrotate équivalent pour effectuer la rotation du fichier log/production.log.
3.2. L'interface
La page d'accueil de Foreman est comparable à Puppet Dashboard, avec un résumé de l'activité des clients Puppet de votre infrastructure.
Figure 6 : Accueil de Foreman
Cette page correspond à l'entrée Dashboard du menu supérieur. Les autres entrées vous permettent de lister et éditer les hôtes (Hosts, comparable à la page des hôtes sous Puppet Dashboard et son graphique d'exécution), les rapports (Reports), les Facts de vos machines (Facts) ainsi qu'un journal des modifications apportées aux données (Audit Log). Vous remarquerez qu'un sous-menu avec les entrées Search et Reset est disponible pour chacune de ces 4 sections. Il vous permet d'effectuer une recherche sur les éléments, de sauvegarder cette recherche sous forme d'un onglet et de l'effacer. L'entrée Statistics vous présente la répartition de vos machines sous forme de graphiques type camembert :
Figure 7 : Page des statistiques
La dernière entrée Settings vous permet de configurer les différentes données (classes, groupes, utilisateurs) dans Foreman. Certaines entrées restent grisées, car il faut passer par la configuration interne de Foreman pour les activer. Cette configuration de l'application se passe dans le fichier config/settings.yaml. Par exemple, pour forcer l'utilisation en HTTPS, il faut rajouter le paramètre suivant :
#fichier config/settings.yaml
...
:require_ssl: true
...
Foreman sera accessible en HTTPS... et sur aucun autre port supplémentaire ! Attention, si vous voulez utiliser ses fonctionnalités d'installation automatisée : les fichiers preseed et kickstart ont besoin de la version non-sécurisée du protocole pour être déployés par Foreman. Il est d'usage de laisser les deux protocoles disponibles. Nous allons également procéder aux modifications suivantes :
#fichier config/settings.yaml
...
:unattended: false #on désactive les installations automatisées pour le moment
#Le nom DNS du serveur puppet par défaut attribué aux clients de ce serveur Foreman
#Peut être modifié dans la page édition d'un hôte dans Foreman également
:puppet_server: puppetmaster
#Intervalle d'exécution des clients puppet, en minutes, ayant précédence sur l'intervalle du puppetmaster
:puppet_interval: 60
...
Vous pouvez également, comme sous Puppet Dashboard, paramétrer Foreman au travers des fichiers config/environment.rb et config/environments/production.rb.
3.3. Comptes utilisateurs
La gestion des utilisateurs en est encore à ses balbutiements. Vous pouvez juste contrôler qui peut se loguer à l'interface web et affecter des machines à des utilisateurs. Ils recevront en particulier les notifications mails associées à leur(s) machine(s). Commencez par activer la gestion utilisateurs, en activant le LDAP, même si vous n'utilisez pas de serveur LDAP comme base de données utilisateurs :
$> cat << EOF | sudo tee -a config/settings.yaml
>:ldap: true
> EOF
$> sudo /etc/init.d/apache2 restart
Connectez-vous avec le compte admin, mot de passe changeme. Les menus Settings > users et Settings > usergroups devraient être visibles désormais.
Pour utiliser un serveur LDAP, allez dans Settings > LDAP Authentication et rentrez les paramètres de connexion de votre serveur. Si vous cochez la case On-the-fly user creation, tous les utilisateurs de votre LDAP auront accès à Foreman. Décochez cette option, enregistrez vos paramètres et créez manuellement les comptes utilisateurs des administrateurs autorisés à utiliser Foreman, via Settings > users en choisissant votre serveur LDAP dans la liste déroulante de l'option Authorized by.
Au fil du temps, les sessions utilisateurs vont s'accumuler dans la base de Foreman. Exécutez la commande suivante pour faire le ménage :
$> cd /usr/share/foreman && sudo rake db:sessions:clear RAILS_ENV="production"
À rajouter dans un cron journalier bien sûr.
3.4. Import des Données
3.4.1. Import des Hôtes
Foreman reçoit exclusivement les rapports depuis le master via un script, de manière similaire à Puppet Dashboard avec puppet_dashboard.rb (cf. 2.3). Commencez par copier le script depuis le dossier d'installation de Foreman dans le dossier /usr/lib/ruby/1.8/puppet/reports du puppetmaster. Autrement dit, si votre puppetmaster et Foreman sont sur le même serveur :
@puppetmaster: $> sudo cp -a extras/puppet/foreman/files/foreman-report.rb /usr/lib/ruby/1.8/puppet/reports/foreman.rb
Modifiez ensuite la variable foreman_url pour refléter votre installation :
# fichier /usr/lib/ruby/1.8/puppet/reports/foreman.rb
...
$foreman_url="http://foreman.exemple.fr"
...
Et indiquez à votre puppetmaster de l'utiliser :
# fichier /etc/puppet/puppet.conf du master
...
[puppetmasterd]
reports = log, puppet-dashboard, foreman
...
Redémarrez le master pour commencer à recevoir des hôtes dans Foreman. Les rapports vont également s'accumuler avec le temps. Foreman vous permet par rake de faire le ménage :
$> # suppression des rapports n'ayant pas retourné d'erreur (status=0) au bout de un jour:
$> sudo rake reports:expire days=1 status=0 RAILS_ENV="production"
À vous d'écrire le cron qui va bien pour faire régulièrement tout ça :
#!/bin/sh
#Fichier /etc/cron.daily/purge_foreman_reports
cd /usr/share/foreman
echo "suppression de tous les rapports de plus de 4 jours"
rake reports:expire days=4 RAILS_ENV="production"
...
3.4.2. Exécuter les Puppetrun
Vous pouvez exécuter puppetrun depuis l'interface de Foreman. Plus besoin de quitter l'interface web, ni de taper des commandes, un simple clic suffit.
$> cat << EOF | sudo tee -a config/settings.yaml
>:puppetrun: true
>EOF
Redémarrez Apache, puis autorisez puppetrun à être exécuté depuis Foreman, c'est-à-dire l'utilisateur propriétaire du dossier d'installation, en l'occurrence Apache dans notre exemple :
$> sudo visudo
...
www-data ALL= NOPASSWD:/usr/sbin/puppetrun
...
Dans l'interface Foreman, cliquez sur un hôte et dans la page de description, vous pouvez lancer un puppetrun en cliquant sur Run Puppet, en haut à droite. Si votre serveur Foreman et votre puppetmaster sont différents, assurez-vous que dans le fichier /etc/puppet/namespaceauth.conf de chaque client (cf. 1.3), la directive [puppetrunner] inclut bien le serveur Foreman (ici, nous sommes bons avec *.exemple.fr). Assurez-vous aussi que le binaire puppetrun est bien présent sur le serveur Foreman. Pour cela, par simplicité, vous pouvez installer tout le paquetage puppetmaster juste pour récupérer le binaire, puis désactiver le service comme suit :
$> sudo aptitude install -t lenny-backports puppetmaster
$> sudo update-rc.d -f puppetmaster remove
3.4.3. Import des Facts
Si vous utilisez les Stored Configs, les Facts Puppet devraient déjà être visibles, car envoyés par votre master. Néanmoins, vous devriez lancer la commande suivante pour importer les données utiles aux Unattended Installations :
@foreman: $> sudo rake puppet:migrate:populate_hosts RAILS_ENV=production
Et ainsi éviter d'avoir ce message d'erreur à l'exécution de Puppet :
@testclient: $> sudo puppetd --test --waitforcert 60
notice: Ignoring --listen on onetime run
err: Could not retrieve catalog: Could not parse: interning empty string
warning: Not using cache on failed catalog
Si vous n'utilisez pas les Stored Configs, vous devriez vous y mettre... Blague à part, si votre master et Foreman sont sur le même serveur :
@foreman: $> sudo rake puppet:import:hosts_and_facts RAILS_ENV=production
S'ils sont sur des machines différentes, vous devrez copier le script push_facts.rb, du répertoire extras/puppet/foreman/files, sur votre master après avoir configuré correctement l'URL de votre serveur Foreman :
#! /usr/bin/env ruby
# Fichier push_facts.rb
# This scripts runs on remote puppetmasters that you wish to import their nodes facts into Foreman
# it uploads all of the new facts its encounter based on a control file which is stored in /tmp directory.
# This script can run in cron, e.g. once every minute
# if you run it on many puppetmasters at the same time, you might consider adding something like:
# sleep rand(10)
# that not all PM hammers the DB at once.
# ohadlevy@gmail.com
# puppet config dir
puppetdir="/var/lib/puppet"
# URL where Foreman lives
url="http://foreman:8080"
...
Toutes les commandes citées sont à exécuter périodiquement via un travail Cron. Comme indiqué dans l'entête du script précédent, attention à la surcharge sur la base de données de Foreman si vous mettez à jour vos Facts depuis plusieurs masters ! Rendez-vous dans Facts, tous vos Facts devraient être listés. Cliquez sur l'un d'entre eux pour afficher les nodes qui partagent la même valeur de ce Fact.
Figure 8 : Les Facts
3.5. Notifications
Foreman peut vous envoyer des alertes et rapports par mails. Commençons par activer l'envoi dans la configuration de Foreman :
$> cat << EOF | sudo tee config/email.yaml
> production:
> delivery_method: :sendmail
> EOF
sudo /etc/init.d/apache2 restart
Vous trouverez dans config/email.yaml.example et sur le wiki de Foreman [4], des exemples pour utiliser d'autres paramètres de connexion SMTP.
3.5.1. Rapport d'exécution
Foreman peut vous envoyer un résumé de l'état de vos clients, suivant les rapports reçus :
$> #envoyer un résumé des 12 dernières heures
$> sudo rake reports:summarize hours=12 RAILS_ENV="production"
Il faudra toujours en passer par un cron si vous voulez automatiser tout ça :
$> cat << EOF | sudo tee /etc/cron.daily/foreman_daily_report
>cd /usr/share/foreman
>rake reports:summarize days=1 RAILS_ENV="production"
>EOF
3.5.2. Notification sur erreur
En cas de problème d'exécution d'un client, Foreman peut vous avertir lorsqu'il reçoit ce rapport en erreur :
$> cat << EOF | sudo tee -a config/email.yaml
>:administrator: root
>:failed_report_email_notification: true
>EOF
sudo /etc/init.d/apache2 restart
Actuellement équivalent à l'utilisation du fichier tagmail.conf dans la configuration de votre master. La possibilité de pouvoir gérer plus finement les destinataires dans de futures versions donnera plus d'intérêt à cette fonctionnalité.
3.6. Foreman comme External Node
3.6.1. Mise en place
Tout comme Puppet Dashboard, Foreman peut être utilisé pour configurer vos hôtes, sans passer par vos fichiers de configuration, en leur assignant classes, environnements et paramètres. Commençons par récupérer les classes déjà déclarées dans votre puppetmaster :
$> sudo rake puppet:import:puppet_classes RAILS_ENV=production
Vous pouvez exécuter cette commande depuis l'interface web de Foreman : Settings > Puppet Classes > Import new puppet classes and environments (en haut à droite de la page) ou mieux, écrire une tâche cron. À côté, vous avez le lien New PuppetClass si vous voulez rentrer manuellement les classes, à la manière de Puppet Dashboard. À éviter bien sûr. Assurez-vous d'avoir bien la ligne indiquant le chemin vers vos modules sur votre puppetmaster, pour que les classes soient liées correctement à vos environnements :
...
[puppetmasterd]
...
modulepath = /etc/puppet/modules
...
Et ça pour tous les environnements que vous utilisez ([development], [test]....). Le script qui permet à votre maître d'interroger Foreman pour savoir quelle configuration est affectée à quelle machine est extras/puppet/foreman/files/external_node.rb. Comme précédemment, copiez ce fichier sur votre master si lui et Foreman ne partagent pas la même machine. Modifiez également la variable foreman_url suivant votre configuration.
external_node.rb
#! /usr/bin/ruby
# a simple script which fetches external nodes from Foreman
# you can basically use anything that knows how to get http data, e.g. wget/curl etc.
# Foreman url
foreman_url="http://foreman"
...
Vous pouvez maintenant configurer votre master pour qu'il exécute ce script :
#fichier /etc/puppet/puppet.conf
[main]
...
external_nodes = /usr/share/foreman/extras/puppet/foreman/files/external_node.rb
node_terminus = exec
...
Si vous utilisez déjà les external nodes, reportez-vous au wiki de Foreman pour importer vos données existantes [5].
3.6.2. Utilisation
Nous allons encore configurer notre node testclient via Foreman grâce aux external nodes. Nous utiliserons à nouveau la classe et le template des tests sous Puppet Dashboard (cf. 2.4).
Dans l'interface de Foreman, rendez-vous dans Settings > Global Parameters. Définissez le paramètre mydomain :
Figure 9 : Ajout d'attribut global
Les paramètres définis sur cette page seront communs à tous les clients qui utilisent ce serveur Foreman comme backend d'external node. Toujours dans Settings, allez cette fois dans Domains. Ici, vous pourrez configurer des paramètres communs à des clients d'un même domaine. Cliquez sur le domaine qui vous intéresse et définissez vos variables :
Figure 10 : Édition d'un domaine
Revenez à Settings, créez un Host group « netconf » et ajoutez-lui la classe resolv, automatiquement importée si vous avez suivi les instructions des sections précédentes. Vous pouvez également éditer les classes individuellement par Settings > Puppet Classes. Ajoutez le système testclient, Hosts > testclient > Edit, et appliquez-lui la configuration :
Figure 11 : Ajout d'un client
On vérifie la configuration qui sera appliquée à testclient dans Hosts > testclient > YAML :
---
---
puppetmaster: puppetmaster
mynameservers: 192.168.1.1,192.168.1.2
myip: 192.168.1.99
classes:
- resolv
environment: production
Exécutez Puppet sur le client (Hosts > testclient > Run Puppet tant qu'à faire) et la configuration devrait être appliquée :
@testclient $> cat /etc/resolv.conf /etc/hosts
search exemple.fr
nameserver 192.168.1.1
nameserver 192.168.1.2
...
192.168.1.99 testclient.exemple.fr
On retrouve bien les éléments qui ont été explicitement associés à testclient (groupe, classe, les fichiers et les paramètres de la classe), ainsi que les paramètres du domaine et le paramètre global, affectés implicitement.
3.7. Installations automatisées
Couplé à un serveur DNS et à un serveur TFTP, Foreman facilite le (re-)déploiement d'une machine par le réseau via boot PXE. Suivant son principe, Foreman requiert que vos machines démarrent toujours en PXE. Si une machine n'est pas à réinstaller, le serveur PXE lui fera charger un menu par défaut, pour la faire démarrer normalement sur son disque dur. Dans le cas contraire, Foreman modifiera les fichiers du serveur TFTP : la machine démarrera sur l'installateur, puis chargera un fichier Kickstart, Preseed ou Jumpstart généré dynamiquement par Foreman suivant les paramètres que vous aurez appliqués à la machine dans l'application.
3.7.1. Pré-requis
Il faut bien sûr que vous ayez le paramétrage qui suit dans votre DHCP :
...
filename "pxelinux.0";
next-server adresse-ip.du.serveur.tftp;
...
Attention, une machine à réinstaller doit obtenir la même adresse IP par DHCP, que celle qui lui est attribuée dans Foreman.
Dans la version stable actuelle, vos serveurs TFTP et Foreman doivent être sur la même machine et l'utilisateur de Foreman doit avoir les droits d'écriture dans le dossier TFTP pour effectuer les modifications :
$> sudo aptitude -y install tftpd-hpa
$> sudo sed -i s/no/yes/g /etc/default/tftpd-hpa # on active le démon
$> sudo /etc/init.d/tftpd-hpa restart
$> sudo mkdir /var/lib/tftpboot/pxelinux.cfg
$> sudo chown www-data: /var/lib/tftpboot/pxelinux.cfg
On crée le fichier de démarrage par défaut, utilisé par toute machine qui n'est pas indiquée comme à réinstaller. Il démarre simplement le système d'exploitation du disque dur :
$> cd /var/lib/tftpboot
$> sudo nano pxelinux.cfg/default
default defaut
label defaut
localboot 0
Dans l'exemple de la section suivante, nous installerons une machine sous Debian Lenny 64 Bits. Peuplons donc le dossier du serveur TFTP avec les fichiers de démarrage réseau adéquats :
$> sudo wget http://ftp.debian.org/debian/dists/lenny/main/installer-amd64/current/images/netboot/debian-installer/amd64/pxelinux.0
$> sudo mkdir -p Debian/5.0/x86_64/linux
$> cd Debian/5.0/x86_64/linux
$> wget http://ftp.debian.org/debian/dists/lenny/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz
$> wget http://ftp.debian.org/debian/dists/lenny/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux
On crée le fichier de démarrage utilisé pour la réinstallation d'une Debian Lenny 64 bits :
$> cd /var/lib/tftpboot
$> sudo nano pxelinux.cfg/Debian-5.0-amd64
default preseed
label preseed
kernel Debian/5.0/x86_64/linux
append initrd=Debian/5.0/x86_64/initrd.gz ramdisk_size=10800 root=/dev/rd/0 rw auto interface=auto url=http://foreman/unattended/preseed hostname=unassigned-hostname locale=fr_FR.UTF-8 keyb=fr console-setup/ask_detect=false locale=fr_FR bootkbd=fr-latin1 console-setup/layoutcode=fr console-setup/variantcode=nodeadkeys DEBCONF_PRIORITY=critical
Lorsque vous déclarerez une Lenny 64 bits pour être réinstallée par Foreman, celui-ci va créer un lien, nommé suivant l'adresse MAC de la machine, pointant vers ce fichier Debian-5.0-amd64. C'est ce fichier qui sera chargé par la machine après le boot PXE, cette fois-ci, car il a priorité sur l'entrée default.
3.7.2. Template des fichiers de réponses
L'option url du fichier précédent indique quel fichier Kickstart, Preseed ou Jumpstart utiliser, généré et récupéré depuis Foreman. Il correspond au fichier preseed.rhtml du dossier /usr/share/foreman/app/views/unattended/. Ce dossier contient déjà des exemples de fichiers d'installation automatisée :
$> ls -l /usr/share/foreman/app/views/unattended/
total 28
-rw-r--r-- 1 www-data www-data 1123 jun 7 09:37 jumpstart_finish.rhtml
-rw-r--r-- 1 www-data www-data 444 jun 7 09:37 jumpstart_profile.rhtml
-rw-r--r-- 1 www-data www-data 2502 jun 7 09:37 kickstart.rhtml
-rw-r--r-- 1 www-data www-data 394 jun 7 09:37 preseed_finish.rhtml
-rw-r--r-- 1 www-data www-data 1669 jun 7 09:37 preseed.rhtml
drwxr-xr-x 2 www-data www-data 4096 jun 7 09:37 snippets
Ces fichiers sont des fichiers de template, à la manière des templates Puppet. Ils permettent de générer un fichier propre à chaque machine. Ainsi, tous les paramètres assignés à une machine dans Foreman (qu'ils soient globaux, découlant du domaine, d'une classe, d'un groupe ou définis dans la page Edit de l'hôte), sont accessibles via le tableau @host.params :
<%= @host.params["mynameservers"] %> # =>192.168.1.1,192.168.1.2
<%= @host.params["mydomain"] %> # => exemple.fr
Vous pouvez également utiliser des variables pré-existantes dans Foreman, dont voici une liste non-exhaustive :
@archive_location
@base
@cluster
@core
@dynamic
@epel foreman_url
@host.diskLayout
@host.domain.name
@host.environment
@host.grub_pass
@host.ip
@host.name
@host.operatingsystem.release_name
@host.puppetmaster
@host.root_pass
@install_type ks_console
@locale
@mediapath
@osver
@partitioning
@preseed_path
@preseed_server
@system_type
@yumrepo
Par exemple, dans le fichier preseed.rhtml par défaut, on peut définir statiquement le réseau sur la machine à déployer comme suit :
...
# Network configuration
d-i netcfg/choose_interface select eth0
d-i netcfg/disable_dhcp boolean true
d-i netcfg/get_hostname string <%= @host.name %>
d-i netcfg/get_domain string <%= @host.domain.name %>
d-i netcfg/get_ipaddress string <%= @host.ip %>
d-i netcfg/get_nameservers string <%= @host.params["mynameservers"].gsub(","," ") %>
d-i netcfg/get_netmask string 255.255.255.0
d-i netcfg/get_gateway string 192.168.1.254
d-i netcfg/confirm_static boolean true
...
Ce fichier par défaut inclut un fichier preseed_finish.rhtml :
cat > /etc/puppet/puppet.conf << EOF
>%= snippets "puppet.conf" -%<
EOF
/bin/sed -i 's/^START=no/START=yes/' /etc/default/puppet
/bin/touch /etc/puppet/namespaceauth.conf
/usr/sbin/puppetd --config /etc/puppet/puppet.conf --onetime --tags no_such_tag --server <%= @host.puppetmaster %> --no-daemonize
/usr/bin/wget --quiet --output-document=/dev/null --no-check-certificate <%= foreman_url %>
On remarque la directive snippets : pour éviter de dupliquer des éléments de configuration communs à vos différents templates, Foreman utilise des snippets ; puppet.conf correspond au template _puppet.conf.erb du dossier /usr/share/foreman/app/views/unattended :
[main]
vardir = /var/lib/puppet
logdir = /var/log/puppet
rundir = /var/run/puppet
ssldir = \$vardir/ssl
pluginsource = puppet://\$server/plugins
environments = <%= @host.environment %>
[puppetd]
factsync = true
report = true
ignoreschedules = true
daemon = false
certname = <%= @host.name %>
environment = <%= @host.environment %>
server = <%= @host.puppetmaster %>
Il fait appel à des variables de Foreman, comme un template Puppet. Il va paramétrer le fichier de configuration de Puppet et vous pouvez y faire appel depuis tous vos templates Kickstart, Preseed ou Jumpstart. N'oubliez pas de redémarrer Apache à chaque modification de vos fichiers Preseed ou d'un snippet.
3.7.3. Paramétrages finaux dans Foreman
On active dans Foreman les unattended installs et on lui indique le dossier TFTP dans lequel il créera les liens :
$> sudo nano foreman/config/settings.yaml
...
:unattended: true
:tftppath: /var/lib/tftpboot/pxelinux.cfg
...
$> sudo /etc/init.d/apache2 restart
Le lien Build dans la page de détail d'un hôte devrait être activé désormais. Foreman va autosigner vos nodes, à la façon du puppetmaster lorsqu'il est contacté par un client. Il faut donc lui donner le droit exécution sur le binaire puppetca et les droits d'écriture sur /etc/puppet/autosign.conf :
$> sudo chown www-data: /etc/puppet/autosign.conf
$> sudo visudo
...
www-data ALL=(ALL) NOPASSWD:/usr/sbin/puppetrun , NOPASSWD:/usr/sbin/puppetca
...
Il en résulte que, à l'heure actuelle, vos serveurs Puppetmaster et Foreman doivent être sur la même machine, si vous voulez utiliser les fonctionnalités PXE.
3.7.4. Ré-installation d'une machine
Il faut commencer par déclarer un dépôt. Rendez-vous dans Setting > Installation Medias, entrez votre miroir Debian et affectez-le à l'OS Debian 5.0 :
Figure 12 : Ajout d'un média d'installation
Settings > Partition Tables, affectez Ubuntu default toujours à l'OS Debian. Vous pouvez maintenant vous rendre dans Edit, dans la page de la machine à réinstaller. De nouvelles options (OS, table de partitions,...) sont disponibles, que vous pouvez appliquer à cette machine :
Figure 13 : Paramétrage de la machine.
Vous pouvez cliquer sur Build, en haut à droite, pour que la machine soit réinstallée par PXE au prochain démarrage. Vous pouvez vérifier que le lien a bien été créé :
$>ls -l /var/lib/tftpboot/pxelinux.cfg
total 4
lrwxrwxrwx 1 root root 16 oct 13 21:35 01-00-50-56-a4-17-d4 -> Debian-5.0-amd64
-rw-r--r-- 1 root root 410 oct 13 15:15 Debian-5.0-amd64
Vous pouvez vérifier quel fichier preseed lui sera appliqué, en vous rendant à l'adresse http://foreman/unattended/preseed?spoof=192.168.1.100 et en affichant le code source de la page, ou plus simplement :
$> wget foreman/unattended/preseed?spoof=192.168.1.100 -qO - | more
...
# Network configuration
d-i netcfg/choose_interface select eth0
d-i netcfg/disable_dhcp boolean true
d-i netcfg/get_hostname string testclient.exemple.fr
d-i netcfg/get_domain string exemple.fr
d-i netcfg/get_ipaddress string 192.168.1.100
d-i netcfg/get_nameservers string 192.168.1.1 192.168.1.2
d-i netcfg/get_netmask string 255.255.255.0
d-i netcfg/get_gateway string 192.168.1.254
d-i netcfg/confirm_static boolean true
...
$> wget http://foreman/unattended/preseed_finish?spoof=10.0.22.70 -qO - | more
cat > /etc/puppet/puppet.conf << EOF
[main]
vardir = /var/lib/puppet
logdir = /var/log/puppet
rundir = /var/run/puppet
ssldir = \$vardir/ssl
pluginsource = puppet://\$server/plugins
environments = production
[puppetd
factsync = true
report = true
ignoreschedules = true
daemon = false
certname = testclient.exemple.fr
environment = production
server = foreman
EOF
/bin/sed -i ‘s/^START=no/START=yes/’ /etc/default/puppet
/bin/touch /etc/puppet/namespaceauth.conf
/usr/sbin/puppetd --config /etc/puppet/puppet.conf --onetime
--tags no_such_tag --server foreman --no-daemonize
/usr/bin/wget --quiet --output-document=/dev/null --no-check-certificate http://foreman/unattended/built
Il ne vous reste plus qu'à redémarrer la machine et à laisser l'installation automatisée avoir lieu.
3.8. Cadeau bonux
Foreman peut vous servir d'interface de requêtes. Vous pouvez ainsi utiliser ses données depuis d'autres applications. La librairie extras/query/foreman.rb vous servira de base pour vos scripts et extras/query/ssh_using_foreman est un script prêt à l'emploi :
$> cd /usr/share/foreman/extras/query
$> sudo gem install net-ssh-multi
$> ./ssh_using_foreman -c ‘uptime’ -s active -f is_virtual=true
About to execute: uptime
on the following 24 hosts:...
[testclient.exemple.fr] 10:31:09 up 7 days, 1:05, 1 user, load average: 0.00, 0.00, 0.00
...
Une fonctionnalité et un exemple qui ont le mérite d'exister bien que vous utilisiez déjà MCollective [6] pour exécuter des commandes en parallèle sur vos machines.
Conclusion
Nous avons vu que Puppet Dashboard et Foreman sont deux applications à surveiller pour compléter votre boîte à outils Puppet.
Les développeurs de Foreman ont donné naissance à un beau projet, qui a déjà des fonctionnalités d'avance sur son homologue et sa propre vision de la gestion du cycle de vie des serveurs.
Puppet Dashboard était un peu en standby (certaines futures fonctionnalités annoncées depuis la sortie de la version 0.1.0 n'ont toujours pas été implémentées [7]), mais son développement est reparti de plus belle ! En ce sens, l'équipe en charge du projet s'est accordée pour sortir des versions régulièrement. Avec l'acquisition de MCollective par PuppetLabs, Puppet Dashboard va intégrer ses possibilités d'exécution de commandes d'ici quelques mois [8] et évoluer de manière significative.
En plus de cet article, les nouvelles fonctionnalités prévues dans les prochaines versions vous aideront sûrement à vous décider entre l'une et l'autre de ces applications.
Références
[1] http://www.puppetlabs.com/puppet/related-projects/dashboard/
[3] http://docs.puppetlabs.com/guides/external_nodes.html
[4] http://theforeman.org/projects/foreman/wiki/Email_configuration
[6] http://marionette-collective.org/
[7] http://www.puppetlabs.com/blog/a-tour-of-puppet-dashboard-0-1-0/
[8] http://www.puppetlabs.com/mcollective/