HowtoAnsible: conversion aux FQCN

This commit is contained in:
Jérémy Lecour 2023-03-21 08:31:04 +01:00 committed by Jérémy Lecour
parent 37f53f5561
commit 9e4d3089b1

View file

@ -80,15 +80,15 @@ jeudi 26 mai 2016, 23:16:01 (UTC+0200)
Par exemple, pour lister les serveurs qui ont le packet `lxc` installé :
~~~
$ ansible stretch,buster,bullseye -bK --one-line --forks 42 -m command --args 'dpkg -l | grep lxc | grep -q ii' | grep CHANGED
$ ansible stretch,buster,bullseye -bK --one-line --forks 42 -m ansible.builtin.shell --args 'dpkg -l | grep lxc | grep -q ii' | grep CHANGED
~~~
Autres exemples pratiques :
~~~
$ ansible stretch,buster -bK --one-line --forks 42 -m command --args "grep -r SFTPEngine /etc/proftpd"
$ ansible "*" -bK --one-line --forks 42 -m command --args "grep foo /etc/passwd"
$ ansible "*" -bK --one-line --forks 42 -m command --args "lxc-ls" | grep CHANGED
$ ansible stretch,buster -bK --one-line --forks 42 -m ansible.builtin.command --args "grep -r SFTPEngine /etc/proftpd"
$ ansible "*" -bK --one-line --forks 42 -m ansible.builtin.command --args "grep foo /etc/passwd"
$ ansible "*" -bK --one-line --forks 42 -m ansible.builtin.command --args "lxc-ls" | grep CHANGED
~~~
@ -112,34 +112,44 @@ Pour avoir la liste des modules utilisables : `ansible-doc -l`
Voici quelques exemples de modules que nous utilisons :
* Module [command](https://docs.ansible.com/ansible/2.10/modules/command_module.html) :
* Module [ansible.builtin.command](https://docs.ansible.com/ansible/2.10/modules/command_module.html) :
~~~{.yaml}
- command: date
- ansible.builtin.command:
cmd: date
~~~
Ce module ne permet que l'exécution de commandes simple (pas de pipe…) mais en échange il vérifie les commandes et les assainit pour limiter les injections.
* Module [shell](https://docs.ansible.com/ansible/2.10/modules/shell_module.html) :
* Module [ansible.builtin.shell](https://docs.ansible.com/ansible/2.10/modules/shell_module.html) :
~~~{.yaml}
- shell: cat foo.txt | grep bar
- ansible.builtin.shell:
cmd: "cat foo.txt | grep bar"
~~~
Ce module permet en revanche d'exécuter arbitrairement et sans contrôle toute commande, au sein d'un shell lancé pour l'occasion.
* Module [file](https://docs.ansible.com/ansible/2.10/modules/file_module.html) :
Pour forcr un shell en particulier :
~~~{.yaml}
- file:
- ansible.builtin.shell:
cmd: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
executable: /bin/bash
~~~
* Module [ansible.builtin.file](https://docs.ansible.com/ansible/2.10/modules/file_module.html) :
~~~{.yaml}
- ansible.builtin.file:
path: /etc/cron.daily/apticron
state: absent
~~~
* Module [copy](https://docs.ansible.com/ansible/2.10/modules/copy_module.html) :
* Module [ansible.builtin.copy](https://docs.ansible.com/ansible/2.10/modules/copy_module.html) :
~~~{.yaml}
- copy
- ansible.builtin.copy:
src: files/foo
dest: /etc/bar
owner: root
@ -147,19 +157,19 @@ Ce module permet en revanche d'exécuter arbitrairement et sans contrôle toute
mode: "0644"
~~~
* Module [replace](https://docs.ansible.com/ansible/2.10/modules/replace_module.html) :
* Module [ansible.builtin.replace](https://docs.ansible.com/ansible/2.10/modules/replace_module.html) :
~~~{.yaml}
- replace:
- ansible.builtin.replace:
dest: /etc/ssh/sshd_config
regexp: '^(Match User ((?!{{ name }}).)*)$'
replace: '\1,{{ name }}'
~~~
* Module [lineinfile](https://docs.ansible.com/ansible/2.10/modules/lineinfile_module.html) :
* Module [ansible.builtin.lineinfile](https://docs.ansible.com/ansible/2.10/modules/lineinfile_module.html) :
~~~{.yaml}
- lineinfile:
- ansible.builtin.lineinfile:
dest: /etc/evocheck.cf
insertafter: EOF
line: "IS_APTICRON=0"
@ -175,20 +185,20 @@ Ce module permet en revanche d'exécuter arbitrairement et sans contrôle toute
* avec _lineinfile_, si l'on veut utiliser une référence (`\1`) dans _line_, ça donne une erreur, il faut utiliser _replace_
* avec _lineinfile_, l'argument `backrefs: yes` sert à utiliser une référence au sein de l'argument _regexp_ (et non pas au sein de l'argument _line_).
* Module [blockinfile](https://docs.ansible.com/ansible/2.10/modules/blockinfile_module.html) :
* Module [ansible.builtin.blockinfile](https://docs.ansible.com/ansible/2.10/modules/blockinfile_module.html) :
~~~{.yaml}
- blockinfile:
- ansible.builtin.blockinfile:
dest: /etc/apache2/envvars
block: |
## Set umask for writing by Apache user.
## Set rights on files and directories written by Apache
~~~
* Module [ini_file](https://docs.ansible.com/ansible/2.10/modules/ini_file_module.html) :
* Module [community.general.ini_file](https://docs.ansible.com/ansible/2.10/modules/ini_file_module.html) :
~~~{.yaml}
- ini_file:
- community.general.ini_file:
dest: /root/.my.cnf
section: client
option: user
@ -198,10 +208,10 @@ Ce module permet en revanche d'exécuter arbitrairement et sans contrôle toute
Ce module permet de facilement d'ajouter/modifier/supprimer des valeurs dans des fichiers INI, dans la bonne section, sans se soucier de la syntaxe.
* Module [user](https://docs.ansible.com/ansible/2.10/modules/user_module.html) :
* Module [ansible.builtin.user](https://docs.ansible.com/ansible/2.10/modules/user_module.html) :
~~~{.yaml}
- user:
- ansible.builtin.user:
state: present
name: "jdoe"
comment: 'John Doe'
@ -217,43 +227,43 @@ Pour générer le hash du mot de passe à mettre dans la variable `password` :
mkpasswd --method=sha-512
~~~
* Module [group](https://docs.ansible.com/ansible/2.10/modules/group_module.html) :
* Module [ansible.builtin.group](https://docs.ansible.com/ansible/2.10/modules/group_module.html) :
~~~{.yaml}
- group:
- ansible.builtin.group:
state: present
name: "foobarcorp"
gid: "1042"
~~~
* Module [stat](https://docs.ansible.com/ansible/2.10/modules/stat_module.html) :
* Module [ansible.builtin.stat](https://docs.ansible.com/ansible/2.10/modules/stat_module.html) :
~~~{.yaml}
- stat:
- ansible.builtin.stat:
path: /etc/sudoers.d/foo
register: foo_sudoers_file
~~~
* Module [apt](https://docs.ansible.com/ansible/2.10/modules/apt_module.html) :
* Module [ansible.builtin.apt](https://docs.ansible.com/ansible/2.10/modules/apt_module.html) :
~~~{.yaml}
- apt:
- ansible.builtin.apt:
name: '{{ item }}'
state: latest
update_cache: yes
cache_valid_time: 3600
with_items:
- vim
- htop
- vim
- htop
~~~
Ce module fait partie d'une courte liste de modules pour lesquels l'utilisation d'une boucle (avec `with_items` par exemple) ne provoque pas l'exécution séquentielle et répétée du module. Dans l'exemple ci-dessus le module utilisera "apt" intelligemment.
* Module [apt_repository](https://docs.ansible.com/ansible/2.10/modules/apt_repository_module.html) :
* Module [ansible.builtin.apt_repository](https://docs.ansible.com/ansible/2.10/modules/apt_repository_module.html) :
~~~{.yaml}
- name: exemple
apt_repository:
ansible.builtin.apt_repository:
repo: "deb https://artifacts.elastic.co/packages/5.x/apt stable main"
filename: elastic
state: present
@ -261,10 +271,10 @@ Ce module fait partie d'une courte liste de modules pour lesquels l'utilisation
L'indication "filename" permet de référencer le dépôt dans `/etc/apt/sources.list.d/<filename>.list`.
* Module [mysql_user](https://docs.ansible.com/ansible/2.10/modules/mysql_user_module.html) :
* Module [community.mysql.mysql_user](https://docs.ansible.com/ansible/2.10/modules/mysql_user_module.html) :
~~~{.yaml}
- mysql_user:
- community.mysql.mysql_user:
name: mysqladmin
password: my_password
priv: "*.*:ALL,GRANT"
@ -275,20 +285,20 @@ L'indication "filename" permet de référencer le dépôt dans `/etc/apt/sources
Lorsqu'une réplication est en place, on peut choisir de ne pas propager l'action dans les binlogs, avec l'option `sql_log_bin: no`.
* module [mysql_variables](https://docs.ansible.com/ansible/2.10/modules/mysql_variables_module.html)
* module [community.mysql.mysql_variables](https://docs.ansible.com/ansible/2.10/modules/mysql_variables_module.html)
~~~{.yaml}
- mysql_variables:
- community.mysql.mysql_variables:
variable: read_only
value: 1
~~~
Cela permet d'exécuter une commande du type "SET GLOBAL read_only = 1;" de manière idempotente.
* module [htpasswd](https://docs.ansible.com/ansible/2.10/modules/htpasswd_module.html)
* module [community.general.htpasswd](https://docs.ansible.com/ansible/2.10/modules/htpasswd_module.html)
~~~{.yaml}
- htpasswd:
- community.general.htpasswd:
path: /etc/nginx/htpasswd_phpmyadmin
name: jdoe
password: 'PASSWORD'
@ -299,36 +309,36 @@ Cela permet d'exécuter une commande du type "SET GLOBAL read_only = 1;" de mani
Il nécessite la bibliothèque Python "passlib", installable sous Debian grace au paquet "python-passlib" ("python3-passlib" sur les versions récentes).
* Module [sysctl](https://docs.ansible.com/ansible/2.10/modules/sysctl_module.html) :
* Module [ansible.posix.sysctl](https://docs.ansible.com/ansible/2.10/modules/sysctl_module.html) :
~~~{.yaml}
- name: exemple
sysctl:
ansible.posix.sysctl:
name: vm.max_map_count
value: 262144
sysctl_file: /etc/sysctl.d/elasticsearch.conf
~~~
* Module [alternatives](https://docs.ansible.com/ansible/2.10/modules/alternatives_module.html) :
* Module [community.general.alternatives](https://docs.ansible.com/ansible/2.10/modules/alternatives_module.html) :
~~~{.yaml}
- alternatives:
- community.general.alternatives:
name: editor
path: /usr/bin/vim.basic
~~~
* Module [service](https://docs.ansible.com/ansible/2.10/modules/service_module.html) :
* Module [ansible.builtin.service](https://docs.ansible.com/ansible/2.10/modules/service_module.html) :
~~~{.yaml}
- name: exemple pour redémarrer un service (compatible avec sysvinit, systemd…)
service: nginx
ansible.builtin.service: nginx
state: restarted
~~~
* Module [openbsd_pkg](https://docs.ansible.com/ansible/2.10/modules/openbsd_pkg_module.html) :
* Module [community.general.openbsd_pkg](https://docs.ansible.com/ansible/2.10/modules/openbsd_pkg_module.html) :
~~~{.yaml}
- openbsd_pkg:
- community.general.openbsd_pkg:
name: "{{ item }}"
state: present
with_items:
@ -336,10 +346,10 @@ Il nécessite la bibliothèque Python "passlib", installable sous Debian grace a
- vim--no_x11
~~~
* module [timezone](https://docs.ansible.com/ansible/2.10/modules/timezone_module.html) :
* module [community.general.timezone](https://docs.ansible.com/ansible/2.10/modules/timezone_module.html) :
~~~{.yaml}
- timezone:
- community.general.timezone:
name: Europe/Paris
~~~
@ -347,10 +357,10 @@ Si systemd est présent, le module utilise `timedatectl`.
Sinon, sur Debian il utilise "/etc/timezone" et reconfigure le paquet "tzdata".
* module [git](https://docs.ansible.com/ansible/2.10/collections/ansible/builtin/git_module.html) :
* module [ansible.builtin.git](https://docs.ansible.com/ansible/2.10/collections/ansible/builtin/git_module.html) :
~~~{.yaml}
- git:
- ansible.builtin.git:
repo: https://gitea.evolix.org/evolix/evoadmin-web.git
dest: /home/evoadmin/www
version: master
@ -383,7 +393,7 @@ Exemple de playbook simple :
- hosts: all
tasks:
- shell: echo hello World
- ansible.builtin.shell: echo hello World
# vim:ft=ansible:
~~~
@ -405,7 +415,7 @@ Un playbook plus évolué :
pre_tasks:
- name: Minifirewall is stopped (temporary)
service:
ansible.builtin.service:
name: minifirewall
state: stopped
@ -504,12 +514,12 @@ Exemple :
~~~{.yaml}
tasks:
- name: copy Apache configuration
copy: (…)
ansible.builtin.copy: (…)
notify: Restart Apache
handlers:
- name: Restart Apache
service:
ansible.builtin.service:
name: apache2
state: restarted
~~~
@ -517,7 +527,7 @@ handlers:
Dans des rôles longs, nous conseillons de purger les handlers de temps en temps (en fin de groupe d'action). En effet, si un playbook est interrompu les handlers ne sont pas forcément exécutés alors que l'action qui les a déclenchés a bien eu lieu. On insère alors l'action suivante :
~~~{.yaml}
- meta: flush_handlers
- ansible.builtin.meta: flush_handlers
~~~
> *Note* : n'importe quel module peut être utilisé comme handler.
@ -614,7 +624,7 @@ vars:
conf_file: /etc/foo.conf
tasks:
- command: echo {{ ip }} >> {{ conf_file }}
- ansible.builtin.command: echo {{ ip }} >> {{ conf_file }}
~~~
Les variables peuvent être définies à de multiples niveaux, chacun ayant une certaine précédence (extrait de la [documentation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable)) :
@ -659,7 +669,7 @@ Les tags permettent de ranger/trier chaque tâche ou rôle dans une catégorie.
~~~{.yaml}
- name: Coucou
debug:
ansible.builtin.debug:
msg: "Saloute!"
tags: message
~~~
@ -686,14 +696,14 @@ Pour `shell`, on a le droit à `.stdout`, `.stderr`, `.rc`… mais cela dépend
Il est possible de consulter le contenu détaillé de la variable avec `debug` :
~~~{.yaml}
- stat:
- ansible.builtin.stat:
path: /etc/passwd
register: st
- debug:
- ansible.builtin.debug:
var: st
- fail:
- ansible.builtin.fail:
msg: "Whoops! file ownership has changed"
when: st.stat.pw_name != 'root'
~~~
@ -705,7 +715,7 @@ Le contenu d'une variable issue d'un `register` peut être utilisé dans des con
Dans l'exemple ci-dessus on utilise une valeur intrinsèque de l'objet `stat` généré par le module, mais il y a des valeurs qui sont utilisables quel que soit le module utilisé.
~~~{.yaml}
- copy:
- ansible.builtin.copy:
src: my_file
dst: /path/to/file
register: _file_copy
@ -778,7 +788,7 @@ Les _tasks_ et les _roles_ peuvent être soumis à conditions. Cela repose sur l
Exemple pour installer un paquet seulement si la distribution est en version 9 ou plus
~~~{.yaml}
- apt:
- ansible.builtin.apt:
name: libapache2-mpm-itk
state: present
when: ansible_distribution_major_version is version('9', '>=')
@ -789,7 +799,7 @@ Exemple pour installer un paquet seulement si la distribution est en version 9 o
Il est possible de combiner plusieurs conditions sur la même ligne, en combinant des `and`ou des `or` :
~~~{.yaml}
- apt:
- ansible.builtin.apt:
name: libapache2-mpm-itk
state: present
when: ansible_distribution_major_version is version('9', '=') or ansible_distribution_major_version is version('10', '=')
@ -798,7 +808,7 @@ Il est possible de combiner plusieurs conditions sur la même ligne, en combinan
Il est possible de séparer les conditions sur plusieurs lignes, elle doivent alors être toutes respectées, comme jointe spar des `and` :
~~~{.yaml}
- apt:
- ansible.builtin.apt:
name: libapache2-mpm-itk
state: present
when:
@ -831,7 +841,7 @@ Il est possible d'inverser une condition (quelle qu'elle soit) en la précédant
~~~{.yaml}
- name: remove file is feature is disabled
file:
ansible.builtin.file:
path: /path/to/file
state: absent
when: not (feature_enabled | bool)
@ -840,7 +850,7 @@ Il est possible d'inverser une condition (quelle qu'elle soit) en la précédant
Il est possible d'avoir 2 valeurs non booléennes en fonction d'une variable booléenne. Exemple pour qu'un fichier soit présent ou absent selon la variable `feature_enabled` :
~~~{.yaml}
- file:
- ansible.builtin.file:
path: /path/to/file
state: "{{ feature_enabled | bool | ternary('present','absent') }}"
~~~
@ -919,7 +929,7 @@ On va donc faire une boucle avec la liste des groupes définit dans l'attribut "
~~~
- name: "Create secondary groups"
group:
ansible.builtin.group:
name: "{{ item }}"
with_items: "{{ users.values() | map(attribute='groups') | list | unique }}"
~~~
@ -1002,7 +1012,7 @@ $ ansible-playbook --check --diff my-experimental-playbook.yml
Pour par exemple, stopper le code à un moment pour lire les valeurs d'une variables
~~~{.yaml}
- debug:
- ansible.builtin.debug:
var: foo
- command: /bin/false
@ -1011,20 +1021,20 @@ Pour par exemple, stopper le code à un moment pour lire les valeurs d'une varia
ou
~~~{.yaml}
- debug:
- ansible.builtin.debug:
var: foo
- fail:
- ansible.builtin.fail:
msg: "FAIL"
~~~
ou
~~~{.yaml}
- debug:
- ansible.builtin.debug:
var: foo
- pause:
- ansible.builtin.pause:
~~~
### Lancement tâches hosts asynchrone
@ -1103,13 +1113,13 @@ S'il manque une valeur pour la suite du script, soit on le gère en mettant une
~~~{.yaml}
vars_prompt:
- name: 'prenom'
prompt: 'Quel est votre prénom ?'
private: no
- name: 'prenom'
prompt: 'Quel est votre prénom ?'
private: no
tasks:
- debug:
var: prenom
- ansible.builtin.debug:
var: prenom
~~~
Malheureusement pour le moment, cela doit se situer avant `tasks`.
@ -1145,11 +1155,12 @@ C'est beaucoup plus simple et rapide que de tester le fichier par le module `sta
~~~{.yaml}
- name: /etc/hosts
command: cat /etc/hosts
ansible.builtin.command:
cmd: cat /etc/hosts
register: tmp
delegate_to: localhost
- debug:
- ansible.builtin.debug:
var: tmp.stdout
~~~
@ -1173,12 +1184,13 @@ Si cet attribut est utilisé avec `delegate_to`, alors cette machine sera la seu
~~~{.yaml}
- name: Manger les fruits
command: eat '{{ item }}'
ansible.builtin.command:
cmd: eat '{{ item }}'
with_items:
- Apple
- Orange
- Strawberry
- Mango
- Apple
- Orange
- Strawberry
- Mango
~~~
Par exemple pour l'installation de plusieurs nouveaux paquets :
@ -1188,14 +1200,14 @@ Par exemple pour l'installation de plusieurs nouveaux paquets :
- hosts: localhost
tasks:
- apt:
- ansible.builtin.apt:
name: '{{ item }}'
state: present
with_items:
- cmatrix
- tetrinet-server
- tetrinet-client
- xtel
- cmatrix
- tetrinet-server
- tetrinet-client
- xtel
~~~
Même si il y aura plusieurs paquets installés, cela ne comptera que pour *un* changement (`changed=1`).
@ -1212,8 +1224,8 @@ tasks:
user: "{{ item[0] }}"
server: "{{ item[1] }}"
with_nested:
- [ 'alice', 'bob' ]
- [ 'machine1', 'machine2', 'machine-backup' ]
- [ 'alice', 'bob' ]
- [ 'machine1', 'machine2', 'machine-backup' ]
~~~
Cela a pour effet d'exécuter l'inclusion pour `alice` pour chacune des 3 machines, puis pour `bob` pour chacune des 3 machines.
@ -1248,14 +1260,14 @@ Permet de prendre le premier fichier trouvé :
~~~{.yaml}
- name: Copy HAProxy configuration
template:
ansible.builtin.template:
src: "{{ item }}"
dest: /etc/haproxy/haproxy.cfg
force: yes
with_first_found:
- "haproxy.cfg/{{ inventory_hostname }}"
- "haproxy.cfg/{{ host_group }}"
- "aproxy.cfg/default"
- "haproxy.cfg/{{ inventory_hostname }}"
- "haproxy.cfg/{{ host_group }}"
- "aproxy.cfg/default"
~~~
De cette manière, si un fichier portant le nom du serveur en cours existe, il sera utilisé, sinon on cherche un fichier du nom du groupe du serveur et enfin on cherche un fichier par défaut, valable pour tous les serveurs qui n'ont pas de configuration spécifique ou de groupe.
@ -1281,7 +1293,7 @@ Pour des modules comme `shell`, `command`… Ansible ne peut savoir si un change
Il est possible de forcer le statut du changement :
~~~{.yaml}
- command: date
- ansible.builtin.command: date
changed_when: False
~~~
@ -1325,7 +1337,7 @@ Pour récupérer toutes les adresses MAC des machines :
gather_facts: true
tasks:
- debug:
- ansible.builtin.debug:
var: ansible_eth0.macaddress
~~~
@ -1428,13 +1440,13 @@ Un cas concret :
~~~{.yaml}
- name: Install monitoring-plugins on OpenBSD 5.6 and later
openbsd_pkg:
community.general.openbsd_pkg:
name: monitoring-plugins
state: present
when: ansible_distribution_version is version('5.6', '>=')
- name: Install nagios-plugins on OpenBSD before 5.6
openbsd_pkg:
community.general.openbsd_pkg:
name: nagios-plugins
state: present
when: ansible_distribution_version is version("5.6",'<')