|
|
|
|
<!-- .slide: data-state="nologo-slide" style="text-align: center" -->
|
|
|
|
|
![Logo Ansible](images/logo-ansible.svg)
|
|
|
|
|
# Structures de contrôle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## _Facts_
|
|
|
|
|
|
|
|
|
|
* Variables délivrées par le système distant :
|
|
|
|
|
|
|
|
|
|
- Adresses IP
|
|
|
|
|
|
|
|
|
|
- Système d'exploitation
|
|
|
|
|
|
|
|
|
|
- ...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Facts - module setup
|
|
|
|
|
|
|
|
|
|
* Liste des informations disponibles : module _setup_
|
|
|
|
|
|
|
|
|
|
<!-- .slide: data-state="medium-code" -->
|
|
|
|
|
```none
|
|
|
|
|
$ ansible my-host -i ./hosts -m setup
|
|
|
|
|
my-host | SUCCESS => {
|
|
|
|
|
"ansible_facts": {
|
|
|
|
|
"ansible_all_ipv4_addresses": [
|
|
|
|
|
"10.6.214.74"
|
|
|
|
|
],
|
|
|
|
|
"ansible_all_ipv6_addresses": [
|
|
|
|
|
"fe80::250:56ff:fe9d:1aaa"
|
|
|
|
|
],
|
|
|
|
|
"ansible_architecture": "x86_64",
|
|
|
|
|
...
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Facts pour la gestion multi-os
|
|
|
|
|
|
|
|
|
|
* `ansible_pkg_mgr` : Le gestionnaire de paquets
|
|
|
|
|
|
|
|
|
|
* `ansible_os_family` : La famille d'OS
|
|
|
|
|
|
|
|
|
|
* `ansible_distribution` : Information détaillées sur la distribution
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Gestionnaire de paquets
|
|
|
|
|
<!-- .slide: data-state="medium-code" -->
|
|
|
|
|
|
|
|
|
|
```none
|
|
|
|
|
$ ansible my-host -i ./hosts -m setup | grep ansible_pkg_mgr
|
|
|
|
|
"ansible_pkg_mgr": "yum",
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Famille d'OS
|
|
|
|
|
<!-- .slide: data-state="medium-code" -->
|
|
|
|
|
|
|
|
|
|
```none
|
|
|
|
|
$ ansible my-host -i ./hosts -m setup | grep ansible_family
|
|
|
|
|
"ansible_os_family": "RedHat",
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Distribution
|
|
|
|
|
<!-- .slide: data-state="medium-code" -->
|
|
|
|
|
|
|
|
|
|
```none
|
|
|
|
|
$ ansible my-host -i ./hosts -m setup | grep ansible_distribution
|
|
|
|
|
"ansible_distribution": "CentOS",
|
|
|
|
|
"ansible_distribution_file_parsed": true,
|
|
|
|
|
"ansible_distribution_file_path": "/etc/redhat-release",
|
|
|
|
|
"ansible_distribution_file_variety": "RedHat",
|
|
|
|
|
"ansible_distribution_major_version": "7",
|
|
|
|
|
"ansible_distribution_release": "Core",
|
|
|
|
|
"ansible_distribution_version": "7.5.1804",
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Exemple d'aiguillage multi-OS
|
|
|
|
|
|
|
|
|
|
<!-- .slide: data-state="small-code" -->
|
|
|
|
|
Arborescence du rôle
|
|
|
|
|
```none
|
|
|
|
|
my-role
|
|
|
|
|
├── README.md
|
|
|
|
|
├── tasks
|
|
|
|
|
│ ├── CentOS.yaml -> RedHat.yaml
|
|
|
|
|
│ ├── Debian.yaml
|
|
|
|
|
│ ├── main.yaml
|
|
|
|
|
│ ├── RedHat.yaml
|
|
|
|
|
│ └── Ubuntu.yaml -> Debian.yaml
|
|
|
|
|
└── vars
|
|
|
|
|
├── CentOS-6.yaml
|
|
|
|
|
├── CentOS-7.yaml
|
|
|
|
|
├── Debian-8.yaml
|
|
|
|
|
├── Debian-9.yaml
|
|
|
|
|
├── RedHat-6.yaml
|
|
|
|
|
├── RedHat-7.yaml
|
|
|
|
|
└── Ubuntu-16.yaml
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- .slide: data-state="medium-code" -->
|
|
|
|
|
`my-role/tasks/main.yaml`
|
|
|
|
|
```yaml
|
|
|
|
|
- name: Add the OS specific variables
|
|
|
|
|
include_vars: '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yaml'
|
|
|
|
|
|
|
|
|
|
- include_tasks: '{{ansible_distribution}}.yaml'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Utilisation des _conditionals_
|
|
|
|
|
|
|
|
|
|
* Action déclenchée de manière conditionnelle
|
|
|
|
|
(en fonction du résultat d’une variable).
|
|
|
|
|
|
|
|
|
|
* Utilisation de _when_.
|
|
|
|
|
|
|
|
|
|
<small>https://docs.ansible.com/ansible/playbooks_conditionals.html</small>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Exemple
|
|
|
|
|
<!-- .slide: data-state="small-code" -->
|
|
|
|
|
```yaml
|
|
|
|
|
- hosts: web
|
|
|
|
|
tasks:
|
|
|
|
|
- name: Install Apache for CentOS system
|
|
|
|
|
yum:
|
|
|
|
|
name: httpd
|
|
|
|
|
state: present
|
|
|
|
|
update_cache: yes
|
|
|
|
|
when:
|
|
|
|
|
- ansible_os_family == "RedHat" # sera joué sur RedHat et Centos
|
|
|
|
|
- name: Install Apache for Ubuntu system
|
|
|
|
|
apt:
|
|
|
|
|
name: apache2
|
|
|
|
|
state: present
|
|
|
|
|
update_cache: yes
|
|
|
|
|
when:
|
|
|
|
|
- ansible_os_family == "Debian" # sera joué sur Debian et Ubuntu
|
|
|
|
|
```
|
|
|
|
|
Chaque tâche cible une famille
|
|
|
|
|
de système d'exploitation précise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- .slide: data-state="small-code" -->
|
|
|
|
|
```none
|
|
|
|
|
$ ansible-playbook playbook.yaml -i ./hosts
|
|
|
|
|
|
|
|
|
|
PLAY [web] *******************************************************************
|
|
|
|
|
|
|
|
|
|
TASK [setup] *****************************************************************
|
|
|
|
|
ok: [centos-vm]
|
|
|
|
|
ok: [ubuntu-vm]
|
|
|
|
|
|
|
|
|
|
TASK [Install Apache for CentOS system] **************************************
|
|
|
|
|
ok: [centos-vm]
|
|
|
|
|
skipping: [ubuntu-vm]
|
|
|
|
|
|
|
|
|
|
TASK [Install Apache for Ubuntu system] **************************************
|
|
|
|
|
skipping: [centos-vm]
|
|
|
|
|
ok: [ubuntu-vm]
|
|
|
|
|
|
|
|
|
|
PLAY RECAP *******************************************************************
|
|
|
|
|
centos-vm : ok=2 changed=0 unreachable=0 failed=0
|
|
|
|
|
ubuntu-vm : ok=2 changed=0 unreachable=0 failed=0
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Les tâches sont exécutées ou non en fonction
|
|
|
|
|
de la famille du système d'exploitation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Utilisation des _loops_
|
|
|
|
|
|
|
|
|
|
* Boucles pour la réalisation d'actions répétitives.
|
|
|
|
|
|
|
|
|
|
* Permet de faire plusieurs actions dans une seule tâche.
|
|
|
|
|
|
|
|
|
|
* Création d'utilisateurs, installation de paquets, ...
|
|
|
|
|
|
|
|
|
|
* Utilisation de ~~with-x~~ _loop_
|
|
|
|
|
|
|
|
|
|
<small>https://docs.ansible.com/ansible/playbooks_loops.html</small>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### with-x
|
|
|
|
|
<!-- .slide: data-state="small-table" -->
|
|
|
|
|
Paramètre | Type | Example d'utilisation
|
|
|
|
|
- | - | -
|
|
|
|
|
`with_items` | Array | To create a group of users, directories, or to install a list of packages
|
|
|
|
|
`with_nested` | Nested loops | To create a list of MySQL users and grant them access to a group of databases
|
|
|
|
|
`with_dict` | Hashes | To parse a dictionary of key-value pairs and create virtual hosts
|
|
|
|
|
`with_fileglobs` |Files with pattern match | To parse a path and copy only those files that match a certain pattern
|
|
|
|
|
`with_together` | S ets | To join two arrays as a set and to loop over it
|
|
|
|
|
`with_subelements` | Hash sub element | To walk over the list of SSH keys and distribute them to a user
|
|
|
|
|
`with_sequence` | Integer sequence | To loop a sequence of numbers
|
|
|
|
|
`with_random_choice` | Random choice | To pick up items from the array in a random order
|
|
|
|
|
`with_indexed_items` | Array with index | Array with an index and is useful when an index for items is required
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Exemple avec with_items
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
- hosts: my-host
|
|
|
|
|
tasks:
|
|
|
|
|
- name: Add some users
|
|
|
|
|
user:
|
|
|
|
|
name: "{{ item }}"
|
|
|
|
|
state: present
|
|
|
|
|
with_items:
|
|
|
|
|
- bob
|
|
|
|
|
- alice
|
|
|
|
|
- joe
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Attention ! à partir d'Ansible 2.5 _with-x_ n'est plus la méthode recommandé pour effectué des boucles.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- .slide: data-state="small-code" -->
|
|
|
|
|
```none
|
|
|
|
|
$ ansible-playbook playbook.yaml -i ./hosts
|
|
|
|
|
|
|
|
|
|
PLAY [my-host] ***************************************************************
|
|
|
|
|
|
|
|
|
|
TASK [setup] *****************************************************************
|
|
|
|
|
ok: [my-host]
|
|
|
|
|
|
|
|
|
|
TASK [Add some users] ********************************************************
|
|
|
|
|
changed: [my-host] => (item=bob)
|
|
|
|
|
changed: [my-host] => (item=alice)
|
|
|
|
|
changed: [my-host] => (item=joe)
|
|
|
|
|
|
|
|
|
|
PLAY RECAP *******************************************************************
|
|
|
|
|
my-host : ok=2 changed=1 unreachable=0 failed=0
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
La boucle a bien itéré sur les 3 utilisateurs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Migration vers loop
|
|
|
|
|
|
|
|
|
|
* A partir d'Ansible 2.5 _with-x_ n'est plus la méthode recommandée pour effectuer des boucles.
|
|
|
|
|
|
|
|
|
|
* La documentation sur les boucles propose une section pour aider à la migration de _with-x_ vers _loop_.
|
|
|
|
|
|
|
|
|
|
<small>https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html</small>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Exemple avec loop
|
|
|
|
|
```yaml
|
|
|
|
|
- hosts: my-host
|
|
|
|
|
tasks:
|
|
|
|
|
- name: Add some users
|
|
|
|
|
user:
|
|
|
|
|
name: "{{ item }}"
|
|
|
|
|
state: present
|
|
|
|
|
loop:
|
|
|
|
|
- bob
|
|
|
|
|
- alice
|
|
|
|
|
- joe
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
On remplace simplement `with_items` par `loop`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- .slide: data-state="small-code" -->
|
|
|
|
|
```none
|
|
|
|
|
$ ansible-playbook -i inventories/formation/hosts playbook.yaml
|
|
|
|
|
|
|
|
|
|
PLAY [my-host] ***************************************************************
|
|
|
|
|
|
|
|
|
|
TASK [Gathering Facts] *******************************************************
|
|
|
|
|
ok: [my-host]
|
|
|
|
|
|
|
|
|
|
TASK [Add some users] ********************************************************
|
|
|
|
|
changed: [my-host] => (item=bob)
|
|
|
|
|
changed: [my-host] => (item=alice)
|
|
|
|
|
changed: [my-host] => (item=joe)
|
|
|
|
|
|
|
|
|
|
PLAY RECAP *******************************************************************
|
|
|
|
|
my-host : ok=2 changed=1 unreachable=0 failed=0
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Le résultat final est strictement identique.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
- hosts: my-host
|
|
|
|
|
tasks:
|
|
|
|
|
- name: Add some users
|
|
|
|
|
user:
|
|
|
|
|
name: "{{ item.name }}"
|
|
|
|
|
state: present
|
|
|
|
|
groups: "{{ item.groups }}"
|
|
|
|
|
loop:
|
|
|
|
|
- { name: 'bob', groups: 'wheel' }
|
|
|
|
|
- { name: 'alice', groups: 'root' }
|
|
|
|
|
- { name: 'joe', groups: 'root' }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
En plus des _strings_ , il est possible d'utiliser des _hashes_.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Itérer sur l'inventaire
|
|
|
|
|
<!-- .slide: data-state="small-code" -->
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
- hosts: centos7
|
|
|
|
|
tasks:
|
|
|
|
|
- name: Iterate on hosts in the group all in the inventory
|
|
|
|
|
debug:
|
|
|
|
|
msg: "{{ item }}"
|
|
|
|
|
loop: "{{ groups['all'] }}" # on itère sur les machines du groupe all
|
|
|
|
|
```
|
|
|
|
|
```none
|
|
|
|
|
$ ansible-playbook -i ./hosts playbook.yaml
|
|
|
|
|
|
|
|
|
|
PLAY [centos7] *****************************************************************
|
|
|
|
|
|
|
|
|
|
TASK [Iterate on hosts in the group all in the inventory] **********************
|
|
|
|
|
ok: [ansible-1] => (item=ansible-3) => {
|
|
|
|
|
"msg": "ansible-3"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-1] => (item=ansible-1) => {
|
|
|
|
|
"msg": "ansible-1"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-1] => (item=ansible-2) => {
|
|
|
|
|
"msg": "ansible-2"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-2] => (item=ansible-3) => {
|
|
|
|
|
"msg": "ansible-3"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-2] => (item=ansible-1) => {
|
|
|
|
|
"msg": "ansible-1"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-2] => (item=ansible-2) => {
|
|
|
|
|
"msg": "ansible-2"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Chaque machine du Play (_centos7_) itère sur le groupe _all_.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Itérer sur le Play
|
|
|
|
|
<!-- .slide: data-state="small-code" -->
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
- hosts: centos7
|
|
|
|
|
tasks:
|
|
|
|
|
- name: Iterate on all the hosts in the current play
|
|
|
|
|
debug:
|
|
|
|
|
msg: "{{ item }}"
|
|
|
|
|
loop: "{{ ansible_play_batch }}" # variable qui contient les machines du Play
|
|
|
|
|
```
|
|
|
|
|
```none
|
|
|
|
|
$ ansible-playbook -i inventories/formation/hosts playbook.yaml
|
|
|
|
|
|
|
|
|
|
PLAY [centos7] *****************************************************************
|
|
|
|
|
|
|
|
|
|
TASK [Iterate on all the hosts in the current play] ****************************
|
|
|
|
|
ok: [ansible-1] => (item=ansible-1) => {
|
|
|
|
|
"msg": "ansible-1"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-1] => (item=ansible-2) => {
|
|
|
|
|
"msg": "ansible-2"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-2] => (item=ansible-1) => {
|
|
|
|
|
"msg": "ansible-1"
|
|
|
|
|
}
|
|
|
|
|
ok: [ansible-2] => (item=ansible-2) => {
|
|
|
|
|
"msg": "ansible-2"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Chaque machine du Play (_centos7_) itère
|
|
|
|
|
sur les machines du Play (_centos7_).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Travaux pratiques
|
|
|
|
|
<!-- .slide: data-state="nologo-slide" style="text-align: center" -->
|
|
|
|
|
|
|
|
|
|
![Travaux pratiques](images/tp.gif)
|
|
|
|
|
|
|
|
|
|
<small>[TP Ansible : structures de contrôle](travaux-pratiques/tp-ansible-structures-de-controle.html)</small>
|