Ansible : cas pratique (1er partie)
Encore un article sur Ansible…mais cette fois avec une approche pas à pas et concrète d’une gestion de parc serveurs.
Je pars du principe que vous connaissez un peu le fonctionnement d’Ansible. Dans le cas contraire, vous pouvez consulter mon article précédent. L’article sera découpé en plusieurs parties pour rester digeste et un dépôt git sera mis à disposition avec l’ensemble du projet.
Contexte
Cet exemple couvre la gestion d’un parc de serveurs Debian 12 par une petite équipe composée de développeurs et d’administrateurs système:
- gestion des utilisateurs (2 catégories)
- installation des services de bases (postfix, snmpd, ntp, firewalld, sshd)
- mises à jour automatique (unattended_upgrades)
- installation d’outils de base
L’infrastructure
Elle repose sur un serveur central de management (control node dans la terminologie Ansible) sous Debian 12. Ce serveur doit pouvoir se connecter en SSH à l’ensemble des serveurs à gérer. Inversement, les serveurs à gérer doivent pouvoir accéder au control node
en HTTP pour récupérer un petit script shell qui permettra de créer le compte ansible
pour les connexions en SSH.
Installer et créer la structure Ansible sur le control node (serveur central):
1sudo apt install ansible ansible-lint -y
2sudo mkdir /opt/Ansible && cd $_
3sudo mkdir host_vars group_vars roles inventories .ssh
4sudo touch inventories/production
le fichier
production
contiendra l’inventaire des serveurs à manager
Générer une paire de clés SSH pour la connexion aux serveurs à manager (managed nodes)
1sudo sh -c 'ssh-keygen -t ed25519 -f /opt/Ansible/.ssh/id_ed25519 -C "ansible@control-node"'
il est important de protéger la clé privée avec une passphrase robuste. En cas de compromission du serveur central et en l’absence de passphrase, il serait trivial de détruire l’ensemble du parc serveur.
Ajouter le fichier de configuration Ansible:
1sudo sh -c 'ansible-config init --disabled > /opt/Ansible/ansible.cfg'
Modifier la configuration d’Ansible:
Dans le fichier /opt/Ansible/ansible.cfg
, je vais préciser:
- le chemin vers la clé SSH à utiliser:
private_key_file=.ssh/id_ed25519
- le chemin vers le fichier d’inventaire:
inventory=./inventories/production
- renoncer à la vérification des clés SSH:
host_key_checking=False
- définir l’utilisateur
ansible
par défaut:remote_user=ansible
la commande
ansible-config dump --only-changed -t all
permet d’afficher uniquement les valeurs modifiées
Installer un serveur web:
Il sera utilisé uniquement pour récupérer le script de création du compte ansible
sur les serveurs à manager.
1sudo apt install lighttpd -y
2sudo rm /var/www/html/index.lighttpd.html
Copier le script shell suivant dans /var/www/html/setup.sh
(modifier la variable SSH_PUBLIC_KEY
avec le contenu du fichier /opt/Ansible/.ssh/id_ed25519.pub
créé précédemment)
1#!/bin/bash
2# Create Ansible user and add this pubkey
3#
4if [ "$(id -u)" -ne 0 ]; then
5 echo "This script must be run as root."
6 exit 1
7fi
8
9# Install requirements
10apt install sudo -y
11
12# Define variables
13USERNAME="ansible"
14SSH_PUBLIC_KEY="copier-ici-la-clé-publique-créée-précédemment"
15
16# Add the new user
17adduser --disabled-password --gecos "Ansible User" $USERNAME
18
19# Create .ssh directory and set permissions
20mkdir -p /home/$USERNAME/.ssh
21chmod 700 /home/$USERNAME/.ssh
22
23# Add the provided SSH public key to authorized_keys
24echo $SSH_PUBLIC_KEY > /home/$USERNAME/.ssh/authorized_keys
25chmod 600 /home/$USERNAME/.ssh/authorized_keys
26chown -R $USERNAME:$USERNAME /home/$USERNAME
27chmod 700 /home/$USERNAME
28
29# Allow new user to use sudo without password
30echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME
31chmod 440 /etc/sudoers.d/$USERNAME
Cette étape est facultative mais permet de gagner du temps lors du déploiement des serveurs. Vous pouvez aussi l’automatiser lors d’une install PXE (preseed), avec du Cloud-Init ou du Terraform…
Configurer les serveurs à manager
Sur les serveurs à manager, il faut ajouter le compte ansible
en utilisant le script:
A exécuter en tant que root
en modifiant l’URL pour pointer vers votre control node
1wget -qO - http://<url-control-node>/setup.sh | bash
Ajouter les serveurs managés dans l’inventaire ansible du control node: /opt/Ansible/inventories/production
1[debian_12]
2serveur-01.exemple.com # description
3serveur-02.exemple.com # description
Il est possible d’utiliser la notation:
serveur-[01:02].exemple.com
Tester le fonctionnement d’Ansible :
1cd /opt/Ansible
2sudo ansible all -m shell -a 'cat /etc/issue'
3
4serveur-01.exemple.com | CHANGED | rc=0 >>
5Debian GNU/Linux 12 \n \l
Ansible se connecte bien aux serveurs en utilisant les paramètres définis dans le fichier de configuration.
Ajouter le rôle “debian_12”
Ce rôle va permettre de gérer la configuration initiale et l’ensemble des services de base.
sur le control node:
1cd /opt/Ansible
2sudo ansible-galaxy role init --init-path ./roles debian_12
Pour rappel, cette commande va générer toute la structure de dossiers et fichiers nécéssaire au fonctionnement du role.
Ajouter des tâches dans le rôle
Les tâches doivent être définis dans le fichier: /opt/Ansible/roles/debian_12/tasks/main.yml
Pour plus de lisibilité, je vais utiliser des inclusions pour gérer chaque partie.
Installer les paquets de base
Je commence toujours par installer les pré-requis.
Sur le control node, dans le fichier: /opt/Ansible/roles/debian_12/tasks/main.yml
1---
2- name: Include install default packets
3 ansible.builtin.include_tasks: packages.yml
4 tags: packages
et dans le fichier: /opt/Ansible/roles/debian_12/tasks/packages.yml
1---
2- name: Add common packages
3 ansible.builtin.package:
4 name:
5 - vim
6 - unzip
7 - zsh
8 - bash-completion
9 - htop
10 - nmap
11 - nload
12 - snmpd
13 - chrony
14 - cloud-guest-utils
15 - net-tools
16 - xfsprogs
17 - bsd-mailx
18 - tree
19 state: present
20 tags: packages
Rien de particulier ici, le module package
d’Ansible va itérer sur la liste de paquets à installer.
Gestion des utilisateurs
On aborde un gros morceau avec la gestion des utilisateurs et les règles de gestions suivantes:
- gérer 2 catégories d’utilisateurs (admins et développeurs)
- ajouter les comptes admins par défaut et les comptes developpeurs uniquement sur certains serveurs
- autoriser l’accès SSH uniquement pour les membres du groupe
ssh-users
- authentification par clés publiques SSH par défaut
- autoriser l’accès par mot de passe pour des intervenants occasionnels appartenant au groupe
ssh-nokey
- autoriser l’utilisation de
sudo
sans mot de passe pour les membres du groupesudo
- simplifier le cycle de vie des comptes (ajout,suppression,remplacement de clés)
- refuser les connexion
root
en SSH
Sur le control node, je vais ajouter 2 dossiers:
/opt/Ansible/files
: pour stocker les fichiers contenants les clés publiques des utilisateurs/opt/Ansible/users_vars
: pour gérer les variables propres à chaque utilisateur
1sudo mkdir -p /opt/Ansible/files/pubkeys /opt/Ansible/users_vars
2sudo touch /opt/Ansible/users_vars/main.yml
La tentation est grande de mettre les variables des utilisateurs et les fichiers dans les dossiers prévus à cet effet directement dans le rôle. Mais dans ce découpage d’inventaire par famille d’OS, il ne serait pas possible de factoriser ces éléments entre différentes versions (debian_13, rockylinux_9, etc…).
Dans le fichier /opt/Ansible/group_vars/all
, j’ajoute une variable add_dev_users: no
dans la section defaults
1# Global
2ansible_connection: ssh
3ansible_user: ansible
4default_shell: /bin/bash
5
6# Default
7add_dev_users: false
Dans le fichier: /opt/Ansible/users_vars/main.yml
1---
2# utiliser la commande `mkpasswd --method=sha-512` pour générer le hash du password
3admin_users:
4 - username: solohan
5 state: present
6 comment: Han Solo
7 groups: sudo,ssh-users
8 password: "$6$SzlZvkG88iMYtAOV$LQXxHREb85Jv7onoxJfW7Y02aoWr51v8hrL.QkyPEzuQ93nHxSY/YvoKM5JJQN0ARhtam1QUibA/9CJGx6gZo0"
9
10 - username: skywalkerluke
11 state: present
12 comment: Luke Skywalker
13 groups: sudo,ssh-users
14 password: "$6$AcgkntPPP6XVx3hf$GWJnTPHuVPyqO2IeBHxWRSxb2D8Bg8yu0oHZ6SRSyT8tzPr5NieqcZheqaJLWUYtKy3U2o/xzC1kleU5aVsBx0"
15
16dev_users:
17 - username: vadordark
18 state: present
19 comment: Dark Vador
20 groups: sudo,ssh-users
21 password: "$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1"
22
23 - username: renkylo
24 state: present
25 comment: Kylo Ren
26 groups: sudo,ssh-users
27 password: "$6$ZaC.HNhhEGF/ZoSF$ees9o9i90qd2rjhKJXKh3OUxQWjslnKb4tOeqdh3a7RzBRUV3SgV.0bWyuSvURPYgZiQNQyH4sb.UuhKknD771"
Ici, tous les utilisateurs pourront obtenir une connexion SSH et utiliser sudo
.
Dans le répertoire /opt/Ansible/files/pubkeys
, je vais créer un fichier par utilisateur contenant sa clé publique SSH.
Il est important que le nom du fichier soit le nom de connexion de l’utilisateur (username)
1tree /opt/Ansible/files/pubkeys/
2/opt/Ansible/files/pubkeys/
3├── renkylo
4├── skywalkerluke
5├── solohan
6└── vadordark
7cat /opt/Ansible/files/pubkeys/solohan
8ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOzRGvI6qSFBYHSyseuTEzwm74KMISfUz9SAN7hWV/xW solohan@laptop
Rajouter dans le fichier: /opt/Ansible/roles/debian_12/tasks/main.yml
1- name: Include users tasks
2 ansible.builtin.include_tasks: users.yml
3 tags: users
Dans le fichier: /opt/Ansible/roles/debian_12/tasks/users.yml
1---
2- name: Include external variables
3 ansible.builtin.include_vars: ../../users_vars/main.yml
4 tags: users
5
6- name: Create users with bash as default shell
7 ansible.builtin.lineinfile:
8 path: "/etc/default/useradd"
9 regexp: "^SHELL=/bin/sh"
10 line: "SHELL=/bin/bash"
11 tags: users
12
13- name: Ensure group "ssh-nokey" exist
14 ansible.builtin.group:
15 name: ssh-nokey
16 state: present
17 tags: users
18
19- name: Ensure group "sudo" exist
20 ansible.builtin.group:
21 name: sudo
22 state: present
23 tags: users
24
25- name: Ensure group "ssh-users" exist
26 ansible.builtin.group:
27 name: ssh-users
28 state: present
29 tags: users
30
31- name: Add ansible user in "ssh-users"
32 ansible.builtin.user:
33 name: ansible
34 groups: ssh-users
35 tags: users
36
37- name: Create accounts for ADMIN
38 ansible.builtin.user:
39 name: "{{ item.username }}"
40 comment: "{{ item.comment }}"
41 groups: "{{ item.groups }}"
42 state: "{{ item.state }}"
43 password: "{{ item.password }}"
44 update_password: on_create
45 # update_password: always
46 append: yes
47 with_items: "{{ admin_users }}"
48 tags: users
49
50- name: Create accounts for DEV
51 ansible.builtin.user:
52 name: "{{ item.username }}"
53 comment: "{{ item.comment }}"
54 groups: "{{ item.groups }}"
55 state: "{{ item.state }}"
56 password: "{{ item.password }}"
57 update_password: on_create
58 # update_password: always
59 append: yes
60 with_items: "{{ dev_users }}"
61 when: add_dev_users
62 tags: users
63
64- name: Set ADMIN authorized key
65 ansible.posix.authorized_key:
66 user: "{{ item.username }}"
67 key: "{{ lookup('file', '../../files/pubkeys/' + item.username) }}"
68 with_items: "{{ admin_users }}"
69 when: item.state == "present"
70 tags: users
71
72- name: Set DEV authorized key
73 ansible.posix.authorized_key:
74 user: "{{ item.username }}"
75 key: "{{ lookup('file', '../../files/pubkeys/' + item.username) }}"
76 with_items: "{{ dev_users }}"
77 when: item.state == "present" and add_dev_users
78 tags: users
79
80- name: Remove ADMIN users homedir when user is absent
81 ansible.builtin.file:
82 path: /home/{{ item.username }}
83 state: absent
84 with_items: "{{ admin_users }}"
85 when: item.state == "absent"
86 tags: users
87
88- name: Remove DEV users homedir when user is absent
89 ansible.builtin.file:
90 path: /home/{{ item.username }}
91 state: absent
92 with_items: "{{ dev_users }}"
93 when: item.state == "absent" and add_dev_users
94 tags: users
95
96- name: Add sudo logfile
97 ansible.builtin.lineinfile:
98 path: /etc/sudoers
99 insertafter: "^Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin"
100 line: "Defaults logfile=/var/log/sudo.log"
101 tags: users
102
103- name: Enable passwordless for sudo group in sudoers
104 ansible.builtin.lineinfile:
105 path: /etc/sudoers
106 regexp: "^%sudo ALL=(ALL) ALL"
107 line: "%sudo {{ ansible_hostname }}=(ALL) NOPASSWD:ALL"
108 tags: users
La première tâche permet de charger les variables situées en dehors du rôle. Ensuite, je vérifie que les groupes dont j’ai besoin existe.
J’utilise la condition when pour créer les comptes des développeurs uniquement si la variable add_dev_users
est à true
(false
par défaut).
Dès lors, il suffira de déclarer cette variable dans /opt/Ansible/host_vars/<fqdn_du_serveur>
pour créer aussi ces comptes uniquement sur les serveurs qui le nécessite.
Configurer le serveur SSH
Rajouter dans le fichier: /opt/Ansible/roles/debian_12/tasks/main.yml
1- name: Include SSH server config
2 ansible.builtin.include_tasks: sshd.yml
3 tags: sshd
Dans le fichier: /opt/Ansible/roles/debian_12/tasks/sshd.yml
1---
2- name: Secure SSH server
3 ansible.builtin.template:
4 src: sshd-custom.conf.j2
5 dest: /etc/ssh/sshd_config.d/sshd-custom.conf
6 owner: root
7 group: root
8 mode: "0600"
9 notify: Restart sshd
10 tags: sshd
On utilise ici le mécanisme de handlers pour redémarrer de daemon SSH si la configuration change.
Dans le fichier /opt/Ansible/roles/debian_12/handlers/main.yml
1---
2# handlers for SSHD
3- name: Restart sshd
4 ansible.builtin.service:
5 name: sshd
6 state: restarted
Dans le fichier /opt/Ansible/roles/debian_12/templates/sshd-custom.conf.j2
1{{ ansible_managed | comment }}
2
3PermitRootLogin no
4PasswordAuthentication no
5
6# Disconnect idle client after 30mn
7ClientAliveInterval 1800
8ClientAliveCountMax 1
9
10MaxAuthTries 3
11MaxSessions 3
12
13# Only ssh-users group members can connect
14AllowGroups ssh-users
15
16# Allow password login for ssh-nokey group members
17Match Group ssh-nokey
18 PasswordAuthentication yes
19
20# End of 'Match' blocks
21Match all
Utiliser un playbook pour lancer le rôle.
Le projet est déjà bien avancé, il est temps de vérifier si tout fonctionne correctement. Pour cela, je vais ajouter un playbook pour appliquer le rôle sur l’ensemble des serveurs.
Dans le fichier /opt/Ansible/infra.yml
1---
2- name: Configure servers
3 hosts: debian_12
4 become: true
5 roles:
6 - debian_12
et utiliser le linter Ansible pour vérifier la syntaxe sur l’ensemble du projet:
1ansible-lint /opt/Ansible/infra.yml
2Read documentation for instructions on how to ignore specific rule violations.
3
4 Rule Violation Summary
5 count tag profile rule associated tags
6 1 schema[meta] basic core
7 3 meta-incorrect shared metadata
8 1 meta-no-info shared metadata
9
10Failed after min profile: 5 failure(s), 0 warning(s) on 9 files.
Hormis les métadonnées que je vous laisse personnaliser à votre guise, il n’y a pas d’erreur de syntaxe.
Je peux donc lancer le playbook (je limite volontairement à un seul serveur)
vous pouvez passer par une phase de “dry run” avec l’option
--check
mais qui n’est pas toujours très concluante quand certaines tâches dépendent d’autres non réellement appliquées.
1sudo ansible-playbook infra.yml --limit serveur-01.exemple.com
1PLAY [Configure servers] **************************************************************************
2
3TASK [Gathering Facts] ****************************************************************************
4Enter passphrase for key '/opt/Ansible/.ssh/id_ed25519':
5ok: [serveur-01.exemple.com]
6
7TASK [debian_12 : Include install default packets] ************************************************
8included: /opt/Ansible/roles/debian_12/tasks/packages.yml for serveur-01.exemple.com
9
10TASK [debian_12 : Add common packages] ************************************************************
11changed: [serveur-01.exemple.com]
12
13TASK [debian_12 : Include users tasks] ************************************************************
14included: /opt/Ansible/roles/debian_12/tasks/users.yml for serveur-01.exemple.com
15
16TASK [debian_12 : Include external variables] *****************************************************
17ok: [serveur-01.exemple.com]
18
19TASK [debian_12 : Create users with bash as default shell] ****************************************
20changed: [serveur-01.exemple.com]
21
22TASK [debian_12 : Ensure group "ssh-nokey" exist] *************************************************
23changed: [serveur-01.exemple.com]
24
25TASK [debian_12 : Ensure group "sudo" exist] ******************************************************
26ok: [serveur-01.exemple.com]
27
28TASK [debian_12 : Ensure group "ssh-users" exist] *************************************************
29changed: [serveur-01.exemple.com]
30
31TASK [debian_12 : Add ansible user in "ssh-users"] ************************************************
32changed: [serveur-01.exemple.com]
33
34TASK [debian_12 : Create accounts for ADMIN] ******************************************************
35changed: [serveur-01.exemple.com] => (item={'username': 'solohan', 'state': 'present', 'comment': 'Han Solo', 'groups': 'sudo,ssh-users', 'password': '$6$SzlZvkG88iMYtAOV$LQXxHREb85Jv7onoxJfW7Y02aoWr51v8hrL.QkyPEzuQ93nHxSY/YvoKM5JJQN0ARhtam1QUibA/9CJGx6gZo0'})
36changed: [serveur-01.exemple.com] => (item={'username': 'skywalkerluke', 'state': 'present', 'comment': 'Luke Skywalker', 'groups': 'sudo,ssh-users', 'password': '$6$AcgkntPPP6XVx3hf$GWJnTPHuVPyqO2IeBHxWRSxb2D8Bg8yu0oHZ6SRSyT8tzPr5NieqcZheqaJLWUYtKy3U2o/xzC1kleU5aVsBx0'})
37
38TASK [debian_12 : Create accounts for DEV] ********************************************************
39skipping: [serveur-01.exemple.com] => (item={'username': 'vadordark', 'state': 'present', 'comment': 'Dark Vador', 'groups': 'sudo,ssh-users', 'password': '$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1'})
40skipping: [serveur-01.exemple.com] => (item={'username': 'renkylo', 'state': 'present', 'comment': 'Kylo Ren', 'groups': 'sudo,ssh-users', 'password': '$6$ZaC.HNhhEGF/ZoSF$ees9o9i90qd2rjhKJXKh3OUxQWjslnKb4tOeqdh3a7RzBRUV3SgV.0bWyuSvURPYgZiQNQyH4sb.UuhKknD771'})
41skipping: [serveur-01.exemple.com]
42
43TASK [debian_12 : Set ADMIN authorized key] *******************************************************
44changed: [serveur-01.exemple.com] => (item={'username': 'solohan', 'state': 'present', 'comment': 'Han Solo', 'groups': 'sudo,ssh-users', 'password': '$6$SzlZvkG88iMYtAOV$LQXxHREb85Jv7onoxJfW7Y02aoWr51v8hrL.QkyPEzuQ93nHxSY/YvoKM5JJQN0ARhtam1QUibA/9CJGx6gZo0'})
45changed: [serveur-01.exemple.com] => (item={'username': 'skywalkerluke', 'state': 'present', 'comment': 'Luke Skywalker', 'groups': 'sudo,ssh-users', 'password': '$6$AcgkntPPP6XVx3hf$GWJnTPHuVPyqO2IeBHxWRSxb2D8Bg8yu0oHZ6SRSyT8tzPr5NieqcZheqaJLWUYtKy3U2o/xzC1kleU5aVsBx0'})
46
47TASK [debian_12 : Set DEV authorized key] *********************************************************
48skipping: [serveur-01.exemple.com] => (item={'username': 'vadordark', 'state': 'present', 'comment': 'Dark Vador', 'groups': 'sudo,ssh-users', 'password': '$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1'})
49skipping: [serveur-01.exemple.com] => (item={'username': 'renkylo', 'state': 'present', 'comment': 'Kylo Ren', 'groups': 'sudo,ssh-users', 'password': '$6$ZaC.HNhhEGF/ZoSF$ees9o9i90qd2rjhKJXKh3OUxQWjslnKb4tOeqdh3a7RzBRUV3SgV.0bWyuSvURPYgZiQNQyH4sb.UuhKknD771'})
50skipping: [serveur-01.exemple.com]
51
52TASK [debian_12 : Remove ADMIN users homedir when user is absent] *********************************
53skipping: [serveur-01.exemple.com] => (item={'username': 'solohan', 'state': 'present', 'comment': 'Han Solo', 'groups': 'sudo,ssh-users', 'password': '$6$SzlZvkG88iMYtAOV$LQXxHREb85Jv7onoxJfW7Y02aoWr51v8hrL.QkyPEzuQ93nHxSY/YvoKM5JJQN0ARhtam1QUibA/9CJGx6gZo0'})
54skipping: [serveur-01.exemple.com] => (item={'username': 'skywalkerluke', 'state': 'present', 'comment': 'Luke Skywalker', 'groups': 'sudo,ssh-users', 'password': '$6$AcgkntPPP6XVx3hf$GWJnTPHuVPyqO2IeBHxWRSxb2D8Bg8yu0oHZ6SRSyT8tzPr5NieqcZheqaJLWUYtKy3U2o/xzC1kleU5aVsBx0'})
55skipping: [serveur-01.exemple.com]
56
57TASK [debian_12 : Remove DEV users homedir when user is absent] ***********************************
58skipping: [serveur-01.exemple.com] => (item={'username': 'vadordark', 'state': 'present', 'comment': 'Dark Vador', 'groups': 'sudo,ssh-users', 'password': '$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1'})
59skipping: [serveur-01.exemple.com] => (item={'username': 'renkylo', 'state': 'present', 'comment': 'Kylo Ren', 'groups': 'sudo,ssh-users', 'password': '$6$ZaC.HNhhEGF/ZoSF$ees9o9i90qd2rjhKJXKh3OUxQWjslnKb4tOeqdh3a7RzBRUV3SgV.0bWyuSvURPYgZiQNQyH4sb.UuhKknD771'})
60skipping: [serveur-01.exemple.com]
61
62TASK [debian_12 : Add sudo logfile] ***************************************************************
63changed: [serveur-01.exemple.com]
64
65TASK [debian_12 : Enable passwordless for sudo group in sudoers] **********************************
66changed: [serveur-01.exemple.com]
67
68TASK [debian_12 : Include SSH server config] ******************************************************
69included: /opt/Ansible/roles/debian_12/tasks/sshd.yml for serveur-01.exemple.com
70
71TASK [debian_12 : Secure SSH server] **************************************************************
72changed: [serveur-01.exemple.com]
73
74RUNNING HANDLER [debian_12 : Restart sshd] ********************************************************
75changed: [serveur-01.exemple.com]
76
77PLAY RECAP ****************************************************************************************
78serveur-01.exemple.com : ok=17 changed=11 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
Je rajoute maintenant les comptes des développeurs:
Dans le fichier: /opt/Ansible/host_vars/serveur-01.exemple.com
1add_dev_users: true
Je profite de l’utilisation des tags, pour relancer le playbook uniquement sur la partie users
.
1sudo ansible-playbook infra.yml --limit serveur-01.exemple.com --tags users
1PLAY [Configure servers] ***********************************************************************************************************************************************************************************
2
3TASK [Gathering Facts] *************************************************************************************************************************************************************************************
4Enter passphrase for key '/opt/Ansible/.ssh/id_ed25519':
5ok: [serveur-01.exemple.com]
6
7TASK [debian_12 : Include users tasks] *********************************************************************************************************************************************************************
8included: /opt/Ansible/roles/debian_12/tasks/users.yml for serveur-01.exemple.com
9
10TASK [debian_12 : Include external variables] **************************************************************************************************************************************************************
11ok: [serveur-01.exemple.com]
12
13TASK [debian_12 : Create users with bash as default shell] *************************************************************************************************************************************************
14ok: [serveur-01.exemple.com]
15
16TASK [debian_12 : Ensure group "ssh-nokey" exist] **********************************************************************************************************************************************************
17ok: [serveur-01.exemple.com]
18
19TASK [debian_12 : Ensure group "sudo" exist] ***************************************************************************************************************************************************************
20ok: [serveur-01.exemple.com]
21
22TASK [debian_12 : Ensure group "ssh-users" exist] **********************************************************************************************************************************************************
23ok: [serveur-01.exemple.com]
24
25TASK [debian_12 : Add ansible user in "ssh-users"] *********************************************************************************************************************************************************
26ok: [serveur-01.exemple.com]
27
28TASK [debian_12 : Create accounts for ADMIN] ***************************************************************************************************************************************************************
29ok: [serveur-01.exemple.com] => (item={'username': 'solohan', 'state': 'present', 'comment': 'Han Solo', 'groups': 'sudo,ssh-users', 'password': '$6$SzlZvkG88iMYtAOV$LQXxHREb85Jv7onoxJfW7Y02aoWr51v8hrL.QkyPEzuQ93nHxSY/YvoKM5JJQN0ARhtam1QUibA/9CJGx6gZo0'})
30ok: [serveur-01.exemple.com] => (item={'username': 'skywalkerluke', 'state': 'present', 'comment': 'Luke Skywalker', 'groups': 'sudo,ssh-users', 'password': '$6$AcgkntPPP6XVx3hf$GWJnTPHuVPyqO2IeBHxWRSxb2D8Bg8yu0oHZ6SRSyT8tzPr5NieqcZheqaJLWUYtKy3U2o/xzC1kleU5aVsBx0'})
31
32TASK [debian_12 : Create accounts for DEV] *****************************************************************************************************************************************************************
33changed: [serveur-01.exemple.com] => (item={'username': 'vadordark', 'state': 'present', 'comment': 'Dark Vador', 'groups': 'sudo,ssh-users', 'password': '$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1'})
34changed: [serveur-01.exemple.com] => (item={'username': 'renkylo', 'state': 'present', 'comment': 'Kylo Ren', 'groups': 'sudo,ssh-users', 'password': '$6$ZaC.HNhhEGF/ZoSF$ees9o9i90qd2rjhKJXKh3OUxQWjslnKb4tOeqdh3a7RzBRUV3SgV.0bWyuSvURPYgZiQNQyH4sb.UuhKknD771'})
35
36TASK [debian_12 : Set ADMIN authorized key] ****************************************************************************************************************************************************************
37ok: [serveur-01.exemple.com] => (item={'username': 'solohan', 'state': 'present', 'comment': 'Han Solo', 'groups': 'sudo,ssh-users', 'password': '$6$SzlZvkG88iMYtAOV$LQXxHREb85Jv7onoxJfW7Y02aoWr51v8hrL.QkyPEzuQ93nHxSY/YvoKM5JJQN0ARhtam1QUibA/9CJGx6gZo0'})
38ok: [serveur-01.exemple.com] => (item={'username': 'skywalkerluke', 'state': 'present', 'comment': 'Luke Skywalker', 'groups': 'sudo,ssh-users', 'password': '$6$AcgkntPPP6XVx3hf$GWJnTPHuVPyqO2IeBHxWRSxb2D8Bg8yu0oHZ6SRSyT8tzPr5NieqcZheqaJLWUYtKy3U2o/xzC1kleU5aVsBx0'})
39
40TASK [debian_12 : Set DEV authorized key] ******************************************************************************************************************************************************************
41changed: [serveur-01.exemple.com] => (item={'username': 'vadordark', 'state': 'present', 'comment': 'Dark Vador', 'groups': 'sudo,ssh-users', 'password': '$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1'})
42changed: [serveur-01.exemple.com] => (item={'username': 'renkylo', 'state': 'present', 'comment': 'Kylo Ren', 'groups': 'sudo,ssh-users', 'password': '$6$ZaC.HNhhEGF/ZoSF$ees9o9i90qd2rjhKJXKh3OUxQWjslnKb4tOeqdh3a7RzBRUV3SgV.0bWyuSvURPYgZiQNQyH4sb.UuhKknD771'})
43
44TASK [debian_12 : Remove ADMIN users homedir when user is absent] ******************************************************************************************************************************************
45skipping: [serveur-01.exemple.com] => (item={'username': 'solohan', 'state': 'present', 'comment': 'Han Solo', 'groups': 'sudo,ssh-users', 'password': '$6$SzlZvkG88iMYtAOV$LQXxHREb85Jv7onoxJfW7Y02aoWr51v8hrL.QkyPEzuQ93nHxSY/YvoKM5JJQN0ARhtam1QUibA/9CJGx6gZo0'})
46skipping: [serveur-01.exemple.com] => (item={'username': 'skywalkerluke', 'state': 'present', 'comment': 'Luke Skywalker', 'groups': 'sudo,ssh-users', 'password': '$6$AcgkntPPP6XVx3hf$GWJnTPHuVPyqO2IeBHxWRSxb2D8Bg8yu0oHZ6SRSyT8tzPr5NieqcZheqaJLWUYtKy3U2o/xzC1kleU5aVsBx0'})
47skipping: [serveur-01.exemple.com]
48
49TASK [debian_12 : Remove DEV users homedir when user is absent] ********************************************************************************************************************************************
50skipping: [serveur-01.exemple.com] => (item={'username': 'vadordark', 'state': 'present', 'comment': 'Dark Vador', 'groups': 'sudo,ssh-users', 'password': '$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1'})
51skipping: [serveur-01.exemple.com] => (item={'username': 'renkylo', 'state': 'present', 'comment': 'Kylo Ren', 'groups': 'sudo,ssh-users', 'password': '$6$ZaC.HNhhEGF/ZoSF$ees9o9i90qd2rjhKJXKh3OUxQWjslnKb4tOeqdh3a7RzBRUV3SgV.0bWyuSvURPYgZiQNQyH4sb.UuhKknD771'})
52skipping: [serveur-01.exemple.com]
53
54TASK [debian_12 : Add sudo logfile] ************************************************************************************************************************************************************************
55ok: [serveur-01.exemple.com]
56
57TASK [debian_12 : Enable passwordless for sudo group in sudoers] *******************************************************************************************************************************************
58ok: [serveur-01.exemple.com]
59
60PLAY RECAP *************************************************************************************************************************************************************************************************
61serveur-01.exemple.com : ok=14 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Cette fois, les comptes des développeurs sont bien ajoutés. Si je dois supprimer un utilisateur particulier, il suffit de passer le state
de son compte à absent
.
Dans le fichier: /opt/Ansible/users_vars/main.yml
1dev_users:
2 - username: vadordark
3 state: absent
4 comment: Dark Vador
5 groups: sudo,ssh-users
6 password: "$6$E0XYQTabJWodgk4E$z2UZFtnjVCmPsL/fg7V8AB2EJfbcpwH5t5ngSEi4MWMr0DZ7PamSYZLoeKaUuzZ2jwYb22Lmum.MYooh9j2fb1"
et relancer le playbook:
1sudo ansible-playbook infra.yml --limit serveur-01.exemple.com --tags users
2PLAY RECAP *************************************************************************************************************************************************************************************************
3serveur-01.exemple.com : ok=15 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Le compte de Dark Vador et son répertoire personnel sont bien supprimés.
Conclusion
Fin de cette première partie déjà bien dense. Si vous avez des pistes d’amélioration, n’hésitez pas à me les remonter (@BrunoL@mamot.fr ). Dans la prochaine partie, on finira de configurer les services de bases…à suivre !
Photo de Lenny Kuhne sur Unsplash