Inventory file (fichier d'inventaire)
Au format YAML, ce type de fichier permet de regrouper les informations nécessaires à l’exécution d’une ou plusieurs opérations. L’inventaire n’est pas obligatoire dans un processus d’automatisation, mais le devient dans le cadre d’une utilisation multihôtes/utilisateurs.
Vous organisez vos inventaires comme bon vous semble, le plus important reste que l’opération doit y avoir accès. Les fichiers d’inventaire peuvent être chiffrés avec SOPS, (plus de détails dans ce chapitre).
Cette partie utilise la commande “run”, Tous les détails sur cette commande.
Besoin d’un fichier d’inventaire ?
Le plus simple est de découvrir pourquoi un fichier d’inventaire va devenir nécessaire dans un process de production.
Cas des clés SSH protégées par mot de passe
- Une opération “OP1” est réalisée couramment sur “server1”, et exécutée comme suit :
automation run -h "server1" -op "OP1" -sshpk "private SSH key place"
- “OP1” devient nécessaire sur “server2”, j’ajoute l’hôte “server2” aux paramètres “-h”
automation run -h "server1 server2" -op "OP1" -sshpk "private SSH key place"
- Le Boss décide que la clé privée SSH utilisée pour se connecter aux serveurs “server1” et “server2” doit être protégée par un mot de passe, nous devons fournir à automation-cli le secret permettant de déchiffrer la clé privée SSH :
automation run -h "server1 server2" -op "OP1" -sshpk "private SSH key place" -sshpass "supersecret"
- Travaillant en espace partagé, le Boss s’aperçoit que l’historique des commandes bash fait apparaître le mot de passe “en clair”. Bob préconise l’utilisation de “l’espace magique” (fortement déconseillé en équipe), mais la moitié des sysadmins l’oubli, Bob propose d’écrire le secret dans un fichier et la commande se transforme en :
automation run -h "server1 server2" -op "OP1" -sshpk "private SSH key place" -sshpass "$(cat ./supersecretfile)"
- Chaque sysadmin crée maintenant son propre fichier, le secret se retrouve maintenant éparpillé sur le nœud de contrôle. La solution consiste à stocker ce secret et l’emplacement de la clé dans un fichier unique qui sera utilisé par tous les sysadmins.
automation run -h "server1 server2" -op "OP1" -i "/inventoryFile.yaml"
- Bob décide même d’ajouter ce fichier au dépôt Git qui contient toutes les opérations.
- Le Boss consulte le dépôt Git et constate que le secret, “en clair”, est désormais visible de tous ceux qui ont accès à ce dépôt !
- Bob n’avait pas encore eu le temps de lire la partie “Secrets” de cette documentation. Il convertit le fichier d’inventaire en fichier SOPS (chiffré), change le secret, et envoie le tout sur le dépôt Git.
- Le Boss constate le chiffrement du fichier dans le dépôt Git, et ne peut pas le déchiffrer, il revient donc sur la version précédente et tente de se connecter avec le secret “en clair”, mais Bob a bien fait son taf…
Cas des paramètres personnalisés
Syntaxe
En passant le commutateur “-i” aux différentes commandes le supportant, la valeur de ce commutateur est le nom d’un fichier d’inventaire, comprenant l’extension “.yaml”.
Ce chemin peut être :
- Relatif au chemin d’exécution :
./inventory.yaml
. - Absolue :
/directory1/directory2/inventory.yaml
. - Relatif à l’ OPSDirectory : “inventory.yaml” sans
./
ou/
, exemple : Si la valeur de la variable d’environnement OPS est égale à$(pwd)/OPSDirectory
alors le chemin final sera la concaténation de la valeur de OPS et du fichier :$(pwd)/OPSDirectory/inventory.yaml
.
Pour un raccourci “bash” vers la “Home directory” d’un utilisateur du serveur (~/), ne pas encadrer la valeur, exemple : -i ~/mydirectory/inventory.yaml
.
La syntaxe pour lire la valeur d’un attribut de l’inventaire est :
- ‘#inv.attribut.otherattribut’, supporte aussi l’itération sur des arrays : ‘#inv.attribut[0].otherattribut’.
- supporte aussi les variables d’environnement : ‘#inv.$USER.attribut’. L’environnement pris en compte est celui du nœud de contrôle au moment de l’exécution. Ces valeurs ne sont jamais résolues sur l’hôte.
Lorsque la valeur d’un attribut de l’inventaire est vide ou n’a pas été trouvée :
- La variable d’environnement est requise : ceci entraîne une erreur d’exécution.
- La variable d’environnement n’est pas requise : la variable d’environnement est définie avec une valeur vide, exemple : TEST="". Ceci permet de gérer confortablement la définition des variables optionnelles pour bash. Rappelez-vous, le shell final exécuté sur l’hôte comporte la commande : “set -u”, ce qui sous-entend que toutes variables utilisées doivent au préalable avoir été déclarée.
Vous pouvez aussi indiquer un attribut représentant un objet, il sera converti en chaine JSON manipulable avec ‘jq’ dans votre shell.
Exemple d’inventaire :
servers: one: ipAddress: "xxxx" two: ipAddress: "xxxx"
Si vous indiquez -e MYVAR='#inv.servers'
, la valeur extraite sera une structure JSON sur une seule ligne :
{ "one": { "ipAddress": "xxxx" }, "two": { "ipAddress": "xxxx" } }
qui peut être convertie (dans votre shell) par ‘jq’ en array :
echo "${MYVAR}" | jq 'map(select(.))|.[]'
Résultat obtenu avec ‘jq’ :
[{ "one": { "ipAddress": "xxxx" } }, { "two": { "ipAddress": "xxxx" } }]
Exemple
- Une opération “OP1” est réalisée couramment sur “server1”, et exécutée comme suit :
automation run -h "server1" -op "OP1"
- “OP1” devient nécessaire sur “server2”, j’ajoute l’hôte “server2” au paramètre “-h”
automation run -h "server1 server2" -op "OP1"
- L’opération se termine avec une erreur pour “server2”. Après analyse, un des fichiers nécessaire porte un autre nom sur “server2”, et la commande utilisée dans cette opération prévoit un paramètre permettant de spécifier l’emplacement de ce fichier.
- Création d’un inventaire de cette forme :
server1: appfile: "/var/lib/1.conf"server2: appfile: "/var/lib/5.conf"
-
Cet inventaire permet de connaître l’emplacement exact du fichier nécessaire sur chacun des serveurs.
-
Arrangeons l’opération.
-
L’opération est de type “script” (run.sh) dont le contenu est le suivant :
#!/usr/bin/env bashmycommand
- D’après la documentation, “mycommand” prévoit le paramètre “-fileplace” pour indiquer le chemin du fichier nécessaire, le script devient :
#!/usr/bin/env bashmycommand -fileplace ${FILEPLACE}
J’ai ajouté le paramètre d’opération “FILEPLACE” de type ‘string’ et dont la fonction permet de précise l’emplacement du fichier nécessaire. Ce paramètre devient “requis” pour son exécution. Modifions le manifeste de l’opération
comment: "operation OP1"scripts: - "run.sh"parameters: required: FILEPLACE: type: string comment: "file place [full path]"
- Exécutons l’opération en fournissant le fichier d’inventaire et la valeur de la variable “FILEPLACE” :
automation run -h "server1 server2" -op "OP1" -i "/inventoryFile.yaml" -e FILEPLACE='#inv.$host.appfile'
- Comment çà marche ?
- “automation-cli” détecte une variable requise par l’opération et fournie dans la ligne de commande (“FILEPLACE”) et détecte aussi le raccourci “#inv.”.
- “automation-cli” en déduit l’utilisation d’un fichier d’inventaire,
- est-il spécifié ? Oui.
- Existe-t-il ? Oui.
- L’opération peut démarrer simultanément sur chacun des hôtes.
- À la préparation, “automation-cli” substitue “$host” par l’hôte sur lequel l’opération est réalisée (“server1” ou “server2”).
- Pour “server1”, la valeur de “FILEPLACE” devient “server1.appfile”,
- lecture de l’inventaire, l’attribut ‘server1.appfile’ existe-t-il ? Oui.
- Sa valeur remplace l’originale : “FILEPLACE=‘server1.appfile’ => FILEPLACE=“/var/lib/1.conf”, si l’attribut n’existe pas, dans le fichier d’inventaire, l’opération se termine par une erreur sans même tenter l’exécution.
- L’opération est exécutée, l’opération ne se termine pas en erreur.
Créer un fichier d’inventaire
La commande pour créer un fichier d’inventaire est : “cinv”, l’option “-age” est recommandée, ceci permet de créer un fichier chiffré avec SOPS.
automation-cli cinv "[inventory yaml full path]" -age "[Your public age key]"
Exemple :
automation-cli cinv "./inventory.yaml" -age "agexxxxxxxx"
Attributs YAML prédéfinis dans le template interne
Nom | Type | Fonction |
---|---|---|
sshpk | string | chemin (absolu/relatif) de la clé privée SSH utilisée pour se connecter aux hôtes |
sshpass | string | mot de passe de la clé privée SSH |
serverGroups.all | Array | liste des hôtes tels qu’appelé par l’option -h |
Exemple d’inventaire
Résolution des hôtes par adresse IP
Ce schéma permet à “automation-cli” de résoudre les noms d’hôtes en adresse IP. Le mécanisme de fonctionnement est simple, l’utilisateur définit le ou les hôtes avec le paramètre “-h”. L’attribut “serverGroups” est une structure d’arbre, qu’il suffit de parcourir pour résoudre l’adresse IP associée à un hôte. Tous les attributs de type “array” sont des groupes, qui permettent d’organiser les hôtes. Si l’hôte final n’est pas référencé par une adresse IP, “automation-cli” utilisera le mécanisme de résolution par DNS.
sshpk: "./sshkeys/maintenance"sshpass: "mysupersecret"serverGroups: all: - sgbdr - redis - localhost controlnode: - localhost sgbdr: - postgresql1 - postgresql2 - postgresql3 redis: - redis1 - redis2 - redis3 redis1: 172.28.10.1 redis2: 172.28.10.2 redis3: 172.28.10.3 postgresql1: 172.28.50.1 postgresql2: 172.28.50.1 postgresql3: 172.28.50.1 localhost: 127.0.0.1
La résolution des hôtes se fait en parcourant l’arbre, la dernière valeur fait office de “Endpoint”. Prenons l’exemple du serveur ‘postgresql3’. Exécutez :
automation run -h "postgresql3" -op "OP1" -i "/inventoryFile.yaml"
Les rapports d’exécution mentionneront que l’opération a été réalisée sur ‘postgresql3’, les connexions SSH se feront auprès de ‘172.28.50.1’. Notez que les rapports d’exécution présentent toujours l’association ‘hôte demandé par l’utilisateur’ et ‘hôte utilisé pour la connexion SSH’.