Ansible trébuche rapidement en essayant de faire quelque chose d'un peu différent de l'exemple de la documentation. Je soupçonne que ce mur Ansible est dû au fait que vous ne pouvez pas voir l'image entière. Au fur et à mesure que vous l'utiliserez, vous verrez progressivement l'image dans son ensemble, mais il est souvent nécessaire de la connaître plus tôt. Je vais le laisser comme mon propre mémo, comme la structure pour une vue d'ensemble de la situation dans son ensemble, mais j'espère que cela sera utile à d'autres personnes autant que possible.
Au minimum, si vous comprenez 1. la notation de configuration d'Ansible, 2. le fichier de configuration ansible.cfg, 3. Inventory et 4. Playbook, vous devriez pouvoir utiliser ansible. Je vais. (Il existe des conditions préalables telles que les paramètres SSH.)
Au fur et à mesure que vous l'utiliserez, vous pourrez gérer plusieurs tâches collectivement et les réutiliser plus souvent. La section 5 décrit comment utiliser ansible en utilisant la structure de répertoires.
Enfin, je décrirai comment l'utiliser avec Raspberry Pi3 en bonus.
Dans les paramètres Ansible, format YAML et format INI Vous pouvez utiliser E3% 82% A1% E3% 82% A4% E3% 83% AB) (notation INI étendue qui autorise «#» dans les commentaires). Bien que vous puissiez écrire de manière flexible en étant capable d'écrire les deux, ce sera déroutant lorsque vous l'utiliserez pour la première fois car il n'est pas uniforme.
C'est une bonne idée de garder à l'esprit les règles suivantes.
* .cfg
, fichier sans extension
est au format INI* .yml
et * .yaml
sont au format YAMLIl se compose d'un «nom de section» entre «[]» et d'un «paramètre» décrit par «=».
Vous pouvez mettre des espaces, TAB, etc. avant et après =
.
ini:./ansible.cfg
[defaults]
host_key_checking = True
#Vous pouvez écrire des commentaires clairement
[privilege_escalation]
become_ask_pass = True
;Vous pouvez écrire un commentaire avec un point-virgule
[ssh_connection]
scp_if_ssh = False
Après =
, sauf pour les booléens True / False et yes / no, il est traité comme une "chaîne de caractères" jusqu'à la fin de la ligne.
Si vous le placez entre «» «etc.,« »« lui-même peut être interprété comme faisant partie de la chaîne.
Séparez les "listes" (tableaux) par des virgules (,
).
L'énumération des «noms» séparés par «:» est appelée «scalaire».
Scalaire
name1:
name2:
:
nameN:
Si vous énumérez sans préfixer -
, il devient" serial "(simple énumération," scalaire ").
Vous pouvez écrire la valeur après «:». Aussi appelé un type de dictionnaire, cela s'appelle un «mappage» en YAML.
cartographie
name1: aaaa
name2: bbbb
:
nameN: cccc
Si vous le préfixez avec -
, il devient une liste (tableau). En YAML, cela s'appelle une "séquence".
séquence
- name1:
- name2:
- nameN:
L'indentation représente une hiérarchie, appelée "collection".
Utilisez des espaces pour l'indentation. Veuillez noter que l'utilisation de TAB telle quelle entraînera une erreur.
(Si vous utilisez vi / vim, le définir avec set expandtab
remplacera TAB par des espaces)
Exemple-playbook-samle1.yml
- name: the 1st Example
hosts: 172.17.0.2
tasks:
- name: Hello, World!
debug:
- name: Next debug
debug: msg="Hello, Ansible!"
Dans cet exemple, name: the 1st Example
, hosts: 172.17.0.2
, tasks:
sont au même niveau de paramètres scalaires (parallèles (séquentiels)), -name: Hello, ansible
, -name: Next. La partie debug
est la séquence (liste (tableau)). C'est un mappage, chacun avec une valeur.
tâches
est une collection.
Je vois souvent le format YAML avec «---» (trois tirets) au début.
C'est parce que la structure de YAML est censée commencer un bloc de définition avec «---» et se terminer par «...» (trois points).
Vous pouvez écrire plusieurs blocs dans un fichier avec «---», mais en général, ansible n'utilise pas une telle structure.
Vous pouvez penser qu'il est prudent d'ajouter «---». La réécriture du playbook-samle1.yml
ci-dessus entraînera ce qui suit.
playbook-samle1.yml
---
- name: the 1st Example
hosts: 172.17.0.2
tasks:
- name: Hello, World!
debug:
- name: Next debug
debug: msg="Hello, Ansible!"
Voir aussi: Paramètres de configuration Ansible - Documentation Ansible (https://docs.ansible.com/ansible/latest/reference_appendices/config.html)
Puisque l'extension du fichier de configuration est .cfg
, il est décrit au format INI.
Les commandes liées à Ansible recherchent les fichiers de configuration dans l'ordre suivant, et le premier fichier de configuration trouvé est utilisé.
(
. / Ansible.cfg`) dans le répertoire courant.ansible.cfg
( ~ / .ansible.cfg
ou `$ HOME / .ansible.cfg)ansible.cfg
[defaults]
inventory = ./inventory
interpreter_python = /usr/bin/python3
#deprecation_warnings = False
[privilege_escalation]
become_ask_pass = yes
[ssh_connection]
scp_if_ssh = False
Voir: Comment créer votre inventaire - Documentation Ansible Afin d'exécuter la commande ansible et d'utiliser le playbook décrit plus loin, il est nécessaire de préparer un fichier appelé Inventory qui décrit l'hôte à exploiter. En un mot, c'est comme une collection de fichiers / etc / hosts.
-i
spécifie le fichier d'inventaire ou le répertoire où se trouve le fichier d'inventaire. Vous pouvez omettre l'option en la définissant dans le fichier de configuration. (Paramètre ʻinventory dans la section [
defaults`])* .py
et * .sh
peuvent être spécifiés et configurés dynamiquement au moment de l'exécution (doivent être renvoyés dans le format correct).myhosts1
myhost1
172.17.0.2
Le plus petit fichier d'inventaire ne contient qu'une seule adresse IP (hôte).
myhosts2
myhost2
172.17.0.2
172.17.0.3
[group1]
172.17.0.2
172.17.0.3
[group2]
172.17.0.[3:7]
[my_all:children]
group1
group2
children
est un ** mot réservé ** et est utilisé pour spécifier un groupe d'enfants.[nom du groupe: vars]
décrit les variables qui s'appliquent au groupe. vars
est un ** mot réservé **.Au lieu de la spécification du module ad hoc (= single-shot) et de l'opération de ʻansible -m ping host pattern`, spécifiez un fichier de configuration appelé playbook pour effectuer une série d'opérations. Le format du playbook est généralement le format YAML.
playbook-sample1.yml
- name: the 1st Example
hosts: 172.17.0.2
tasks:
#Les tâches sont répertoriées(séquence)Précisez avec.
#Afficher le message par défaut dans le débogage.
- name: Hello, World
debug:
#Afficher le message spécifié dans le débogage.
- name: Next debug
debug: msg="Hello, Ansible!"
Pour exécuter le playbook, vous devez spécifier un fichier d'inventaire.
myhosts1
172.17.0.2
$ ansible-playbook -i myhosts1 playbook-sample1.yml
PLAY [the 1st Example] *************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [172.17.0.2]
TASK [Hello, World] ****************************************************************************************************
ok: [172.17.0.2] => {
"msg": "Hello world!"
}
TASK [Next debug] ******************************************************************************************************
ok: [172.17.0.2] => {
"msg": "Hello, Ansible!"
}
PLAY RECAP *************************************************************************************************************
172.17.0.2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Voir: Roles - Ansible Documentation En utilisant la structure de répertoires suivante, il sera plus facile de spécifier des fichiers et des tâches.
./
├─ ansible.cfg ……………………………… (1)Fichier de configuration. Variable d'environnement ANSIBLE_Dans CONFIG
│ Nom fixe sauf indication contraire.
├─ playbook.yml ……………………………… (2)Playbook Tout nom de fichier. Le format YAML est courant.
│
├─ inventory/ …………………………………… (3)Répertoire d'inventaire. Doit être spécifié,
│ │ N'importe quel nom. Spécifiez en option.
│ ├─ hosts …………………………………… (4)N'importe quel nom. Format INI sans extension,
│ ├─ hosts2.extension yml.Format YAML pour yml.
│ ├─ :
│ └─ hostsN
├─ group_vars/ ………………………………… (5)Variables qui s'appliquent au "groupe d'hôtes cible" de la tâche spécifiée
│ │ Le répertoire à stocker. Nom fixe.
│ ├─ groupname1 ……………………… (6)Définissez le nom du "groupe d'hôtes cible" sur le nom du fichier. Format INI sans extension,
│ ├─ groupname2.S'il est au format yml YAML, l'extension.Faites-le yml.
│ ├─ :
│ └─ groupnameN
├─ host_vars/ …………………………………… (7)Variables qui s'appliquent à "l'hôte cible" de la tâche spécifiée
│ │ Le répertoire à stocker. Nom fixe.
│ ├─ hostname1 ………………………… (8)Définissez le nom «hôte cible» sur le nom de fichier. Format INI sans extension,
│ ├─ hostname2.S'il est au format yml YAML, l'extension.Faites-le yml.
│ ├─ :
│ └─ hostnameN
├─ files/ ……………………………………………… (9)Stockage de fichiers utilisé pour la copie et le transfert. Nom fixe.
│ ├─ file1 ……………………………………(10)Tout nom de fichier.
│ ├─ file1
│ ├─ :
│ └─ fileN
└─ roles/ ………………………………………………(11)Répertoire des paramètres pour l'utilisation des rôles dans les playbooks. Nom fixe.
├─ role1/ ……………………………………(12)Définissez le nom du "rôle cible" sur le nom du répertoire.
├─ role2/
├─ :
└─ roleN/
├─ defaults …………………(13)Le répertoire qui stocke les paramètres de variable par défaut. Nom fixe.
│ └── main.yml ……(14)Le fichier de paramétrage de variable chargé en premier. Nom fixe.
│ import_Comme les vars, il est chargé lorsque le playbook est analysé.
├─ vars ……………………………(15)Un répertoire qui stocke les paramètres de variable. Nom fixe.
│ │ Répertoire de base lors de la spécification d'un fichier avec un chemin relatif.
│ ├─ varfile1 ……(16)Tout nom de fichier. Format INI sans extension,
│ ├─ varfile2.S'il est au format yml YAML, l'extension.Faites-le yml.
│ ├─ :
│ └─ varfileN
└─ tasks …………………………(17)Répertoire de stockage des tâches. Nom fixe.
└── main.yml ……(18)Le premier fichier de configuration de tâche à exécuter. Nom fixe.
Si vous souhaitez modifier le traitement en fonction du système d'exploitation de l'hôte cible,
main.importer depuis yml/Lire avec include.
Il existe d'autres rôles dans les répertoires tels que handlers /
, templates /
et meta /
, mais pour le moment, si vous comprenez la structure de répertoires ci-dessus, il sera plus facile de comprendre les autres répertoires également. ..
Voir «Roles - Ansible Documentation» pour plus d'informations. Il existe également un exemple dans "Bonnes pratiques: mise en page de répertoire - Documentation Ansible".
Voir: Inclure et importer - Documentation Ansible L'import * et l'inclusion * sont les mêmes pour la lecture des fichiers, mais ils sont lus à des moments différents.
- All import* statements are pre-processed at the time playbooks are parsed.
- All include* statements are processed as they are encountered during the execution of the playbook.
Il est particulièrement important de savoir quand traiter les variables (par exemple, le modèle {{samplevarname}}) en utilisant le modèle JINJA2 et quand les affecter aux variables.
Si vous utilisez import *, il est développé avant que la tâche ne soit exécutée, de sorte que le modèle intégré est remplacé par la valeur réelle et la tâche est exécutée une fois l'affectation à la variable terminée.
D'autre part, si vous utilisez include *, il sera développé lors de l'exécution de la tâche, donc quand il sera chargé et exécuté, le modèle sera remplacé par la valeur réelle et l'affectation sera effectuée.
Ansible est utilisé dans l'environnement Python, mais si vous installez Ansibule basé sur le système d'exploitation (apt / apt-get install) sur Ubuntu (stretch 9) de Raspberry Pi3, la version 2.2 d'Ansible sera installée (écrite le 13 janvier 2020). À la date).
Les dernières fonctionnalités ne sont pas disponibles dans la v2.2, ce qui est un peu gênant, vous pouvez donc utiliser la dernière version d'Ansible (dernière v2.9 au moment de la rédaction) en installant (pip install) dans un environnement virtuel de Python. (La version de Python3 pour Raspberry Pi3 / Ubuntu est 3.5)
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
VERSION_CODENAME=stretch
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$ python3 --version
Python 3.5.3
L'installation dans l'environnement virtuel Python est la suivante.
$ python3 -m venv ansible
$ source ansible/bin/activate
$ pip install -U pip
$ pip install ansible
Le * ansible * après python3 -m venv
et le * ansible * spécifié dans la commande source
sont les mêmes, et vous pouvez décider vous-même.
Le ʻansiblespécifié dans
pip install` est le paquet à installer, alors exécutez-le tel quel sans le changer.
Si vous utilisez bash, il est pratique de définir les paramètres suivants dans ~ / .bashrc
.
bash:~/.bashrc Ou ~/.bash_aliases Tel
alias ansibleenv='type deactivate > /dev/null 2>&1 && deactivate; cd ~/work/Ansible.d/; source ~/work/Python.d/envs/ansible/bin/activate'
Dans la partie de type disable> / dev / null 2> & 1 && deactivate
, s'il a été activé dans un autre environnement, désactivez-le.
Accédez à votre répertoire de travail avec cd ~ / work / Ansible.d
.
L'environnement d'ansible est activé par source ~ / work / Python.d / envs / ansible / bin / activate
.
Une fois défini, vous pouvez l'appeler avec ʻansibleenv`.
Sur Raspberry Pi, même si ansible lui-même est exécuté avec succès, l'erreur suivante peut se produire.
:
PLAY RECAP *************************************************************************************************************
172.17.0.2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Exception ignored in: <function WeakValueDictionary.__init__.<locals>.remove at 0x75c7fdf8>
Traceback (most recent call last):
File "/usr/lib/python3.5/weakref.py", line 117, in remove
TypeError: 'NoneType' object is not callable
Exception ignored in: <function WeakValueDictionary.__init__.<locals>.remove at 0x75c7fdf8>
Traceback (most recent call last):
File "/usr/lib/python3.5/weakref.py", line 117, in remove
TypeError: 'NoneType' object is not callable
:
:
Exception ignored in: <function WeakValueDictionary.__init__.<locals>.remove at 0x75c7fdf8>
Traceback (most recent call last):
File "/usr/lib/python3.5/weakref.py", line 117, in remove
TypeError: 'NoneType' object is not callable
Il s'agit d'une erreur causée par la variable non définie de
/ usr / lib / python3.5 / lowref.py``` (type "None").
La solution sous-jacente doit être considérée par l'appelant, mais peut être provisoirement évitée en appliquant le correctif suivant: (Bien que ce soit assez rugueux)
diff:weakref.py.patch
*** weakref.py.bak 2018-09-28 02:25:39.000000000 +0900
--- weakref.py 2020-01-03 18:44:49.190027705 +0900
***************
*** 114,120 ****
else:
# Atomic removal is necessary since this function
# can be called asynchronously by the GC
! _remove_dead_weakref(d, wr.key)
self._remove = remove
# A list of keys to be removed
self._pending_removals = []
--- 114,121 ----
else:
# Atomic removal is necessary since this function
# can be called asynchronously by the GC
! if type(_remove_dead_weakref) is not type(None) and type(d) is not type(None) and type(wr) is not type(None):
! _remove_dead_weakref(d, wr.key)
self._remove = remove
# A list of keys to be removed
self._pending_removals = []
Patcher:
$ sudo patch -c -b /usr/lib/python3.5/weakref.py weakref.py.patch
-c
est une option de correction de type de contexte et -b
est une option de création de sauvegarde.