fix 004
Ansible - controle du code / controle (push) Successful in 3m42s
Ansible - controle du code / promouvoir (push) Failing after 3s

This commit is contained in:
hcornet committed 2026-09-15 17:43:07 +02:00
1 parent 05141e6ec2
commit b307a35eb4
9 files changed
+46 -32

No files matched your search

+4 -7
View File
@@ -39,17 +39,14 @@ jobs:
- name: Passer ansible-lint
run: ansible-lint
- name: Vérifier que chaque compte SSH a au moins une clé
- name: Vérifier que les clés déclarées dans ssh_users existent
run: |
set -euo pipefail
manquants=0
for d in files/keys/*/; do
[ -d "$d" ] || continue
n=$(find "$d" -name '*.pub' | wc -l)
echo "$(basename "$d") : $n clé(s)"
[ "$n" -gt 0 ] || manquants=1
for f in $(grep -oE 'keys: \[[^]]*\]' group_vars/all/main.yml | tr -d '[]' | sed 's/keys: //; s/,/ /g'); do
if [ -f "files/keys/$f" ]; then echo "files/keys/$f : ok"; else echo "files/keys/$f : ABSENT"; manquants=1; fi
done
[ "$manquants" -eq 0 ] || { echo "Un répertoire de files/keys/ est vide"; exit 1; }
[ "$manquants" -eq 0 ]
promouvoir:
# Semaphore suit la branche « valide » : elle n'avance que depuis « main », après contrôle réussi.
+4 -3
View File
@@ -55,7 +55,7 @@ inventaire et vault versionnés, collections déclarées dans `collections/`.
│ ├── main.yml # réseaux, DNS, proxy, comptes, supervision, activation des rôles
│ └── vault.yml.example # à copier vers vault.yml, chiffrer, puis versionner
├── files/
│ ├── keys/<utilisateur>/*.pub # clés publiques SSH (versionnées)
│ ├── keys/*.pub # clés publiques SSH, attribuées par ssh_users[].keys
│ └── ca/*.crt # certificats racine internes (versionnés)
├── roles/ # common, proxy, dns, updates, ssh, firewall, fail2ban,
│ # os_hardening, snmp, nrpe, glpi_agent
@@ -68,8 +68,9 @@ inventaire et vault versionnés, collections déclarées dans `collections/`.
1. **Inventaire** : renseigner `inventory/hosts.yml`. Deux modes de connexion :
- compte de service `ansible` + sudo (`become` est activé dans `ansible.cfg`) ;
- root par clé, comme sur les VM Terraform : `ansible_user: root`, `become` est alors sans effet.
2. **Clés publiques** : un répertoire par compte dans `files/keys/`, un ou plusieurs
fichiers `*.pub` dedans. Le compte utilisé par Ansible **doit** y avoir une clé.
2. **Clés publiques** : fichiers `*.pub` à plat dans `files/keys/`, attribués aux comptes
par `ssh_users[].keys` dans `group_vars/all/main.yml`. Le compte utilisé par Ansible
(root) **doit** y avoir la clé de Semaphore.
3. **Certificat racine** (facultatif) : `files/ca/root-ca.crt` au format PEM.
4. **Secrets** : `cp group_vars/all/vault.yml.example group_vars/all/vault.yml`,
renseigner, puis `ansible-vault encrypt group_vars/all/vault.yml`.
+11 -9
View File
@@ -1,16 +1,18 @@
# Clés publiques SSH
Un sous-répertoire par utilisateur, contenant une ou plusieurs clés au format
OpenSSH (`*.pub`) :
Fichiers `*.pub` au format OpenSSH, déposés à plat (comme `cles/` du dépôt Terraform) :
files/keys/root/hcornet.pub
files/keys/root/ansible.pub
files/keys/ansible/ansible.pub
files/keys/hcornet/hcornet.pub
files/keys/hcornet.pub
files/keys/ansible.pub # clé de Semaphore
Le rôle `ssh` concatène les fichiers `*.pub` du répertoire portant le nom de
l'utilisateur et remplace intégralement le fichier de clés autorisées : une clé
retirée d'ici est retirée du serveur au passage suivant.
L'attribution aux comptes se fait dans `group_vars/all/main.yml` :
ssh_users:
- name: root
keys: [hcornet.pub, ansible.pub]
Le rôle `ssh` remplace intégralement le fichier de clés autorisées :
une clé retirée d'ici est retirée du serveur au passage suivant.
Les clés publiques sont versionnées : Semaphore clone le dépôt et doit les trouver.
Une clé publique n'est pas un secret ; ne jamais déposer de clé privée ici.
+1
View File
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINrHwV6BNYMsMBfNCEk23pIAx2FFLCA7f5lbhpEYT7/c semaphore@tips-of-mine
+1
View File
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFDIXkfS5dM3po9Jz7NKgd3t1H4vqh0/cVoxrAP42ivd thedj@ZEU
+5 -5
View File
@@ -24,16 +24,16 @@ dns_nameservers:
- 10.78.56.8
- 10.78.56.9
dns_search_domains:
- fr.dgs.group
- tips-of-mine.local
# ----------------------------------------------------------------- proxy ----
# Laisser vide pour ne configurer aucun proxy.
proxy_url: ""
# proxy_url: "http://serv-proxy.fr.dgs.group:3128"
# proxy_url: "http://serv-proxy.tips-of-mine.local:3128"
proxy_no_proxy:
- localhost
- 127.0.0.1
- .fr.dgs.group
- .tips-of-mine.local
# ------------------------------------------------------------------- SSH ----
# Les clés publiques sont lues dans files/keys/<utilisateur>/*.pub.
@@ -46,7 +46,7 @@ ssh_users:
- name: hcornet
groups: [sudo_or_wheel]
ssh_banner_organisation: "Tapis-Saint-Maclou"
ssh_banner_organisation: "Tips-Of-Mine"
# Logo ASCII repris de 01-ssh/banner, dans un fichier pour éviter tout souci d'indentation YAML.
ssh_banner_logo: "{{ lookup('ansible.builtin.file', playbook_dir ~ '/files/banner-logo.txt') }}"
@@ -57,7 +57,7 @@ snmp_communities:
nrpe_allowed_hosts: "{{ supervision_sources }}"
glpi_agent_server: "https://glpi.fr.dgs.group/marketplace/glpiinventory/"
glpi_agent_server: "https://glpi.tips-of-mine.fr/marketplace/glpiinventory/"
glpi_agent_tag: "ServeurProd"
# ------------------------------------------------------------- activation ----
+4 -4
View File
@@ -12,10 +12,10 @@ ssh_port: 22
# connecte en root) ; le mot de passe root reste utilisable sur la console.
ssh_permit_root_login: prohibit-password
# Comptes autorisés en SSH. Chaque entrée : name (obligatoire), groups (liste,
# « sudo_or_wheel » est traduit selon l'OS), sudo_nopasswd (bool), shell,
# password_hash (optionnel, pour un mot de passe local — jamais en clair).
# Les clés publiques sont lues dans files/keys/<name>/*.pub.
# Comptes autorisés en SSH. Chaque entrée : name (obligatoire), keys (liste de
# fichiers .pub pris dans files/keys/), groups (liste, « sudo_or_wheel » est
# traduit selon l'OS), sudo_nopasswd (bool), shell, password_hash (optionnel,
# pour un mot de passe local — jamais en clair).
ssh_users:
- name: root
+15 -3
View File
@@ -1,14 +1,26 @@
---
- name: Recenser les clés publiques disponibles par compte
- name: Recenser les clés publiques de chaque compte
# Fichiers listés dans « keys », à plat dans files/keys/ (comme cles/ du dépôt Terraform).
ansible.builtin.set_fact:
ssh_users_keys: >-
{{ ssh_users_keys | default({}) | combine({
item.name: lookup('ansible.builtin.fileglob', ssh_keys_dir ~ '/' ~ item.name ~ '/*.pub', wantlist=True)
item.name: item['keys'] | default([]) | map('regex_replace', '^', ssh_keys_dir ~ '/') | list
}) }}
loop: "{{ ssh_users }}"
loop_control:
label: "{{ item.name }}"
- name: Vérifier que les fichiers de clés déclarés existent
ansible.builtin.stat:
path: "{{ item }}"
delegate_to: localhost
become: false
loop: "{{ ssh_users_keys.values() | flatten | unique }}"
loop_control:
label: "{{ item | basename }}"
register: ssh_keys_stat
failed_when: not ssh_keys_stat.stat.exists
- name: Calculer la liste AllowUsers
ansible.builtin.set_fact:
ssh_allow_users_effective: "{{ ssh_users | map(attribute='name') | list }}"
@@ -23,7 +35,7 @@
- not (ssh_ansible_login == 'root' and ssh_permit_root_login == 'no')
fail_msg: >-
Le compte de connexion Ansible « {{ ssh_ansible_login }} » doit figurer dans ssh_users
avec au moins une clé dans {{ ssh_keys_dir }}/{{ ssh_ansible_login }}/*.pub,
avec au moins un fichier dans sa liste « keys » (présent dans {{ ssh_keys_dir }}/),
et ssh_permit_root_login ne peut pas valoir « no » si Ansible se connecte en root.
vars:
ssh_ansible_login: "{{ ansible_user | default('root') }}"
+1 -1
View File
@@ -1,5 +1,5 @@
# {{ ansible_managed }}
# Source : files/keys/{{ item.name }}/*.pub
# Source : {{ ssh_users_keys[item.name] | map("basename") | sort | join(", ") }}
{% for key_file in ssh_users_keys[item.name] | sort %}
{{ lookup('ansible.builtin.file', key_file) | trim }}
{% endfor %}