Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
gfaivre committed Jan 17, 2024
1 parent 4a3f80f commit d423d87
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ En terme de structure vous rencontrerez énormément de façons de faire, celles
Bref tout est imaginable à ce niveau.
En ce qui nous concerne nous interviendrons sur un parc plutôt modeste puisque pour nos travaux nous utiliserons au maximum 4 machines.

Nous allons donc commencer par créer un répertoire qui leur sera dédié appelé `inventories` nous déplacerons ensuite le fichier `hosts.yml` que nous avions créé [précédemment](http://localhost:8000/blog/cours/ansible/ansible-premiers-pas#communication-ansible-serveurs-distants).
Nous allons donc commencer par créer un répertoire qui leur sera dédié appelé `inventories` nous déplacerons ensuite le fichier `hosts.yml` que nous avions créé [précédemment](/blog/cours/ansible/ansible-premiers-pas#communication-ansible-serveurs-distants).

**Vous devriez donc disposer d'une arborence similaire à la suivante:**

Expand Down
173 changes: 147 additions & 26 deletions content/blog/cours/ansible/ansible-les-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,17 @@ all:
## Introduction
Nous avons vu précemment comment débuter avec Ansible avec les notions fondamentales d'inventaire et de playbooks. Dans l'idée d'apporter un peu plus d'outils à cet ensemble Ansible est également capable de gérer et interpréter des variables qui peuvent venir de différentes sources.
La gestion des variables d'Ansible étant relativement souple cela ouvre la porte à beaucoup de façons de les définir et surtout la possibilité de le faire à partir de nombreuses sources !
Pour commencer attaquons nous aux variables qu'Ansible lui même manipule pour son propre fonctionnement.
Nous avons vu précemment comment débuter avec Ansible avec les notions fondamentales d'inventaire et de playbooks. Dans l'idée d'apporter un peu plus de matière à cet ensemble nous allons à présent aborder la notion de variables.
## Les variables
Ansible introduit énormément de souplesse en terme « d'endroit » ou peuvent être déclarées des variables ce qui laisse énormémement de liberté sur la façon dont on souhaite organiser notre projet mais qui a pour contrepartie de demander énormément de rigueur afin de respecter les standards établis pour le projet, sous peine que cela devienne très rapidement un vrai foutoir.
Ansible introduit énormément de **souplesse** en terme « d'endroits » peuvent être déclarées des variables ce qui laisse **énormémement de liberté** sur la façon dont on peut organiser un projet. En contrepartie cela requiert de la **rigueur** afin de respecter les standards établis pour un projet donné, sous peine que cela devienne très rapidement un vrai foutoir.
### Les variables d'hôte
Pour commencer nous aborderons le principe des variables d'hôtes qui en toute logique, permettent de définir des variables au niveau d'une machine bien précise. Vous verrez avec le temps que sur des infrastructures d'exploitation conséquentes ces variables sont souvent peu utilisées car il est rare de n'avoir qu'une seule machine derrière un service.
Commençons par créer un nouveau répertoire `host_vars` à la racine de notre répertoire de travail qui contiendra des fichiers reprenant les nom d'hôtes définis dans notre inventaire, nous commencerons par les membres du groupe `webservers` et crérons donc 2 fichiers `vm-web-prod-01.yml` et `vm-web-staging-01.yml`.
Commençons par créer un nouveau répertoire `host_vars` à la racine de notre répertoire de travail qui contiendra des fichiers **reprenant les nom d'hôtes définis dans notre inventaire**, nous débuterons par les membres du groupe `webservers` et créerons donc 2 fichiers `vm-web-prod-01.yml` et `vm-web-staging-01.yml`.

Chaque fichier contiendra pour l'instant une définition de variable selon l'exemple suivant:

Expand All @@ -91,45 +88,45 @@ et
```yaml
hostname: db-staging-01
```
Il est possible de faire afficher à Ansible les différentes variables définies `ansible-inventory --graph -i inventories --vars` qui devrait vous renvoyer pour l'instant:
Il est possible de faire afficher à Ansible les différentes variables définies via `ansible-inventory --graph -i inventories --vars` qui devrait vous renvoyer pour l'instant:

```yaml
@all:
|--@ungrouped:
|--@webservers:
| |--vm-web-prod-01
| | |--{ansible_host = 162.19.93.111}
| | |--{ansible_host = XXX.XXX.XXX.XXX}
| | |--{ansible_user = debian}
| | |--{hostname = web-production-01}
| |--vm-web-staging-01
| | |--{ansible_host = 162.19.93.190}
| | |--{ansible_host = XXX.XXX.XXX.XXX}
| | |--{ansible_user = debian}
| | |--{hostname = web-staging-01}
|--@dbservers:
| |--vm-db-prod-01
| | |--{ansible_host = 162.19.92.208}
| | |--{ansible_host = XXX.XXX.XXX.XXX}
| | |--{ansible_user = debian}
| | |--{hostname = db-prod-01}
| |--vm-db-staging-01
| | |--{ansible_host = 162.19.92.175}
| | |--{ansible_host = XXX.XXX.XXX.XXX}
| | |--{ansible_user = debian}
| | |--{hostname = db-staging-01}
|--@staging:
| |--vm-web-staging-01
| | |--{ansible_host = 162.19.93.190}
| | |--{ansible_host = XXX.XXX.XXX.XXX0}
| | |--{ansible_user = debian}
| | |--{hostname = web-staging-01}
| |--vm-db-staging-01
| | |--{ansible_host = 162.19.92.175}
| | |--{ansible_host = XXX.XXX.XXX.XXX}
| | |--{ansible_user = debian}
| | |--{hostname = db-staging-01}
|--@production:
| |--vm-web-prod-01
| | |--{ansible_host = 162.19.93.111}
| | |--{ansible_host = XXX.XXX.XXX.XXX}
| | |--{ansible_user = debian}
| | |--{hostname = web-production-01}
| |--vm-db-prod-01
| | |--{ansible_host = 162.19.92.208}
| | |--{ansible_host = XXX.XXX.XXX.XXX}
| | |--{ansible_user = debian}
| | |--{hostname = db-prod-01}
```
Expand All @@ -138,8 +135,8 @@ Où l'on peut constater la présence de nos variables au niveau de chacun des h

### Les variables de groupe

Passons à présent aux variables de groupes, vous l'aurez compris celles-ci s'appliqueront à un groupe de machine tel que nous l'aurons défini dans notre inventaire.
Leur fonctionnement repose sur le même principe que les variables d'hôtes, nous crérons donc cette fois un répertoire appelé `group_vars` contenant un fichier pour chacun des groupes que nous aurons défini.
Passons à présent aux variables de groupes, vous l'aurez compris celles-ci s'appliqueront à un groupe de machine **tel que nous l'aurons défini dans notre inventaire**.
Leur fonctionnement repose sur le même principe que les variables d'hôtes, nous créerons donc cette fois un répertoire appelé `group_vars` contenant un fichier pour chacun des groupes que nous aurons défini.

Nous allons donc créer les fichiers `production.yml` et `staging.yml` contenant respectivement pour l'instant:

Expand All @@ -151,12 +148,12 @@ et
stage: staging
```

En rejouant la commande ansible précédente vous pourrez constater qu'une nouvelle variables `stage` apparait bien comme définie lors de l'affichage de votre inventaire.
En rejouant la commande ansible précédente vous pourrez constater qu'une nouvelle variable `stage` apparait bien comme définie lors de l'affichage de votre inventaire.

!!! info "L'héritage des variables"
Il est bien évidemment possible d'appliquer une définition de variable aux groupes parent comme aux groupes enfant, dans ce cas on prendra bien soin de faire attention à l'héritage des variables !
Il est bien évidemment possible d'appliquer une définition de variable aux groupes parents comme aux groupes enfants, dans ce cas on prendra bien soin de faire attention à l'héritage des variables !

On oubliera pas au passage que même s'il n'apparait pas de manière explicite dans notre inventaire, le groupe `all` est systématiquement définit par Ansible comme « super parent » et qu'il est donc de manière possible de déclarer des variables pour ce groupe en créant un fichier `all.yml` dans `group_vars` contenant par exemple:
On oubliera pas au passage que même s'il n'apparait pas de manière explicite dans notre inventaire, le groupe `all` est systématiquement défini par Ansible comme « super parent » et qu'il est donc bien évidemment possible de déclarer des variables pour ce groupe en créant un fichier `all.yml` dans `group_vars` contenant par exemple:

```yaml
workshop: ansible
Expand All @@ -166,7 +163,7 @@ workshop: ansible

Il est possible (je vous l'ai dit Ansible est très souple) de définir des variables directement dans votre fichier d'inventaire, on l'a déjà plus ou moins vu d'ailleurs avec la définition de clés spécifiques à Ansible comme `ansible_host` ou `ansible_user` au niveau d'un hôte, l'ajout de variable sur un hôte fonctionne donc de la même façon en ajoutant des clés à la suite.

Au niveau d'un groupe il faudra passer par la clé `vars` on pourrait imaginer par exemple indiquer un serveur de temps bien précis pour une zone géographique avec quelque chose comme:
Au niveau d'un groupe, il faudra passer par la clé `vars`. Par exemple on pourrait imaginer par exemple indiquer un serveur de temps bien précis pour une zone géographique avec quelque chose comme:

```yaml
france:
Expand All @@ -179,7 +176,7 @@ france:

### Comment les variables sont elles fusionnées ?

Ansible fusionne les variables pour les appliquer de manière spécifique à chacun de nos hôte, cela signifie que sortie de notre définition d'inventaire et de correspondance hôte/groupe la notion de groupe ne perdure pas, en effet Ansible va écraser les variables préalablement définies en suivant cet ordre (de poids le plus faible au plus important):
Ansible fusionne les variables pour les appliquer de manière spécifique à chacun de nos hôtes, cela signifie que sortie de notre définition d'inventaire et de correspondance hôte/groupe la notion de groupe ne perdure pas, en effet Ansible va écraser les variables préalablement définies en suivant cet ordre (de poids le plus faible au plus important):

- groupe `all` (n'oubliez pas c'est le parent « racine »)
- groupe parent
Expand All @@ -190,7 +187,7 @@ Pour résumer de la variable la moins précise (en terme de périmètre de défi

**Quelques points d'attention toutefois:**

Pour les groupes de même niveau hiérarchique les variables du dernier groupe considéré écraseront les autres, sauf si une pondération est appliqué au niveau du groupe en utilisant la variable `ansible_group_priority` comme suit:
Pour les groupes de même niveau hiérarchique les variables du dernier groupe considéré écraseront les autres, sauf si une pondération est appliquée au niveau du groupe en utilisant la variable `ansible_group_priority` comme suit:

```yaml
france:
Expand Down Expand Up @@ -232,7 +229,7 @@ On peut donc modifier nos fichiers d'hôte de la manière suivante pour exploite
hostname: "web-{{ stage }}-01"
```

Et allons modifier notre playbook (`example.yml`) pour utiliser ces variables de la manière suivante:
Et allons modifier notre playbook (`webservers.yml`) pour utiliser ces variables de la manière suivante:

```yaml
---
Expand Down Expand Up @@ -271,16 +268,140 @@ Et allons modifier notre playbook (`example.yml`) pour utiliser ces variables de

## Les templates

Sujet étroitement lié à l'utilisation des variables, les templates au sens d'Ansible sont des fichiers un peu particulier dont le contenu peut-être défini dynamiquement (par opposition notamment à l'utilisation de fichiers de configuration « statiques ») comme nous avons pu le voir dans la partie [playbook](http://localhost:8000/blog/cours/ansible/ansible-les-playbooks#les-handlers).
Sujet étroitement lié à l'utilisation des variables, les templates au sens d'Ansible sont des fichiers un peu particulier dont le contenu peut-être défini dynamiquement (par opposition notamment à l'utilisation de fichiers de configuration « statiques ») comme nous avons pu le voir dans la partie [playbook](/blog/cours/ansible/ansible-les-playbooks#les-handlers).

Il faut également savoir qu'Ansible s'appuie sur le moteur de template [Jinja2](https://jinja.palletsprojects.com/en/3.1.x/) issu du monde Python qui pourrait être comparé à Twif pour PHP, Pebble pour Java, Liquid pour RoR ou encore DotLiquid pour .Net.
Il faut également savoir qu'Ansible s'appuie sur le moteur de template [Jinja2](https://jinja.palletsprojects.com/en/3.1.x/) issu du monde Python qui pourrait être comparé à Twig pour PHP, Pebble pour Java, Liquid pour RoR ou encore DotLiquid pour .Net.

Nous l'avons vu les variables peuvent être définies à divers endroits et peuvent ensuite être accessibles avec les doubles parenthèses `{{ ... }}`.

Imaginons que nous souhaitions personnaliser nos [motd](https://fr.wikipedia.org/wiki/Message_of_the_Day) par exemple en fonction de l'environnement que nous allons accéder.

### Définir et utiliser un nouveau template

Ansible prévoit par défaut l'utilisation d'un répertoire `templates` pour cette mission, que nous devrons donc créé (toujours à la racine de notre répertoire de travail).
Afin de stocker 2 fichiers nous crérons un répertoire dédié à motd qui contiendra donc `production.j2` et `staging.j2`

Pour ces deux nouveaux fichiers nous ajouterons les contenus suivants:

Pour la **production**:

```shell
#!/bin/sh
MOTD=$(cat <<'EOF'
 ____
 _.' : `._
 .-.'`. ; .'`.-.
 __ / : ___\ ; /___ ; \ __
 ,'_ ""--.:__;".-.";: :".-.":__;.--"" _`,
 :' `.t""--.. '<@,`;_ ',@>` ..--""j.' `;
 `:-.._J '-.-'L__ `-- ' L_..-;'
 "-.__ ; .-" "-. : __.-"
 L ' /.------.\ ' J
 "-. "--" .-"
 __.l"-:_JL_;-";.__
 .-j/'.; ;"""" / .'\"-.
 .' /:`. "-.: :.-" .'; `.
 .-" / ; "-. "-..-" .-" : "-.
 .+"-. : :  "-.__.-" ;-._ \
 ; \ `.; ; : : "+. ;
 : ; ; ; : ; : \:
 : `."-; ; ; : ; ,/;
 ; -: ; : ; : .-"' :
 :\ \ : ; : \.-" :
 ;`. \ ; : ;.'_..-- / ;
 : "-. "-: ; :/." .' :
 \ .-`.\ /t-"" ":-+. :
 `. .-" `l __/ /`. : ; ; \ ;
 \ .-" .-"-.-" .' .'j \ / ;/
 \ / .-" /. .'.' ;_:' ;
 :-""-.`./-.' / `.___.'
 \ `t ._ /
 "-.t-._:'

{{ motd.message | center(42) }}

EOF
)
```

Pour la **staging**:

```shell
#!/bin/sh
{% set message = motd.message -%}

MOTD=$(cat <<'EOF'
-{% for i in range(message | length) %}-{% endfor %}-
< {{ message }} >
-{% for i in range(message | length) %}-{% endfor %}-
\ ^__^
\ (oo)\_______
(__)\ )\/\\
||----w |
|| ||
EOF
)

printf "${MOTD}\n\n\n"
```

Vous devriez à ce stade disposer d'une arborescence ressemblant à ça:

```
|-- example.yml
|-- files
| `-- nginx
| `-- status.conf
|-- group_vars
| |-- all.yml
| |-- production.yml
| `-- staging.yml
|-- host_vars
| |-- vm-db-prod-01.yml
| |-- vm-db-staging-01.yml
| |-- vm-web-prod-01.yml
| `-- vm-web-staging-01.yml
|-- inventories
| `-- hosts.yml
`-- templates
`-- motd
|-- production.j2
`-- staging.j2
```

Après avoir ajouté le contenu de chacun de ces motd nous allons exploiter ces 2 templates en modifiant notre playbook de la façon suivante:

```yaml
# MOTD
- name: MOTD > Installing template
ansible.builtin.template:
src: "motd/{{stage}}.j2"
dest: "/etc/update-motd.d/10-welcome"
owner: root
group: root
mode: "0755"
```
Vous l'aurez sans doute compris, nous allons déployer un motd différent en fonction de notre environnement, l'idée étant d'afficher de manière flagrante à la connexion si nous arrivons sur un environnement de production ou de staging.
### Variabiliser ses fichiers de configuration
Avec cette première approche vous avez sans doute vu les possibilités qui s'offrent à nous, nous avons vu pour l'instant la possibilité de déposer des fichiers de manière « statique » à savoir sans données spécifiques à un hôte et un groupe.
C'est justement ce qu'apporte les templates nous allons pouvoir définir des variables dont la valeur dépendra de l'environnement d'exécution ou de la finalité de nos serveurs.
Introduisions avec cette idée un service PHP-FPM qui nous permettra de faire tourner des applicatifs basés sur PHP.
Toujours dans notre playbooks `webservers` ajoutons une section pour PHP:

```yaml
# PHP
- name: Install PHP-FPM service
ansible.builtin.apt:
name: php-fpm
state: present
```



Expand Down

0 comments on commit d423d87

Please sign in to comment.