#acl +All:read Default <<Include(Bandeau/PagePublique)>> <<TableOfContents>> = Aperçu = == Formations préalables == ## Lister les formations qu'une personne doit avoir suivi avant celle-ci pour être en mesure de comprendre les concepts * Aucune * Être minimalment familier avec l'utilisation de la ligne de commande est nécessaire (pour des participant.e.s externes, il faut savoir comment se connecter à un serveur via `ssh`) * Avoir une connaissance des concepts des logiciels de gestion de versions de code comme `git` peut aider. Par contre, nous n'utiliserons pas ces logiciels de manière pratique dans cette formation-ci. == Temps estimé == ## Combien de temps est-ce que cette formation prend habituellement. ## On vise normalement à faire des formations de 30 à 60mins == Objectifs == ## Préparer une courte liste numérotée des concepts et outils qu'on espère que les participant.e.s auront appris durant la formation * Apprendre qu'est-ce que c'est l'outil Puppet, quelle est sa fonction * Apprendre le jargon qui est utilisé autour de l'outil pour représenter certains concepts * Situer Puppet dans l'écosystème d'outils avec lequel on peut l'intégrer pour permettre la gestion d'infratructures complexes * Se familiariser avec le client Puppet et ses différences facettes * Modifier directement une machine avec puppet sans script * Avoir un premier contact en surface avec le format du code Puppet * Ecrire un premier script (manifeste) qui permet 1. d'installer un logiciel à l'aide d'un package de la distribution Linux 1. de créer un fichier de configuration 1. de s'assurer qu'un certain service est bien démarré = Préparation des participant.e.s = ## Qu'est-ce que les participant.e.s doivent préparer avant d'arriver à la formation pour pouvoir faire les exercices ## e.g. p-e préparer son setup de VMs, ou bien créer un site drupal de base... Avant la formation, chaque participant.e devrait valider ses accès aux machines virtuelles. Si vous participez à la formation et que vous ne faites pas partie de l'équipe sysadmin de Koumbit, assurez-vous d'avoir un client ssh qui soit fonctionnel: les exercices seront exécutés sur des machines virtuelles accessibles sur internet via SSH. = Préparation de la part de l'animateur.trice = '''Pour une formation à l'équipe infra de Koumbit''': * Prendre du temps avec chaque personne pour s'assurer * qu'elle a `vagrant` d'installé selon les instructions du control repository * `pm_buster` est bien démarrée * On peut voir les fichiers en NFS à partir de `pm_buster` * `pm_buster` peut appliquer un changement qui se trouve dans le control repository * Créer une branche dans le control repository qui contient un fichier `brise.pp` à la racine avec comme contenu: ## NOTE: il n'y a pas de highlight de syntaxe ici par exprès pour ne pas trop attirer l'oeil des participant.e.s vu que c'est juste un truc de préparation {{{ file { '/root/le_script_n_est_plus_brise': content => 'vous avez reussi!' mode => '0600', owdner => 'root', } }}} '''Pour les formations externes à Koumbit''': * créer une VM pico pour chaque participant.e * installer `sudo`, `tmux` et `vim-nox` * créer un compte `formation` avec un mot de passe facile à communiquer et qui a un accès sudo * installer puppet en suivant l'étape 2 (seulement) de [[PuppetConfiguration#bootstrap]] * '''important''': la VM ne devrait pas être branchée au serveur puppet en production de Koumbit * Créer une VM chiquito additionnelle qui servira de serveur puppet pour les VMs de formation * installer `sudo`, `tmux` et `vim-nox` * pas besoin d'un setup git pour le control repos.. on va monter qqch d'ultra simple * Créer une série de fichiers sous `/etc/puppet/code/environments/production` * `manifests/*.pp` : un fichier pour chaque VM de participant.e pour décrire sa node. * chaque node devrait contenir une ligne `include formation` * `modules/formation/manifests/init.pp` : une classe nommée `formation` qui a une seule ressource `file { '/home/formation/hello_world_agent': content => 'le serveur veut que votre agent ait ce fichier sur disque' }` * signer les certificats des VMs des participant.e.s * Sur chaque VM * créer un fichier `/etc/puppet/code/environments/production/brise.pp` avec le même contenu que `brise.pp` dans les instructions pour l'équipe infra * valider que puppet roule bien contre le serveur, mais en noop seulement. ne pas laisser puppet appliquer les changements (sinon deleter le fichier que ça produit) * désactiver l'agent puppet = Qu'est-ce que c'est Puppet et quel est son rôle? = Puppet c'est un logiciel qui sert de service de '''gestion centralisée de configurations'''. Comme le terme l'indique, grâce à ce logiciel on peut imposer une configuration sur des serveurs et avoir un seul point à partir d'où exercer ce contrôle. C'est une des idées fondamentales de '''l'infrastructure en tant que code''' (nous en verrons un peu plus sur ce terme dans la prochaine section). Dans l'idée précédente, par ''configuration'' on veut dire ''tout ce qui défini qu'est-ce qui s'exécute sur une machine et comment''. Donc quels logiciels sont installés, quels fichiers sont créés et quel est leur contenu pour que les logiciels se comportent de la façon dont on l'espère, mais également quels services (''daemons'') doivent être actifs. La ''gestion centralisée de configurations'' permet donc en fait '''d'automatiser l'installation et la configuration''' de serveurs. Quelques avantages remarquables par rapport à ça sont: * permet de gérer beaucoup de machines sans tout conserver la configuration de chacune dans notre mémoire d'humain (qui a tendance à oublier des choses, surtout quand une tâche est répétitive) -- ou même dans des pages de wiki qui ont un grand risque de ne pas être à jour. * représente (et documente) qu'est-ce qui est installé dans l'infrastructure * quand une machine est complètement gérée par puppet (situation idéale), on peut lire le code Puppet qu'on a écrit pour facilement voir qu'est-ce qui est installé sur cette machine là et comment. * permet la reprise en charge graduelle des serveurs, pour automatiser de manière itérative * lorsqu'on adopte Puppet comme outil de gestion, ou si on commence l'automatisation d'une machine qui n'était pas sous notre charge initalement, on peut automatiser seulement certains services et en laisser d'autres pas gérés * puppet ne '''gère que ce qui est déclaré dans le code''' * permet ainsi une reprise graduelle, un service ou un aspect de la machine à la fois. on peut donc petit à petit se rapprocher de l'objectif de la gestion automatisée complète de la machine * standardise la configuration des ordinateurs * l'installation et la configuration sont toujours faites de la même façon sans oublier d'étape * retire le besoin de configurer les systèmes à la main, donc on retire un grand risque d'erreur de manipulations Le problème de gestion automatisée de machines n'est pas un problème simple. Puppet rembli bien le rôle de représenter une configuration désirée sous forme de code, envoyer ce code du serveur aux clients, puis appliquer ce code pour que l'état désiré sur la machine soit bien en place. Par contre il nous faudra utiliser quelques logiciels additionnels pour certaines autres tâches spécifiques. Donc en fait quand on commence à utiliser Puppet, on plonge en fait dans ''une suite de logiciels inter-reliés'' qui permettent de remplir au total la fonction complexe de gestion de configuration. Nous verrons dans une section plus bas quels sont les autres logiciels qui accompagnent généralement Puppet et un peu plus bas encore comment Puppet interagit avec ces outils (nous n'aurons pas besoin nécessairement d'interagir directement avec chacun mais il est tout de même important de connaître leur existance et leur rôle). == Serveur vs. client == Puppet utilise un modèle de diffusion d'information où les agents (clients) "tirent" ("pull") leur état en demandant au serveur de leur fournir. C'est alors l'agent qui appliquera la configuration fournie par le serveur et qui fera les changements nécessaire. Donc si l'agent ne fonctionne pas, les changements ne se font pas (donc il est important de s'assurer que ce mécanisme est en bon état). Par contraste, certains autres outils qui remplissent la même fonction que puppet utiliseront un modèle où l'outil lui-même se connectera sur la machine pour y imposer ("push") la configuration et les changements. Donc puppet utilise le concept de serveur vs. client pour que les clients obtiennent leur configuration d'un seul point central. {{attachment:puppet_run_lifecycle.jpg}} 1. l'agent se connecte de manière périodique au serveur, obtient les facts de la part de `facter` et les envoie au serveur pour lui demander s'il y a des changements à appliquer 1. le serveur compile le code, qu'on appellera '''manifestes''', écrit par les administratrices.teurs sous un format plus compacte et facile pour le programme client à utiliser. Le code compilé, qu'on appellera '''catalogue''', est alors envoyé à l'agent ainsi que tout contenu de fichier nécessaire pour que l'agent puisse appliquer les changements requis. 1. l'agent applique le catalogue sur la machine où il s'exécute, puis envoie au serveur un rapport d'exécution qui indique s'il y a eu des erreurs d'application et combien, et aussi combien de temps ça aura pris à l'agent pour appliquer les changements qui amènent la machine à l'état décrit par le catalogue. 1. le serveur peut réacheminer le rapport d'exécution à un service de stockage tel que `PuppetDB` Dans le cas de Puppet, il existe des clients pour *nix (e.g. FreeBSD, OpenBSD, etc), Linux, MacOS X et Windows, donc on peut contrôler des machines de toutes ces plateformes là sous un même serveur central! == Configuration sans serveur == Comme on le verra un peu plus tard, Puppet fournit une commande qui applique des changements sans les demander à un serveur central. On peut appliquer des changements soit en donnant le code directement via un argument, soit en pointant l'outil vers un fichier qui contient le code que l'on veut appliquer. Ça veut donc dire qu'il est possible d'utiliser puppet sans le serveur centralisé. Ce genre de configuration là ne permettra par contre pas, ou bien avec plus de difficulté, l'échange d'information entre les serveurs (comme par exemple avec le modèle serveur-client on peut configurer automatiquement un service de monitoring selon quels services sont installés par puppet sur d'autres machines) == Code déclaratif == Les développeurs du logiciel Puppet ont fait un choix important dès la conception initiale de l'outil, et qui se démarque encore des outils alternatifs: l'outil s'attend à recevoir une déclaration de quel est l'état final d'une machine, et non quelles sont les instructions pour se rendre à l'état final. Donc le code Puppet utilise un modèle '''déclaratif''' -- ça veut dire que lorsqu'on écrit des ''manifestes'' on veut spécifier ce qui doit être présent sur la machine. Tout l'aspect procédural de comment changer les choses pour se rendre à l'état déclaré est caché "sous le capot". Il y du code pour chaque type de ressource qui sait comment créer, retirer et modifier les choses sur la machine pour pouvoir se rendre à l'état désiré. Donc on n'a pas besoin de savoir comment faire les changements, mais seulement de demander à puppet de les faire pour nous. Donc quand on écrit du code Puppet, on ''se soucie seulement de qu'est-ce que l'état final doit être''. Le code à nature ''déclaratif'' utilise une propriété très importante pour éviter de toujours apporter des changements à une machine: Le code a une '''idempotence d'exécution''': on peut lancer Puppet autant de fois qu'on veut et celui-ci ne devrait pas refaire les modifications si elles ne sont pas nécessaires. En d'autre mots, si une ressource correspond déjà à l'état souhaité, elle ne subira pas de changements. = L'infrastructure en tant que code (Infrastructure as Code) = Voir: https://fr.wikipedia.org/wiki/Infrastructure_as_code L'idée qui a été nommée ''Infrastructure as code'' est un concept relativement simple mais qui a permis de complètement refaçonner la nature du travail d'administration de serveurs. C'est une des idées fondatrices de ce qui est souvent appelé [[https://fr.wikipedia.org/wiki/Devops|DevOps]]. Au lieu de gérer une infrastructure à l'aide d'une série de procédures manuelles, on représente ce que cette infrastructure devrait être dans des instructions (du code) qui est exécuté par des logiciels. Le travail de gestion d'une infrastructure '''devient donc en partie du travail de développement de logiciel''' -- d'où l'idée du nom DevOps, ou la fusion entre le développement et les opérations! L'idée d'abstraire la représentation d'une infrastructure en tant que code apporte les avantages suivant: * on retire la partie répétitive de toujours faire les mêmes configurations à la main. donc moins de travail long et ennuyeux * on peut utiliser les mêmes techniques de travail que les développeurs de code comme: * la gestion de versions de code (e.g. git, svn) * les tests unitaires * l'intégration continue * la revue de code * les merge requests * réduit énormément le temps nécessaire pour la gestion d'une machine, puisque l'installation et la configuration sont automatisées * on peut donc gérer des infrastructures beaucoup plus grandes que si on le faisait manuellement * permet à toute l'équipe de lire quel est l'état des machines, et ensuite d'y apporter des changements * en général le code se trouve dans un dépôt central et donc toute l'équipe devient en mesure de voir quels changements ont été apportés à l'infrastructure en relisant les commits * si un problème survient, on peut revenir sur les modifications à la configuration via le dépot de code * surtout: comme les changements apportés aux machines sont en fait du code, les changements peuvent être répétés souvent et rapidement exactement de la même manière * donc par exemple: une fois qu'on a décrit la configuration d'un desktop, on peut en installer 10 exactement de la même manière en très peu de temps, et pourquoi pas 100, 1000! * le code peut être partagé avec d'autres pour créer des outils puissants et surtout avec moins de bugs * le partage de code est une des idées centrales du devops: favoriser la réutilisation du code plutôt que de garder ses "recettes secrètes" et réinventer la roue dans chaque compagnie différente * un outil en particulier, `hiera`, nous permettra de séparer les données spécifiques à notre infrastructure du code pour éviter de partager toutes sortes d'informations sensibles en même temps que le code. = Quels autres outils accompagnent généralement Puppet? = Comme on l'a déjà mentionné plus tôt, Puppet est généralement accompagné d'outils additionnels qui remplissent une fonction spécifique complémentaire. On peut utiliser plusieurs des outils plus bas directement sur la ligne de commande pour interroger les informations spécifiques que chacun permet d'obtenir, mais lors de l'utilisation de Puppet ces outils seront intégrés de manière transparente. Voici une liste des outils les plus communs et importants qui se rattachent à Puppet: * `facter` * extrait de l'information, nommée `facts`, par rapport à la machine qui devrait être immuable lors de l'exécution des changements par puppet * c'est un peu comme une mini base de données d'informations propres à chaque machine. Quelques exemples d'information sont: les modèles de CPUs et leur nombre, la quantité de mémoire vive, les disques et les partitions, la version du noyau Linux, la version de la distribution Linux, est-ce qu'une machine est virtuelle ou physique, etc. * `hiera` * permet de séparer le code des données, donc le paramétrage particulier à notre infrastructure se retrouve dans des fichiers à part. * le code reste ainsi plus facile à lire: on décrit seulement qu'est-ce qu'on veut sur une machine selon les données qui seraient présentes * le code n'a donc pas de données sensibles et spécifiques à notre infrastructure, ce qui veut donc dire qu'on peut partager ce code avec d'autres personnes et ainsi recevoir des commentaires et patches pour corriger certaines configurations * `PuppetDB` * note: c'est un outil qui n'est pas obligatoire, mais sans lui certaines fonctions de Puppet comme les ressources exportées ne sont pas accessibles. c'est donc un outil qu'on retrouve la grande majorité du temps en accompagnement à Puppet. * Interface abstraite sur une base de données * Permet de stocker plusieurs types d'informations comme: * les `facts` (voir `facter`) des clients * des ressources qu'on aurait exportées de certains clients et qu'on pourrait ainsi importer sur d'autres * les catalogues des clients * Offre un langage de recherche spécialisé via une interface (API) REST * On peut ainsi récupérer plusieurs informations et les combiner pour avoir une meilleure compréhension de notre infrastructure * permet de créer des rapports avec une vue globale par rapport à l'état de l'infrastructure * On peut ainsi tisser des liens entre les données de toutes les machines * Comme on peut inspecter les catalogues (code compilé), on peut également connaître qui et combien de machines utilisent certaines portion du code (e.g. certaines classes) * super outil pour quantifier certaines portions de notre infrastructure p-e par rapport à des projets en cours ou bien qu'on voudrait commencer dans pas longtemps (e.g. Nous visons terminer la mise à jour vers la version X du logiciel `foo`. Nous avons déjà terminé la mise à jour de Y serveurs mais il nous en reste encore Z de la version précédente) * Deux exemples de requête pour puppetdb, en mots: * Combien existe-t-il de machines qui utilisent la version 9 de debian, et ce sont lesquelles? * Combien de plateformes physiques différentes existent dans l'infrastructure et ce sont lesquelles? Est-ce qu'on utilise plusieurs fabricant, plusieurs modèles différents? * `git` * Il est très fortement conseillé de conserver le code puppet dans un outil de gestion de versions de code et `git` est le plus populaire * C'est grâce à ce type d'outil qu'on peut réutiliser plusieurs méthodes bien établies dans le domaine du développement logiciel * `puppet-strings` (pas obligatoire) * Outil qui cumule les commentaires qui sont au haut des fichiers et qui suivent un certain format particulier (format `YARD`) pour produire des pages HTML de documentation technique du code. * `Puppet Bolt` (pas obligatoire) * permet l'exécution de scripts sur les serveurs sans avoir absolument besoin de la présence de Puppet * `Bolt` permet d'automatiser les changements qui sont plus ponctuels. Par exemple: * redémarrer un serveur * créer un snapshot LVM * remplacer un disque par un autre dans un array RAID * `Puppet Dashboard` (pas obligatoire) * Interface web pour visualiser les agents puppet et leur configuration. Permet de consulter différentes informations par rapport aux agents comme les rapports d'exécution et les `facts` * Peut également être utilisé pour la configuration des agents via l'assignation d'un rôle pour un agent * Koumbit n'utilise pas cette interface = Jargon utilisé autour du logiciel Puppet = {{attachment:puppet_software_blocks.jpg}} agent:: Client Puppet. C'est le logiciel qui roule sur la majorité des machines et qui demande au serveur de lui fournir son code de configuration. C'est également l'agent qui applique les modifications nécessaires selon ce que le serveur a spécifié. serveur:: (était anciennement nommé `puppet master`) point central de l'infrastructure qui fournit aux clients la configuration. Cette machine est spéciale et contient beaucoup d'information sensible (puisqu'elle connaît toute la configuration, les mots de passe, les certificats, etc.) de toutes les machines. On veut donc s'assurer de la protéger de manière stricte! manifest:: nom donné aux fichiers qui contiennent du code Puppet. Ces fichiers auront normalement une extension `.pp`. Les manifests sont utilisés pour décrire plus qu'une seule machine: le même code peut s'adapter selon différentes valeurs, soit provenant des `facts`, soit de `hiera` catalogue:: C'est le code Puppet qui est propre à une seule machine et qui a été compilé à partir des manifests. un catalogue est un format de type `byte-code` du code Puppet. L'agent peut utiliser le catalogue pour appliquer les changements qui lui sont nécessaires. Comme un catalogue est spécifique à une machine, chaque agent ne connaît pas les configurations des autres machines fact:: une donnée extraite par l'outil `facter`. cette donnée ne changera pas durant la compilation du catalogue et elle peut être utilisée par le code pour créer des configurations différentes selon les valeurs des `facts`. Les `facts` sont disponible dans le code sous la variable globale `$facts` (tableau de données) ressource:: Bloc de construction de base dans le code Puppet. Chaque ressource représente une chose qui doit être présente sur la machine où l'agent s'exécute. Plusieurs types de ressources existent déjà dans Puppet, et on peut en créer des nouveaux. ressource exportée:: Représentation d'une ressource dans une structure de données qui est sauvegardée dans la base de données de `PuppetDB`. On peut ensuite importer cette ressource sur une ou plusieurs autres machines. (dans la documentation, l'importation est nommée '''collecting resources''') paramètre:: une paire de clef et valeur qui modifie le comportement d'une ressource. C'est un peu comme un paramètre de fonction dans du code: la clef identifie ce qu'on modifie, et la valeur nous permet de donner une valeur différente pour chaque ressource. classe:: type de ressource de base qui est utilisé dans les manifests pour regrouper plusieurs autres ressources ensemble dans un bloc logique. Identifié dans le code par le mot `class`. C'est un conteneur pour du code plus précis. Une classe n'est traitée qu'une seule fois par machine lors de la compilation des catalogues -- ça nous assure ainsi qu'un certain groupe de ressources est présent, mais pas plus d'une fois. Les classes peuvent avoir des paramètres, défini dans le code lors de la construction de la classe, pour modifier son comportement. types de données:: les paramètres des ressources peuvent être contraint à utiliser un certain type de données en particulier. si on rend le type de données le plus spécifique possible, ça nous permet de réduire les imprévus dans le code. Il existe plusieurs types de données de base dans Puppet, et on peut également en créer de nouveaux en combinant les types de bases. Le module `stdlib` écrit par Puppetlabs contient plusieurs types complexes additionnels qui sont très pratiques (par exemple pour représenter une chaîne de caractères qui devrait être une adresse IP) type défini:: type de ressource de base qui regroupe plusieurs autres ressources ensemble. ''attention! ici on se réfère à un type de ressource alors que les `types de données` se réfèrent à des paramètres (la surcharge du mot "type" peut facilement devenir mélangeante)''. identifié dans le code par le mot `define`. C'est très similaire à une classe! Mais la différence est qu'un type défini peut être utilisé plusieurs fois dans une même machine dans le but de déclarer plusieurs choses différentes. Un exemple de cas d'utilisation pourrait être un `vhost apache`. tout comme pour les classes, les types défini peuvent avoir des paramètres définis dans le code qui permettent d'en modifier le comportement fonction:: Code, généralement écrit en ruby, qui permet de modifier une certaine donnée. Par exemple on pourrait utiliser la fonction `join()` pour prendre toutes les valeurs d'un tableau de données et les coller ensemble dans une seule chaîne de caractères avec chaque valeur séparée par un délimiteur. Les fonctions sont exécutées sur le serveur puppet lors de la compilation du catalogue. module:: regroupement de manifests, de définitions de fonctions, et d'autres fichiers pour former un bloc logique de code. Le plus souvent un module représente tout ce qui est nécessaire pour l'installation et la configuration d'un logiciel particulier. Par exmple le module `mysql` installe et configure `mysql`. = Exercice: Découvrir de l'information à propos d'une machine à l'aide de facter = On peut lancer manuellement l'outil `facter` pour découvrir les mêmes informations à propos d'une machine que Puppet trouverait lors de son exécution. On peut demander une information précise: {{{#!highlight bash numbers=disable facter processors.count }}} {{{#!wiki tip On peut séparer les noms des valeurs demandées par un `.` ce qui veut dire dans l'élément de gauche, chercher l'élément de droite, e.g. l'élément `processors` est en fait un tableau de données qui contient un élément qui s'appelle `count`. }}} {{{#!highlight bash numbers=disable facter }}} Sans donner de nom de valeur, on obtient toutes les valeurs connues par facter. Trouver dans la réponse de la commande: * la taille des différentes partitions de disques sur la machine * le modèle de CPU Demander à facter seulement la valeur de la version majeure de la distribution linux du système. * quel argument avez-vous donné à la commande `facter` pour obtenir cette information? Lorsque puppet demande de l'information à facter, certaines informations additionnelles sont affichées. On peut demander à facter de nous les afficher en ajoutant un argument: {{{#!highlight bash numbers=disable facter -p }}} Identifier la version de puppet dans la réponse de l'outil {{{{#!wiki tip Il est à noter: toutes les valeurs qui sont présentes dans la réponse de la commande `facter` sont accessibles au code puppet à travers la variable globale `$facts`. Pour accéder à un fact spécifique dans du code puppet, on doit utiliser des crochets pour accéder à un élément du tableau. Dans les quelques exemples suivant, on utilise la ressource de type `notify` pour afficher le contenu de la variable sur le terminal dans la réponse du client puppet: {{{#!highlight puppet numbers=disable notify { $facts['package_provider']: } # identifie le logiciel qui est utilisé pour l'installation de packages notify { $facts['processors']['count']: } # le nombre de processeurs dans la machine }}} }}}} = Comment est-ce que Puppet communique avec les différents outils? = {{attachment:puppetmaster_components.jpg|Relations entre le puppetmaster et les autres sources de données}} '''Communication entre agent et serveur''' * HTTPS sur le port 8140 avec l'aide de certificats ''clients'' pour l'authentification en plus d'un certificat ''serveur'' * exactement le même type de certificats qu'on utilise pour HTTPS. Par contre les certificats des clients doivent être signés par le serveur * le serveur agit comme Certificate Authority (CA) envers les agents '''facter''' * lancé localement par l'agent puppet '''hiera''' * utilisé localement par le serveur puppet lors de chaque compilation de catalogue * hiera version 5 est en fait du code ruby qui est inclus dans Puppet '''PuppetDB''' * Le serveur Puppet communique avec PuppetDB via HTTPS sur le port 8081 '''git''' * Puppet n'interagit pas directement avec l'outil, mais utilise simplement les fichiers que celui-ci présente dans un répertoire donné sur le serveur = Exercice: Se familiariser avec l'agent (client) Puppet = L'outil de ligne de commande de Puppet s'appelle `puppet` (tout en minuscules). `puppet` offre des détails sur comment on peut l'utiliser: {{{#!highlight bash numbers=disable # Cette commande vous offre une série de sous-commandes possibles à utiliser. puppet --help # Pour obtenir de l'aide à propos d'une des sous-commandes, on peut utiliser la sous-commande 'help': puppet help agent puppet help apply }}} Comme le nom de la sous-commande l'implique, `agent` permet de rouler en tant qu'un agent, et donc d'obtenir les modifications à partir d'un serveur central. {{{#!highlight bash numbers=disable # en premier lieux, on veut activer l'agent, qui a été désactivé pour le début de la formation # en temps normal, l'agent devrait rester activé en tout temps, sauf si on veut explicitement # mettre l'agent sur pause pour investiguer quelque chose sur la machine et éviter que puppet ne # change quelque chose pendant notre investigation puppet agent --enable # lancer l'agent. l'option -t active la trace des activités de l'agent à l'écran puppet agent -t` ## Constater ici dans la réponse les différentes étapes suivies par l'agent ainsi que qu'est-ce qui a été modifié }}} La sous-commande `apply` permet de faire des modifications sur la machine en utilisant du code soit passé en argument, soit via un fichier qui se trouve sur la machine même (contrairement au cas de l'agent où les fichiers de code se trouvent obligatoirement sur le serveur). {{{#!highlight bash numbers=disable # -e permet de donner le code sur la ligne de commande puppet apply -e 'file { "/tmp/hello_world": ensure => present, content => "mon premier fichier"}' ## Constatez que le fichier a bel et bien été modifié sur la machine. # Donc il faut faire attention si on test quelque chose via `puppet apply` puisque le changement est vraiment appliqué. # on peut ajouter --noop à la commande pour que `puppet apply` n'effectue pas les changements de mandés sur la machine. # l'outil affiche alors seulement quels seraient les changements qui auraient été appliqués, mais sans les faire. }}} {{{#!highlight bash numbers=disable # ici au lieu d'utiliser -e, on donne un nom de fichier (qui existe présentement sur disque) # pour que le code dans ce fichier soit appliqué puppet apply /etc/puppet/code/environments/production/brise.pp ## Ce fichier nous donne une erreur! Constater quel est le format de cette erreur et tenter de corriger cette erreur ## Le fichier comprend en effet plusieurs erreurs. Continuez d'appeler `puppet apply` pour vérifier quelles nouvelles erreurs ## l'outil affiche et tentez de les corriger dans le fichier, jusqu'à ce que puppet effectue les changements sans erreur }}} En utilisant `puppet apply -e '...'` comme plus haut, et en vous basant sur les exemples dans la section d'exercice par rapport à `facter`, affichez la capacité totale de mémoire système (RAM). = Quelques exemples simples de structures du langage Puppet = On plongera beaucoup plus en détail dans le langage de programmation Puppet dans la [[FormationPupppetDSL]]. Cependant, pour pouvoir commencer à explorer puppet tout de suite, nous verrons ici quelques idées de base qui nous permettront d'exprimer les choses les plus imporantes: déclarer une ressource et ordonnancer l'application des changements pour chacune. == Commentaires == Comme dans tous les langages de programmation, il est très utile d'ajouter des commentaires dans le code que l'on écrit pour offrir des explications additionnelles comme par exemple pourquoi certains cas spéciaux devraient être présent ou encore quel est le comportement qu'un paramètre modifie et quelles en sont les valeurs possibles. Les commentaires dans le code Puppet commencent par un dièse `#`. On peut placer un dièse en début de ligne pour avoir toute une ligne en commentaire, ou alors placer un dièse à la droite d'une ligne de code pour ajouter un commentaire sur la même ligne que le code. Par exemple (ici les mots `@summary` et `@param` sont utilisés par l'outil `puppet-strings` pour créer la documentation pour un fichier de code): {{{#!highlight puppet numbers=disable # @summary Ce commentaire décrit en général ce que le bloc de code fait, et comment on peut # modifier son comportement. # # @param blah # Nombre entier qui permet de spécifier combien de `blah` se retrouvent dans le fichier de configuration `foo` # class foo ( Integer $blah = 1, # 1 ici c'est la valeur par défaut si "blah" n'est pas spécifié ) { # ... } }}} == Ressources de base dans Puppet == Puppet contient déjà du code pour représenter plusieurs types de choses dans un ordinateur. La liste complète est [[https://puppet.com/docs/puppet/6/type.html|visible dans la documentation de puppet]] (C'est une page très utile à garder en marque-page) Avec les types de ressources de base, on peut déjà configurer une grande majorité des services possibles. On peut également créer des types de ressources plus complexes qui contiennent plusieurs ressources de base d'une certaine façon spécifique (à l'aide de classes et types définis). Nous verrons ces ressources complexes dans une formation future. Les ressources de base qui sont utilisées de manière la plus commune sont, en ordre: * file * un fichier ou un répertoire qui devrait être présent sur le serveur ou absent sous un certain chemin. on peut gérer ses permissions, p-e définir son contenu {{{#!highlight puppet numbers=disable file { '/chemin/vers/le/fichier': ensure => present, owner => 'root', mode => 0700, content => 'Cette chaîne de caractères remplacera entièrement le contenu du fichier', } file { '/etc/logiciel/configuration_bogus.conf': ensure => absent, } }}} * package * un logiciel devrait être présent sur l'ordinateur. on peut l'installer à l'aide des packages de la distribution {{{#!highlight puppet numbers=disable package { 'borg': ensure => present, } }}} * service * un service devrait être soit actif, soit désactivé sur une machine {{{#!highlight puppet numbers=disable service { 'apache2': ensure => running, } }}} * user * un certain utilisateur devrait être présent sur la machine {{{#!highlight puppet numbers=disable user { 'farah': ensure => present, uid => 1030, gid => 901, groups => ['adm', 'sudo', 'libvirt'], home => '/home/farah', shell => '/bin/bash', password => '$6$.....', } }}} * group * un certain groupe d'utilisateurs devrait exister sur la machine {{{#!highlight puppet numbers=disable group { 'admins': ensure => present, gid => 901, } }}} * cron * une tâche périodique devrait exister et appeler une certaine commande à un horaire défini {{{#!highlight puppet numbers=disable cron { 'cleanup': ensure => present, command => '/usr/local/bin/cleanup_my_mess', user => 'root', hour => 1, minute => 35, } }}} * ssh_authorized_key * une clef publique SSH devrait permettre l'accès à un certain utilisateur de la machine {{{#!highlight puppet numbers=disable ssh_authorized_key { 'gontrand@desktop301': ensure => present, user => 'adminweb', type => 'ssh-rsa', key => 'AAA......qXfdaQ==', } }}} * exec * une commande devrait être exécutée sur la machine * dernier recours: il est très facile de représenter une commande qui sera exécutée à chaque fois que le client Puppet s'exécute malgré que celà n'est pas nécessaire. Il est généralement préférable d'utiliser un des types de base ou même un type plus complexe pour représenter l'état des choses sur une machine. quelques fois par contre c'est inévitable. {{{#!highlight puppet numbers=disable exec { 'activate_license': command => '/opt/proprietary_softwareY/bin/active_license', creates => '/opt/proprietary_softwareY/etc/license_file', } }}} == Relations d'ordre entre les ressources == Dans le code Puppet on déclare qu'est-ce qui devrait être contenu dans une machine. Mais des fois, il faut absolument qu'une chose existe avant qu'une autre puisse exister. Par exemple, avant de pouvoir configurer un logiciel, il faut que celui-ci soit installé. On peut déclarer l'ordre entre deux ressources en utilisant l'opérateur `->` (`flèche à droite`) entre les deux ressources. Ça indique à Puppet que la ressource qui précède (est à gauche de) la flèche doit être traitée avant celle qui suit la flèche. Par exemple: {{{#!highlight puppet numbers=disable # Le répertoire my.conf.d doit exister pour qu'on puisse créer des fichiers dedans file { '/etc/mysql/my.conf.d': ensure => directory, owner => 'root', group => 'mysql', mode => '0700', } -> file { '/etc/mysql/my.conf.d/tuning.conf': ensure => present, owner => 'root', group => 'root', mode => '0640', } }}} On peut également avoir une relation d'ordre qui en plus '''envoie un signal''' à la ressource qui suit la flèche. On utilise pour ceci une flèche avec un tilde au lieu du tiret, `~>`. Ce ne sont pas tous les types de ressources qui réagissent à un signal. Le plus commun type de ressource utilisé avec ce type d'ordonnancement est `service`. Lorsqu'un changement est apporté à la ressource précédent un `service` dans une relation de flèche avec tilde (avec signal), le service sera alors redémarré automatiquement. Ça nous assure ainsi que les changements que puppet a apporté à la configuration seront pris en compte immédiatement par un service. {{{#!wiki tip Le `service` dans ce cas ne sera pas redémarré dans les cas où Puppet considère qu'aucun changement n'a été nécessaire aux ressources précédent les flèches avec tilde (donc si la configuration ne change pas, on ne redémarre pas le service pour rien) }}} Par exemple: {{{#!highlight puppet numbers=disable file { '/etc/apache2/conf-enabled/security.conf': ensure => link, target => '/etc/apache2/conf-available/security.conf', } ~> service { 'apache2': ensure => running, } }}} Avec les deux types de flèches, on peut utiliser l'opérateur flèche plusieurs fois pour définir des relations de plusieurs ressources avec une seule ressource finale. On peut donc par exemple s'assurer que plusieurs fichiers de configuration devront exister avant qu'un service soit lancé et également que le service soit redémarré si n'importe lequel des fichiers de configuration subit une modification. Nous verrons les relations d'ordonnancement plus en détail dans une formation future. = Quelques outils alternatifs à Puppet = * ansible * mgmt * salt stack * chef = Exercice: Ecrire un premier script = * créer un fichier `test.pp` et utiliser les ressources de base pour: 1. installer le package `mariadb` 1. créer le fichier de configuration `/etc/mysql/conf.d/my_config.cnf` avec comme contenu {{{#!highlight ini numbers=disable [mysqld] max_connections=100 }}} 1. s'assurer que le service `mariadb` est bien en marche * Assurez-vous d'ordonnancer les ressources entre elles pour que les opérations puissent toutes se faire en une seule passe. L'ordre devrait être le même que les points plus haut. * la relation d'ordonnancement entre le fichier de configuration et le service devrait utiliser un signal pour redémarrer le service lorsqu'il y a un changement au fichier de configuration * appliquer le script `test.pp` avec `puppet apply test.pp` * Constater dans la réponse que les changements attendus ont bel et bien eu lieu. Voilà, vous avez reproduit le pattern qui est utilisé dans environs 80 à 90% des cas pour la gestion de différents logiciels sur les serveurs! :) Dans le cas de la gestion via le serveur, la différence c'est simplement que le fichier manifeste, `test.pp`, devrait se trouver au bon endroit sur le serveur au lieu du client, et à ce moment on l'applique en appelant `puppet agent -t`. <<Include(Rétrospective)>> = Information complémentaire = ## Donner quelques idées d'informations que les participant.e.s peuvent investiguer par eux/elles-mêmes pour approfondir leurs connaissances * [[https://puppet.com/docs/puppet/5.5/architecture.html|Vue d'ensemble sur l'architecture de l'application Puppet]] * [[https://puppet.com/docs/puppet/5.5/type.html|Documentation des types de ressources de base]] * [[https://puppet.com/docs/puppet/5.5/function.html|Documentation des fonctions]] * [[https://puppet.com/docs/puppet/5.5/core_facts.html|Liste des facts de base de facter]] * [[https://puppet.com/docs/puppet/5.5/hiera_intro.html#concept-7256|Vue d'ensemble de Hiera]] * [[https://puppet.com/docs/puppetdb/latest/index.html|Vue d'ensemble de PuppetDB]] * formations suivantes: * FormationPuppetDonnéesHiera * [[FormationPuppetDSL]] * FormationPuppetModules ---- CategoryFormation CategoryFormationPublique