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

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

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#

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

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:

>>> 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):

key1: val1 # this key is important
# this one too
key2: val2

YAML : structures principales#

Listes :

- obj1
- obj2

Dictionnaires clefs/valeurs :

key1: val1
key2: val2

Texte sur plusieurs lignes :

text: |
   line1
   line2

Exemple#

Un fichier yaml contenant :

- item1
- item2: value
- item3:
    key1: value
- item4:
    - key2: value

se traduit en Python par :

['item1',
 {'item2': 'value'},
 {'item3': {'key1': 'value'}},
 {'item4': [{'key2': 'value'}]}]

YAML : édition#

Pour tester du YAML : https://yaml-online-parser.appspot.com/

Coloration éditeurs :

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 :

{% for user in users %}
  - name : {{user}}
{% endfor %}
  • Tests et conditions if/elif/else :

{% if foo['bar'] == 'test' %}
  - name = something
{% else %}
  - name = otherthing
{% endif %}

Jinja2 - syntaxe (suite)#

  • Variables

{{ user }}
{{ foo.bar }}
{{ foo['bar'] }} # equivalent foo.bar
{{ alist[0] }} # pour une liste
  • Commentaires

{# 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 :

{%  %}  # 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 :

{% set msg = 'hello world' %}
{% set lst = (1,2,5,67) %}

Pour importer ou inclure avec ou sans contexte :

{% 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() %}