307 lines
8.8 KiB
Markdown
307 lines
8.8 KiB
Markdown
# Recettes Ansible d'Aurore
|
|
|
|
Dépendances requises :
|
|
|
|
* Ansible 2.9 ou plus récent.
|
|
|
|
## Ansible 101
|
|
|
|
Si vous n'avez jamais touché à Ansible avant, voilà une rapide introduction.
|
|
|
|
**Inventory** : c'est le fichier `hosts` d'inventaire.
|
|
Il contient la définition de chaque machine et le regroupement.
|
|
|
|
Quand on regroupe avec un `:children` en réalité on groupe des groupes.
|
|
|
|
Chaque machine est annoncée avec son hostname. Il faut pouvoir SSH sur cette
|
|
machine avec ce hostname, car c'est ce qu'Ansible fera (sauf pour les switchs,
|
|
voir plus bas).
|
|
|
|
**Playbook** : c'est une politique de déploiement.
|
|
Il contient les associations des rôles avec les machines.
|
|
|
|
L'idée au Crans est de regrouper par thème. Exemple, le playbook `monitoring.yml`
|
|
va contenir toutes les définitions machines-rôles qui touchent au monitoring.
|
|
Cela permet de déployer manuellement tout le monitoring sans toucher au reste.
|
|
|
|
**Rôle** : un playbook donne des rôles à des machines. Ces rôles sont tous dans
|
|
le dossier `roles/`. Un rôle installe un service précis sur un serveur.
|
|
|
|
Il est préférable d'être atomique sur les rôles plutôt d'en coder un énorme
|
|
qui sera difficilement maintenable.
|
|
|
|
*Exemples de rôle* : activer les backports pour ma version de Debian, installer NodeJS,
|
|
déployer un serveur prometheus, déployer une node prometheus…
|
|
|
|
**Tâche** : un rôle est composé de tâches. Une tâche effectue une et une seule
|
|
action. Elle est associée à un module Ansible.
|
|
|
|
*Exemples de tâche* : installer un paquet avec le module `apt`, ajouter une
|
|
ligne dans un fichier avec le module `lineinfile`, copier une template avec le
|
|
module `template`…
|
|
|
|
Une tâche peut avoir des paramètres supplémentaires pour la réessayer quand
|
|
elle plante, récupérer son résultat dans une variable, mettre une boucle
|
|
dessus, mettre des conditions…
|
|
|
|
N'oubliez pas d'aller lire l'excellente documentation de RedHat sur tous les modules
|
|
d'Ansible !
|
|
|
|
### Gestion des groupes de machines
|
|
|
|
Pour la liste complète, je vous invite à lire le fichier `hosts`.
|
|
|
|
Exemple :
|
|
|
|
```yaml
|
|
[fleming_vm]
|
|
dhcp-fleming.adm.auro.re
|
|
dns-fleming.adm.auro.re
|
|
prometheus-fleming.adm.auro.re
|
|
routeur-fleming.adm.auro.re
|
|
|
|
[fleming_pve]
|
|
pve1.adm.auro.re
|
|
|
|
[fleming:children]
|
|
fleming_pve
|
|
fleming_vm
|
|
```
|
|
|
|
> NB :
|
|
>
|
|
> L'exemple a été adapté de la configuration d'Aurore pour des raisons
|
|
> pédagogiques.
|
|
|
|
Pour les fonctions (`proxy-server`, `dhcp-dynamique`…) il a été choisi
|
|
de ne pas faire de groupe particulier mais plutôt de sélectionner/enlever
|
|
les machines pertinentes directement dans les playbooks.
|
|
|
|
### Lister tout ce que sait Ansible sur un hôte
|
|
|
|
Lors du lancement d'Ansible, il collecte un ensemble de faits sur les serveurs
|
|
qui peuvent ensuite être utilisés dans des variables.
|
|
Pour lister tous les faits qu'Ansible collecte nativement d'un serveur
|
|
on peut exécuter le module `setup` manuellement.
|
|
|
|
```bash
|
|
ansible proxy.adm.auro.re -m setup --ask-vault-pass
|
|
```
|
|
|
|
Il est notamment possible de :
|
|
|
|
* tester les versions de Debian,
|
|
|
|
```YAML
|
|
ansible_lsb.codename == 'stretch'
|
|
```
|
|
|
|
* tester si c'est un CPU Intel x86_64,
|
|
|
|
```YAML
|
|
ansible_processor[0].find('Intel') != -1
|
|
and ansible_architecture == 'x86_64'
|
|
```
|
|
|
|
## Exécution d'Ansible
|
|
|
|
### Configurer la connexion au vlan adm
|
|
|
|
Envoyer son agent SSH peut être dangereux
|
|
([source](https://heipei.github.io/2015/02/26/SSH-Agent-Forwarding-considered-harmful/)).
|
|
|
|
On va utiliser plutôt `ProxyJump`.
|
|
Dans la configuration SSH :
|
|
|
|
```text
|
|
Host *.adm.auro.re *.pve.auro.re
|
|
# Accept new host keys
|
|
StrictHostKeyChecking accept-new
|
|
|
|
# Use passerelle to connect to administration VLANs
|
|
ProxyJump passerelle.auro.re
|
|
```
|
|
|
|
Il faut sa clé SSH configurée sur le serveur que l'on déploie.
|
|
|
|
```bash
|
|
ssh-copy-id proxy.adm.auro.re
|
|
```
|
|
|
|
### Lancer Ansible
|
|
|
|
Il faut `python3-netaddr` sur sa machine.
|
|
|
|
Pour tester le playbook `base.yml` :
|
|
|
|
```bash
|
|
ansible-playbook --ask-vault-pass base.yml --check
|
|
```
|
|
|
|
Vous pouvez ensuite enlever `--check` si vous voulez appliquer les changements !
|
|
|
|
Si vous avez des soucis de fingerprint ECDSA, vous pouvez ignorer une
|
|
première fois (dangereux !) : `ANSIBLE_HOST_KEY_CHECKING=0 ansible-playbook...`.
|
|
|
|
### Ajouter toutes les empreintes de serveur
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
for ip in `cat hosts|grep .adm.auro.re`; do
|
|
ssh-copy-id -i ~/.ssh/id_rsa.pub $ip
|
|
done
|
|
```
|
|
|
|
> Remarque :
|
|
>
|
|
> L'utilisation d'un certificat permet d'éviter d'avoir à ajouter sa clé ssh
|
|
> sur les serveurs.
|
|
|
|
### Passage à Ansible 2.10 (release: 30 juillet)
|
|
|
|
Installez la version de développement d'ansible pour faire fonctionner les
|
|
playbooks de ce repo, ainsi que les collections suivantes :
|
|
|
|
```bash
|
|
ansible-galaxy collection install community.general
|
|
ansible-galaxy collection install ansible.posix
|
|
```
|
|
|
|
Si vous n'arrivez pas à entrer votre *become password* (bug dans ansible?), un
|
|
workaround est le suivant :
|
|
|
|
`$ export ANSIBLE_BECOME_PASS='<votre mot de passe LDAP>'`
|
|
|
|
Notez l'espace au début pour ne pas log la commande dans votre historique
|
|
shell.
|
|
|
|
## Configuration des switchs depuis Ansible
|
|
|
|
Afin d'acquérir de l'indépendance vis-à-vis de re2o, un module permettant de
|
|
configurer les switchs depuis Ansible a été créé. Il utilise l'api rest des
|
|
switchs afin de récupérer et appliquer la configuration voulue.
|
|
|
|
### Prérequis
|
|
|
|
Pour utiliser le module, il faut d'abord annoncer à Ansible qu'il ne faut pas
|
|
effectuer de connexion ssh et de ne pas récupérer les faits. Cela se fait à
|
|
l'aide des variables `connection: httpapi` et `gather_facts: false` à placer
|
|
dans le playbook (pour une configuration locale) ou dans ansible.cfg (pour une
|
|
configuration globale). Ensuite, l'infrastructure actuelle de Aurore nécessite
|
|
l'utilisation d'un proxy. Pour cela, il suffit d'exécuter la commande :
|
|
|
|
```bash
|
|
ssh -D 3000 switchs-manager.adm.auro.re
|
|
```
|
|
|
|
et d'annoncer l'utilisation du proxy dans la configuration en exportant la
|
|
variable d'environnement `HTTP_PROXY=socks5://localhost:3000` et en
|
|
configurant la variable du module `use_proxy: true`.
|
|
|
|
Exemple :
|
|
|
|
```yaml
|
|
environment:
|
|
HTTP_PROXY: "socks5://localhost:3000"
|
|
tasks:
|
|
- name: vlans
|
|
switch_config:
|
|
username: ****
|
|
password: ****
|
|
port: 80
|
|
host: 192.168.1.42
|
|
use_proxy: true
|
|
config:
|
|
path: vlans/42
|
|
data:
|
|
name: VLAN42
|
|
vlan_id: 42
|
|
status: VS_PORT_BASED
|
|
type: VT_STATIC
|
|
```
|
|
|
|
Le module est alors utilisable, il ne reste plus qu'à le configurer.
|
|
|
|
### Écrire la configuration
|
|
|
|
Le module se veut assez libre. Ainsi, l'ensemble de la requête doit être écrite
|
|
dans les `tasks`. Voici un exemple pour configurer un vlan :
|
|
|
|
```yaml
|
|
tasks:
|
|
- name: vlans
|
|
switch_config:
|
|
username: ****
|
|
password: ****
|
|
port: 80
|
|
host: 192.168.1.42
|
|
config:
|
|
path: vlans/42
|
|
data:
|
|
name: VLAN42
|
|
vlan_id: 42
|
|
status: VS_PORT_BASED
|
|
type: VT_STATIC
|
|
```
|
|
|
|
Le `path` correspond à l'url de l'objet que l'on souhaite éditer et `data`
|
|
correspond aux données qui seront envoyées dans une requête `PUT` (au format
|
|
`json`). Cependant, la configuration d'un vlan peut nécessiter de le créer.
|
|
Pour remédier à ce problème, il est possible d'utiliser la syntaxe suivante :
|
|
|
|
```yaml
|
|
|
|
tasks:
|
|
- name: vlans
|
|
switch_config:
|
|
username: ****
|
|
password: ****
|
|
port: 80
|
|
host: 192.168.1.42
|
|
config:
|
|
path: vlans
|
|
create_method: POST
|
|
subpath:
|
|
- path: 42
|
|
data:
|
|
name: VLAN42
|
|
vlan_id: 42
|
|
status: VS_PORT_BASED
|
|
type: VT_STATIC
|
|
```
|
|
|
|
Le variable `create_method` correspond au type de la requête pour effectuer une
|
|
action de création de l'objet. Il s'agit généralement de `POST`. Dans le cas
|
|
où la variable n'est pas définit, la création sera désactivée et ainsi, si
|
|
l'url indiquée dans les `subpath` n'existe pas, alors la configuration échouera.
|
|
Par conséquent, si le vlan 42 a besoin d'être créé, une requête `POST` sera
|
|
effectué sur l'url `vlans` avec les données dans `data`.
|
|
|
|
Il est également possible d'éxecuter une action de suppression d'un vlan à l'aide
|
|
de la variable `delete` :
|
|
|
|
```yaml
|
|
tasks:
|
|
- name: vlans
|
|
switch_config:
|
|
username: ****
|
|
password: ****
|
|
port: 80
|
|
host: 192.168.1.42
|
|
config:
|
|
path: vlans/42
|
|
delete: true
|
|
```
|
|
|
|
Si la variable `delete` est activée, alors une requête `DELETE` sera envoyée
|
|
sur l'url indiquée. Pour vérifier si la suppression est déjà effective avant
|
|
l'éxecution, le module vérifiera si un `GET` sur l'url retourne une 404.
|
|
|
|
> Remarque :
|
|
>
|
|
> Si les variables `delete` et `data` sont définies (dont `delete` à `true`),
|
|
> alors il en résultera une action de suppression malgré tout.
|
|
|
|
Puisque `subpath` est une liste, il est possible de configurer plusieurs requête
|
|
en même temps. Cela à l'avantage d'effectuer toutes les modifications à la suite
|
|
(sans avoir à se connecter plusieurs sur l'api).
|