\documentclass[compress]{beamer}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[frenchb]{babel}
\usepackage{aeguill}
\usepackage{fancyhdr}

%\usepackage{beamerthemesplit}
%\usetheme{MyTheme}
%\usecolortheme{dolphin}

\setcounter{tocdepth}{2}

\title{Automatisation de l'administration système avec \\
Puppet à la présidence de l'UHP}
\author{Sylvain Zimmermann}
\date{\today}
\institute{Université Henri Poincaré}

% Table des matières dans chaque sous-section
\AtBeginSubsection[]
{
  \begin{frame}<beamer>
    \frametitle{\insertsubsection}
    \tableofcontents[currentsection,currentsubsection]
  \end{frame}
}

\begin{document}

\begin{frame}
  \titlepage
\end{frame}

\section*{}
\begin{frame}{Plan}
  \tableofcontents
\end{frame}

\section{Introduction}

\subsection{Motivations à utiliser puppet}

\begin{frame}{Constats sur l'administration système par machine (1)}
  \begin{itemize}
  \item nombreuses tâches répétitives identiques (\emph{ou presque})
  \item installations de machines : laborieuses
  \item machines jamais tout à fait identiques
  \item difficultés à maintenir une cohérence
  \item chaque machine est vue séparément comme un élément à part entière
  \end{itemize}
\end{frame}

\begin{frame}{Constats sur l'administration système par machine (2)}
  \begin{itemize}
  \item de plus en plus de machines
  \item services en augmentation (sauvegardes, surveillance, plus tard :
    logs, etc.)
  \item explosion du nombre de relations entre machines et au sein des
    machines
  \item documentation dispersée (wiki, helpdesk/redmine, documentations
    annexes)
  \item système de suivi et de catalogage des éléments de l'infrastructure
    globale pas à jour
  \item en général : augmentation de l'entropie du système
  \end{itemize}
\end{frame}

\begin{frame}{Constats sur l'administration système par machine (3)}
  \begin{itemize}
  \item on sait résoudre les problèmes
    \begin{itemize}
    \item souvent similaires
    \item leurs solutions aussi
    \end{itemize}
  \item ce qui est fait une fois par l'homme peut être reproduit par la
    machine (résoudre les problèmes une fois pour toutes)
  \end{itemize}
\end{frame}

\begin{frame}{Constats - conclusions (James White Manifesto - 1)}
  \begin{itemize}
  \item il n'y a qu'un système et non une collection de systèmes
  \item il ne sert à rien d'améliorer une procédure manuelle qu'on
    pourrait automatiser
  \item le système doit converger vers l'état désiré
  \item la seule source valable de l'état actuel du système est le
    système lui-même
  \item chaque élément du système doit être simple pour être mieux compris
  \end{itemize}
\end{frame}

\begin{frame}{Constats - conclusions (James White Manifesto - 2)}
  \begin{itemize}
  \item utiliser de petits outils qui interagissent bien entre eux plutôt
    qu'un gros outil qui fait tout pas très bien
  \item tous les outils doivent s'authentifier et être autorisés depuis
    une source de donnée externe
  \item Le reste : http://blog.websages.com/2010/12/10/jameswhite-manifesto/
  \end{itemize}
\end{frame}

\begin{frame}{Constats - conclusions (3)}
  \begin{itemize}
  \item Pour que l'entropie n'augmente pas trop vite, il faut structurer le
    système, le contrôler. Un système de gestion de machines centralisé et
    automatisé rempli ce rôle. \alert{Puppet} est l'un d'entre eux.
  \item \emph{Puppet} n'est pas la seule solution au problème, ce n'est
    qu'une partie de la réponse.
  \item Il reste
    \begin{itemize}
    \item les outils d'installation (kickstart et consors) avec les
      métadonnées des systèmes permettant d'initier l'installation des
      systèmes
    \item le dépôt des applications/des sources de données permettant de
      reconstruire complètement le système
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Autres gestionnaires de configuration centralisés}
  \begin{description}
  \item[Cfengine] ancien (langage C)
  \item[Bcfg2] ancien (xml)
  \item[chef] inspiré par \emph{puppet} - tout est en \emph{ruby} (les
    recettes entre autres)
  \item[Uniconf] connaît pas
  \item[Quattor] celui mentionné en son temps par Jean-Michel, utilisé
    par l'European Data Grid.
  \item[D'autres] wikipedia \emph{Comparison of open source configuration
    management software}
  \end{description}
\end{frame}

\begin{frame}{Pourquoi \emph{puppet} ?}
  \begin{itemize}
  \item version stable (2.6.4 actuellement)
  \item langage de description simple
  \item grosse communauté active
  \item de nombreux partenaires :
    \begin{itemize}
    \item RedHat
    \item Ubuntu
    \item Rackspace
    \end{itemize}
  \item utilisé par de grands groupes :
    \begin{itemize}
    \item Google, eBay
    \item Oracle, digg.com, the guardian
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{Généralités sur puppet}

\begin{frame}{\emph{Puppet}}
  \begin{itemize}
  \item \alert{C'est}
    \begin{itemize}
    \item Un système de gestion centralisée de configuration de
      machines \emph{déjà} installées.
    \item Créé par Luke Kaniés.
    \end{itemize}
  \item \alert{Ce n'est pas}
    \begin{itemize}
    \item Un outil d'installation de machines (rôle rempli par
      kickstart, dhcp, pxe, tftp, cobbler, etc.)
    \end{itemize}
  \end{itemize}
\end{frame}

% C'est pas une section très utile - à virer très probablement !
\subsection{Historique}

\begin{frame}{Luke Kanies, créateur de \emph{puppet}}
  \begin{itemize}
  \item Spécialiste de \emph{cfengine}.
  \item Contributeur de \emph{cfengine}.
  \item À fait du conseil auprès d'entreprises en utilisant
    \emph{cfengine}.
  \end{itemize}
\end{frame}

\begin{frame}{Cfengine - limitations}
  \begin{itemize}
  \item Code trop fermé (même si open source).
  \item Un seul contributeur majeur acceptant peu de patches (au goût
    de Luke Kanies).
  \item Écrit en C.
  \item Règles d'écriture laborieuses.
  \end{itemize}
  \begin{block}{Conclusion}
    \emph{Puppet} a donc été créé par Luke Kanies pour dépasser les
    limitations de \emph{cfengine}.
  \end{block}
\end{frame}

\section{Caractéristiques de puppet}

\begin{frame}{Informations générale sur \emph{puppet}}
  \begin{itemize}
  \item Écrit en Ruby ; GPL.
  \item Projet débuté en août 2005.
  \item Langage de \emph{description} de l'état des machines (quoi) et non
    comment.
  \item C'est à \emph{puppet} de converger vers l'état décrit.
  \item Volonté de l'auteur de créer une communauté forte et ouverte autour
    de ce logiciel.
  \end{itemize}
\end{frame}

\begin{frame}{Plateformes supportées}
  \begin{itemize}
  \item Linux - plusieurs distributions :
    \begin{itemize}
    \item style packets debian (debian, ubuntu)
    \item style packets redhat (fedora, redhat, centos, suze)
    \item gentoo
    \item archlinux
    \end{itemize}
  \item Solaris, HP-UX, AIX
  \item BSD (free, open, net)
  \item Mac OS X
  \item Windows (quelques débuts expérimentaux).
  \end{itemize}
\end{frame}

\begin{frame}{Composants de \emph{Puppet}}
  \begin{description}
  \item[puppet] générateur de configuration de machine (à partir des
    recettes)
  \item[puppetmasterd] serveur de configuration
  \item[facter] remontée des \alert{faits} des systèmes clients
    au \emph{puppetmasterd} (\emph{Les faits, rien que les faits !})
  \item[Dashboard] (2.6+), interface de gestion
    graphique.
  \item[puppetca] le système PKI de \emph{puppet} - gestion des clés
  \item[puppetdoc] le système de génération automatique de documentation
  \item[puppetrun] pour lancer un \emph{puppet} depuis le serveur sur
    l'une des machines clientes
  \item[ralsh] un shell pour interroger ou modifier l'état d'une machine
  \end{description}
\end{frame}

\section{Qu'attendre de l'utilisation de puppet ?}

\begin{frame}{Avantages de \emph{puppet}}
  \begin{itemize}
  \item Administration à faire sur une seule machine !
  \item facilite la mise en cohérence globale de l'infrastructure
  \item opérations standards portables entre systèmes
  \item serveur de fichiers centralisé (un peu comme rsync)
  \end{itemize}
\end{frame}

\begin{frame}{Avantages (2)}
  \begin{itemize}
  \item facilite le travail en équipe, de groupe
    \begin{itemize}
    \item suivi de règles communes
    \item aide à formaliser des manières de faire
    \item vision stratégique des machines dans leur ensemble plutôt que
      tactique au niveau de chaque machine
    \end{itemize}
  \item Le code \emph{est} la documentation (\alert{puppetdoc}).
  \item les recettes permettent de cristalliser les compétences et le
    savoir faire.
  \end{itemize}
\end{frame}

\begin{frame}{Avantages (3)}
  \begin{itemize}
  \item simplifie
    \begin{itemize}
    \item les migrations impliquant plusieurs serveurs
    \item la gestion globale (par exemple lors de changements de politique)
    \item la gestion des dépendances entre services ou composants du
      système
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Inconvénients}
  \begin{itemize}
  \item nécessite une grande attention aux détails
  \item des standards de travail plus contraignants
  \item de nouvelles façons de travailler
  \item impose des méthodes et un travail en équipe
    \begin{itemize}
    \item Gestion de version des recettes \emph{puppet}
    \end{itemize}
  \item travail de conception plus abouti
  \item nécessite de simplifier et homogénéiser les pratiques
  \end{itemize}
  \begin{block}{En résumé}
    Plus de pouvoir suppose plus de responsabilités.
  \end{block}
\end{frame}

\section{Concepts de puppet}

\subsection{Puppet, une architecture en trois parties}
\begin{frame}{Les trois parties de l'architecture de \emph{puppet}}
  \begin{itemize}
  \item Un langage \alert{déclaratif}.
  \item Une abstraction des ressources des machines. Les ressources sont
    abstraites (exemple : \emph{user} ou utilisateur, \emph{package}).
    \begin{itemize}
    \item les ressources sont donc \emph{indépendantes} du type de machine
      (que ce soit sur Linux, FreeBSD ou Solaris) ;
    \item ressource sur une machine dépend de \emph{providers} qui décrit
      spécifiquement le code pour une architecture en particulier.
    \end{itemize}   
  \end{itemize}
\end{frame}

\subsection{Les ressources}
\begin{frame}{Les ressources}
  \begin{description}
  \item[Ressources] Ce sont les objets manipulables par \emph{puppet} ayant
    un \emph{type}, un \emph{titre} et des \emph{attributs}. 
  \end{description}
  \begin{exampleblock}{Types de ressources}
    \begin{itemize}
    \item \emph{user}
    \item \emph{package}
    \item \emph{service}
    \item \emph{file}
    \end{itemize}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Les Ressources (2)}
  \begin{exampleblock}{Code}
    \begin{verbatim}
    file { "/etc/passwd":
        owner => "root",
        group => "root",
    }
    \end{verbatim}
  \end{exampleblock}
  \begin{description}
  \item[file] est le \emph{type} de ressource
  \item[/etc/passwd] est le \emph{titre} de la ressource
  \item[owner,group] sont des \emph{attributs} de la ressource
  \end{description}
\end{frame}

\begin{frame}[plain]{Puppet, comment ça marche ?}
\includegraphics{puppet-comment-ca-marche.eps}
\end{frame}

\section{Quelques types de ressources}

\begin{frame}{Les nœuds (\emph{node})}
  \begin{description}
  \item[Nœud] une machine identifiée par un nom dns complet
  \end{description}
  \begin{itemize}
  \item Des nœuds peuvent hériter d'autres nœuds - par exemple pour
    spécialiser un comportement sur une machine spécifique.
  \item Chaque nœud (machine) doit être autorisé à interroger le
    \emph{puppetmaster} grâce à une gestion de clés publiques/privées
    (\texttt{puppetca}).
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Les nœuds - exemples}
  \begin{exampleblock}{Code}
    \begin{verbatim}
    import "classes/*.pp"

    node default {
        # administrateurs
        include unixadmins
    }
    \end{verbatim}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Les nœuds - exemples (suite)}
  \begin{exampleblock}{Code}
    \begin{verbatim}
    …
    node "test.cri.uhp-nancy.fr" inherits default {
        include autres\_utilisateurs
        include logrotate, crontab, fstab, snmp, git, bashrc, ntp
    }
    \end{verbatim}
  \end{exampleblock}
  \begin{itemize}
  \item Nom du nœud entre guillemets et c'est le fqdn de la machine.
  \item Inclusion de différentes classes avec le mot-clé \alert{include}.
  \item Les classes doivent être \emph{importées} dans le fichier
    (\alert{import}) pour pouvoir être inclues dans un nœud.
  \item L'héritage incluera donc \emph{unixadmins} dans le nœud
    \texttt{test.cri.…}.
  \end{itemize}
\end{frame}

\begin{frame}{Les classes (\emph{class})}
  \begin{description}
  \item[Classe] Permet de rassembler plusieurs définitions décrivant un
    ensemble plus complexe que les types de base. C'est une sorte de type
    composé.
  \end{description}
  \begin{itemize}
  \item Comme les \emph{nœuds}, les \emph{classes} peuvent être héritées.
  \item C'est un peu la brique de base de la description d'un système.
  \item Héritage utilisé comme spécialisation pour des nœuds particuliers.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Les classes - exemples}
  \begin{exampleblock}{Code}
    \begin{verbatim}
    class ntp {
        package { "ntp": ensure => latest }
            
        file { "/etc/ntp.conf":
            owner   => "root",
            group   => "root",
            mode    => 644,
            content => template("ntp.conf.erb"),
            require => Package["ntp"],
        }
    \end{verbatim}
  \end{exampleblock}
  \begin{description}
  \item[latest] s'assure que c'est la dernière version du paquet
    qui est installée - il existe aussi le terme \alert{installed}.
  \end{description}
\end{frame}

\begin{frame}[fragile]{Les classes - exemples (suite)}
  \begin{exampleblock}{Code}
    \begin{verbatim}
        file { "/etc/ntp.conf":
            owner   => "root",
            group   => "root",
            mode    => 644,
            content => template("ntp.conf.erb"),
            require => Package["ntp"],
            notify  => Service["ntpd"],
        }
    \end{verbatim}
  \end{exampleblock}
  \begin{description}
  \item[template] pour définir un contenu paramétré.
  \item[require] pour indiquer que le paquet doit être installé avant que
    la ressource \emph{file} soit traitée.
  \item[notify] pour envoyer un message au service \emph{ntpd} en cas de
    modif.
  \end{description}
\end{frame}

\begin{frame}[fragile]{Les classes - exemples (suite 2)}
  \begin{exampleblock}{Code}
    \begin{verbatim}
        service { "ntpd":
            ensure    => running,
            subscribe => [ Package["ntp"], File["/etc/ntp.conf"] ],
        }
    }
    \end{verbatim}
  \end{exampleblock}
  \begin{description}
  \item[running] pour que \emph{puppet} s'assure que le service tourne et
    le fasse tourner si ce n'est pas le cas.
  \item[subscribe] s'inscrit aux modifications éventuelles du fichier de
    conf ou du paquet. Le service se redémarrera alors. Je ne sais pas s'il
    faut mettre à la fois \emph{subscribe} et \emph{notify}.
  \end{description}
\end{frame}


\begin{frame}{Les classes - dernières remarques}
  \begin{itemize}
  \item On peut souscrire à une classe.
  \item Les références à des objets existants ailleurs se font avec une
    Majuscule initiale (\emph{\alert{P}ackage}, \emph{\alert{S}ervice},
    etc.) contrairement à leur déclaration (en minuscule cette fois).
  \end{itemize}
\end{frame}

\begin{frame}{Les modules}
  \begin{itemize}
  \item Plutôt une structuration pratique qu'une syntaxe du langage de
    Puppet.
  \item Rassemble un ensemble de classes, de définitions, de fichiers et de
    modèles (\emph{templates}).
  \item Généralement conseillé : rassemblement de classes qui contribuent à
    la description d'un service.
  \item Considéré comme une bonne pratique de faire surtout des modules
    plutôt que de simples classes non organisées.
  \end{itemize}
\end{frame}

\begin{frame}{\emph{File} : fichiers, répertoires et liens}
  \begin{itemize}
  \item Le type \alert{file} regroupe les notions de fichier, de répertoire
    ou de lien (symbolique ou non).
  \item Permet de gérer les droits (groupe et propriétaire) mais aussi les
    autorisations d'accès (lecture, écriture, exécution, \emph{sticky bit},
    etc. (rwx).
  \item Le contenu peut provenir d'un fichier existant dans
    l'infrastructure de \emph{puppet} (\emph{filebucket}) ou être défini
    \emph{in situ} dans sa définition ou, enfin, venir d'un modèle
    (\emph{template}).
  \end{itemize}
\end{frame}

%%%%%
\begin{frame}[fragile]{\emph{File} - exemple}
  \begin{exampleblock}{Code}
    \begin{verbatim}
        file { "/etc/snmpd/snmpd.conf":
            ensure   => file,
            source   => "puppet///snmpd/files/snmpd.conf",
            require  => Package["snmpd"],
            notify   => Service["snmpd"],
            backup   => main,
            path     => "/etc/snmpd/snmpd.conf",
        }
    }
    \end{verbatim}
  \end{exampleblock}
  \begin{itemize}
  \item Plusieurs sources sont possibles. La première qui existe sera utilisée.
  \item \alert{path} : là où le fichier doit être copié sur le client.
  \end{itemize}
\end{frame}

% À virer à la fin
\begin{frame}{À virer}
  \begin{itemize}
  \item Linux
    \begin{itemize}
    \item archlinux
    \end{itemize}
  \item Windows
  \end{itemize}
\end{frame}

\end{document}
