.. -*- coding: utf-8 -*- :orphan: ====================================== Gestion centralisée de configuration ====================================== Gestion de configuration ======================== Définir des états ----------------- * Les états sont **attribués** à des machines dans ``top.sls`` - en utilisant le *targeting* * Les états sont **déclarés** dans des fichiers ``.sls`` - organisés dans une structure arborescente, - un dossier peut être référencé par son nom si celui-ci contient un fichier ``init.sls`` Fichier ``top.sls`` - structure ------------------------------- ``top.sls`` .. code-block:: yaml base: # nom de l'environnement '*': # targeting : a qui s'appliquent les # declarations ci-dessous - state1 # ref. de fichier state à appliquer - state2 # idem - ``base`` est l'environnement de base, mais il est possible d'en définir d'autres (typiquement ``prod``, ``pre-prod``, etc.) Fichier ``top.sls`` - configuration ----------------------------------- Les environnements sont déclarés dans le fichier de configuration du *master* .. code-block:: yaml file_roots: base: - /srv/salt/ dev: - /srv/salt/dev/services - /srv/salt/dev/states Fichier ``top.sls`` - targeting ------------------------------- * Par défaut, le ciblage utilise le *globbing* sur les ``minion_id`` (comme pour les commandes) * Il est possible d'utiliser les autres méthodes de ciblage : - ``match: grain`` **(not match: grains)** - ``match: nodegroup`` - ``match: pillar`` - ``match: compound`` Fichier ``top.sls`` - exemple ----------------------------- .. code-block:: yaml base: '*': - basic 'manufacturer:Dell Inc.': - match: grain - dell 'webserv* and G@os:Debian or E@web-dc1-srv.*': - match: compound - webserver Structure d'un fichier ``.sls`` ------------------------------- Les fichiers ``.sls`` (autres que ``top.sls``) : - servent à déclarer des *states* - qui seront appliqués sur des *minions* - selon les règles de *targeting* .. code-block:: yaml deploy-and-config-ssh: # identifiant (unique) pkg: # nom du state a appliquer - installed # nom de la fonction du state a executer - name : openssh-server # argument de la fonction file.managed: # concatenation state.function # arguments passes a la fonction - name: /root/.ssh/authorized_keys # fichier résultat produit - source: salt://ssh/authorized_keys # en transformant source - template: jinja # avec moteur jinja make-sure-ssh-is-running: # identifiant service.running: # module d'état et fonction - name : ssh # nom du service - require: # declaration de dependance - pkg: openssh-server Déploiement de fichiers ----------------------- Salt inclus un serveur de fichiers, livrant des fichiers bruts, mais aussi des fichiers transformés (moteurs de template, jinja par défaut). * ``salt://dir/file.conf`` - salt file server Il est aussi possible d'utiliser ce serveur de fichier avec le module d'exécution ``cp``. YAML ==== YAML : généralités ------------------ Le format par défaut des fichiers ``.sls`` est YAML http://yaml.org/ YAML est un format de sérialisation de données lisible par des humains et indépendant du langage de programmation Les principaux types de données gérés : - nombres (entiers ou flottants) - chaînes de caractères - booléens - listes - dictionnaires (tables de correspondance) **Attention :** pour une chaîne contenant des nombres, ne pas oublier de mettre des guillemets autour (indispensable par exemple pour les permissions sur les fichiers, du type ``"0644"``) Les guillemets simples ou doubles sont automatiquement interprétés par YAML, il est cependant possible d'insérer des guillemets simples ou double dans une chaine YAML: .. code-block:: python >>> import yaml >>> yaml.load("""{a: 1, '"b"': 2}""") {'"b"': 2, 'a': 1} >>> yaml.load("""{a: 1, "'b'": 2}""") {"'b'": 2, 'a': 1} * Le yaml utilise le caractère ``#`` pour les commentaires (identique au langage python ou la plupart des langages de script): .. code-block:: yaml key1: val1 # this key is important # this one too key2: val2 YAML : structures principales ----------------------------- Listes : .. code-block:: yaml - obj1 - obj2 Dictionnaires clefs/valeurs : .. code-block:: yaml key1: val1 key2: val2 Texte sur plusieurs lignes : .. code-block:: yaml text: | line1 line2 Exemple ------- Un fichier yaml contenant : .. code-block:: yaml - item1 - item2: value - item3: key1: value - item4: - key2: value se traduit en Python par : .. code-block:: python ['item1', {'item2': 'value'}, {'item3': {'key1': 'value'}}, {'item4': [{'key2': 'value'}]}] YAML : édition -------------- Pour tester du ``YAML`` : https://yaml-online-parser.appspot.com/ Coloration éditeurs : * vim : sls.vim https://github.com/saltstack/salt-vim * emacs : ``yaml-mode.el`` (disponible dans le package debian ``yaml-mode``) * Sublime Text : https://github.com/saltstack/sublime-text * atom : https://github.com/saltstack/atom-salt * VSCode : https://code.visualstudio.com/ Templating avec Jinja2 ====================== Présentation ------------ * Jinja2 est un moteur de *template* écrit en Python * Disponible dans salt pour produire des fichiers (distribués via le protocole ``salt://path/to/file``) ou des structures de données (fichiers ``.sls``) * http://jinja.pocoo.org/ Jinja2 - syntaxe ---------------- * Boucles ``for`` : .. code-block:: jinja {% for user in users %} - name : {{user}} {% endfor %} * Tests et conditions ``if/elif/else`` : .. code-block:: jinja {% if foo['bar'] == 'test' %} - name = something {% else %} - name = otherthing {% endif %} Jinja2 - syntaxe (suite) ------------------------ * Variables .. code-block:: jinja {{ user }} {{ foo.bar }} {{ foo['bar'] }} # equivalent foo.bar {{ alist[0] }} # pour une liste * Commentaires .. code-block:: jinja {# comment #} * Gestion des espaces blancs (lisibilité du code) - par défaut, le moteur de *template* : - supprime les retours chariots simples - mais ne touche pas les espaces - on peut localement modifier ce comportement en utilisant : .. code-block:: python {% %} # pas de modification locale des espaces {%- %} # suppression des espaces avant le bloc {% -%} # suppression des espaces après le bloc Jiinja2 - set et import ----------------------- Pour définir des variables : .. code-block:: jinja {% set msg = 'hello world' %} {% set lst = (1,2,5,67) %} Pour importer ou inclure avec ou sans contexte : .. code-block:: jinja {% from "map.jinja" import apache with context %} {% include 'map.jinja' without context %} Jinja2 - variables salt disponibles ----------------------------------- Des variables sont disponibles dans les *templates* Jinja2 traités par salt permettant d'utiliser l'API de commande de salt ou les données de salt (*grains*, *pillars*, etc.) : * ``{{ grains['os'] }}`` - *grains* du *minion* * ``{{ pillar['mykey'] }}`` - *pillars* du *minion* * ``{{ pillar.get('mykey', 'default') }}`` * ``{{ pillar['pkgs']['apache'] }}`` * ``{{ salt['network.ipaddrs']() }}`` * ``{{ salt['cmd.run']('ls /dev/disk/by-id/*') }}`` * ``{{ salt['pillar.get']('pkgs:apache', 'default-value') }}`` Jinja2 - Variables dans les boucles ou les tests ------------------------------------------------ On peut boucler sur des éléments d'un dictionnaire, d'une liste ou d'une exécution salt : * ``{% for number in (1,2,5,67) %}`` * ``{% for ip in salt['network.ipaddrs']() %}`` * ``{% for disk in salt['cmd.run']('ls /dev/disk/by-id/*') %}`` * ``{% for key in dictionnary %}`` * ``{% for value in dictionnary.values() %}`` * ``{% for key, value in dictionnary.items() %}``