Automatiser les tâches d'administration RHEL avec Ansible

AnsibleBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire complet, vous maîtriserez l'automatisation des tâches critiques d'administration Linux à l'aide d'Ansible. En vous appuyant sur vos connaissances en gestion de fichiers, vous explorerez désormais comment gérer le cycle de vie complet de l'administration système, de l'installation de logiciels à la gestion des utilisateurs, en passant par la configuration des services, le provisionnement du stockage et la configuration réseau.

Vous commencerez par automatiser la gestion des paquets logiciels et la configuration des dépôts à l'aide de modules tels que ansible.builtin.dnf, ansible.builtin.yum_repository et ansible.builtin.rpm_key. Ensuite, vous créerez et gérerez des comptes utilisateurs, configurerez l'accès SSH et établirez les privilèges sudo. Le laboratoire progresse vers la gestion des services, les tâches planifiées avec cron et systemd, avant de passer à la gestion du stockage à l'aide de LVM et des opérations sur les systèmes de fichiers. Enfin, vous configurerez les interfaces réseau et collecterez des informations système.

Ce laboratoire met l'accent sur des scénarios réels couramment rencontrés dans les environnements Linux d'entreprise, vous préparant à mettre en œuvre efficacement les pratiques d'Infrastructure as Code (Infrastructure en tant que Code).

Configurer le dépôt et gérer les paquets logiciels

Dans cette étape, vous apprendrez à automatiser la gestion des paquets logiciels sur les systèmes RHEL à l'aide d'Ansible. Vous configurerez un dépôt Yum, gérerez les clés GPG RPM et collecterez des informations sur les paquets sur les hôtes gérés. Ceci est essentiel pour maintenir des installations logicielles cohérentes sur votre infrastructure.

Vous utiliserez plusieurs modules clés : ansible.builtin.yum_repository pour la gestion des dépôts, ansible.builtin.rpm_key pour la gestion des clés GPG, ansible.builtin.package_facts pour la collecte d'informations sur les paquets, et ansible.builtin.dnf pour l'installation des paquets.

  1. Tout d'abord, configurez l'environnement du projet et installez Ansible.

    Installez le paquet ansible-core et naviguez vers le répertoire du projet.

    sudo dnf install -y ansible-core
    cd ~/project
    mkdir system-software
    cd system-software
  2. Créez un fichier d'inventaire Ansible pour définir nos hôtes gérés. Pour ce laboratoire, nous allons gérer la machine locale.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    
    [all:children]
    webservers
    EOF
  3. Créez le playbook principal repo_playbook.yml qui gérera la configuration du dépôt et l'installation des paquets. Ce playbook démontre un flux de travail complet de gestion logicielle.

    nano repo_playbook.yml

    Ajoutez le contenu suivant pour créer un playbook complet de gestion logicielle :

    ---
    - name: Repository Configuration and Software Management
      hosts: all
      become: true
      vars:
        custom_pkg: httpd
      tasks:
        - name: Gather Package Facts
          ansible.builtin.package_facts:
            manager: auto
    
        - name: Show Package Facts for the custom package (initial check)
          ansible.builtin.debug:
            var: ansible_facts['packages'][custom_pkg]
          when: custom_pkg in ansible_facts['packages']
    
        - name: Ensure EPEL repository is configured
          ansible.builtin.yum_repository:
            name: epel
            description: Extra Packages for Enterprise Linux 9
            file: epel
            baseurl: https://download.fedoraproject.org/pub/epel/9/Everything/x86_64/
            gpgcheck: yes
            gpgkey: https://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9
            enabled: yes
            state: present
    
        - name: Import EPEL GPG key
          ansible.builtin.rpm_key:
            state: present
            key: https://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9
    
        - name: Install the custom package
          ansible.builtin.dnf:
            name: "{{ custom_pkg }}"
            state: present
    
        - name: Gather Package Facts (after installation)
          ansible.builtin.package_facts:
            manager: auto
    
        - name: Show Package Facts for the custom package (post-installation)
          ansible.builtin.debug:
            var: ansible_facts['packages'][custom_pkg]
          when: custom_pkg in ansible_facts['packages']
    
        - name: Display installed package version
          ansible.builtin.debug:
            msg: "{{ custom_pkg }} version {{ ansible_facts['packages'][custom_pkg][0]['version'] }} is installed"
          when: custom_pkg in ansible_facts['packages']

    Ce playbook démontre plusieurs concepts importants :

    • Collecte de faits sur les paquets : Montre comment collecter des informations sur les paquets installés.
    • Gestion des dépôts : Configure le dépôt EPEL avec une validation GPG appropriée.
    • Gestion des clés GPG : Importe la clé GPG du dépôt pour la sécurité.
    • Installation des paquets : Installe le paquet spécifié à l'aide du module dnf.
    • Vérification : Confirme l'installation du paquet avec des faits mis à jour.
  4. Exécutez le playbook pour observer le flux de travail complet de gestion logicielle en action.

    ansible-playbook -i inventory.ini repo_playbook.yml

    Vous devriez voir une sortie indiquant :

    • La vérification initiale du paquet (probablement ignorée car httpd n'est pas installé).
    • La configuration du dépôt.
    • L'importation de la clé GPG.
    • L'installation du paquet.
    • La vérification finale montrant le paquet installé.
  5. Vérifiez la configuration du dépôt en examinant le fichier de dépôt créé.

    cat /etc/yum.repos.d/epel.repo

    Vous devriez voir la configuration du dépôt EPEL avec les paramètres baseurl, gpgcheck et gpgkey.

  6. Testez l'idempotence de la gestion des paquets en exécutant à nouveau le playbook.

    ansible-playbook -i inventory.ini repo_playbook.yml

    Remarquez qu'Ansible indique "ok" pour les tâches qui n'ont pas besoin de modifications, démontrant ainsi l'idempotence.

Vous avez automatisé avec succès la gestion des paquets logiciels, y compris la configuration des dépôts, la gestion des clés GPG et la vérification de l'installation des paquets à l'aide d'Ansible.

Automatiser la gestion des utilisateurs et la configuration SSH

Dans cette étape, vous apprendrez à automatiser la gestion des comptes utilisateurs, la configuration SSH et les privilèges sudo à l'aide d'Ansible. Ceci est crucial pour maintenir des politiques cohérentes d'accès utilisateur et de sécurité sur votre infrastructure.

Vous utiliserez des modules tels que ansible.builtin.user pour la gestion des utilisateurs, ansible.builtin.group pour la création de groupes, ansible.posix.authorized_key pour la gestion des clés SSH, et ansible.builtin.lineinfile pour la modification des fichiers de configuration.

  1. Naviguez vers un nouveau répertoire de projet pour les tâches de gestion des utilisateurs.

    cd ~/project
    mkdir system-users
    cd system-users

    Installez la collection ansible.posix.

    ansible-galaxy collection install ansible.posix
  2. Créez le fichier d'inventaire pour cet exercice.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Créez un fichier de variables pour définir les utilisateurs et les groupes que nous voulons gérer.

    mkdir vars
    nano vars/users_vars.yml

    Ajoutez le contenu suivant pour définir les comptes utilisateurs et leurs appartenances aux groupes :

    ---
    users:
      - username: webuser1
        groups: webadmin
      - username: webuser2
        groups: webadmin
      - username: devuser1
        groups: webadmin
  4. Générez des paires de clés SSH pour nos utilisateurs. Dans un environnement réel, les utilisateurs fourniraient leurs clés publiques.

    mkdir files
    
    ## Generate SSH keys for each user
    ssh-keygen -t rsa -b 2048 -f files/webuser1.key -N "" -C "webuser1@example.com"
    ssh-keygen -t rsa -b 2048 -f files/webuser2.key -N "" -C "webuser2@example.com"
    ssh-keygen -t rsa -b 2048 -f files/devuser1.key -N "" -C "devuser1@example.com"
  5. Créez le playbook principal de gestion des utilisateurs users.yml. Ce playbook créera des groupes, des utilisateurs, distribuera des clés SSH et configurera l'accès sudo.

    nano users.yml

    Ajoutez le playbook complet de gestion des utilisateurs suivant :

    ---
    - name: Create and manage user accounts
      hosts: webservers
      become: true
      vars_files:
        - vars/users_vars.yml
      tasks:
        - name: Create webadmin group
          ansible.builtin.group:
            name: webadmin
            state: present
    
        - name: Create user accounts
          ansible.builtin.user:
            name: "{{ item['username'] }}"
            groups: "{{ item['groups'] }}"
            shell: /bin/bash
            create_home: yes
            state: present
          loop: "{{ users }}"
    
        - name: Set up SSH authorized keys
          ansible.posix.authorized_key:
            user: "{{ item['username'] }}"
            key: "{{ lookup('file', 'files/' + item['username'] + '.key.pub') }}"
            state: present
          loop: "{{ users }}"
    
        - name: Configure sudo access for webadmin group
          ansible.builtin.lineinfile:
            path: /etc/sudoers.d/webadmin
            state: present
            create: yes
            mode: "0440"
            line: "%webadmin ALL=(ALL) NOPASSWD: ALL"
            validate: /usr/sbin/visudo -cf %s
    
        - name: Configure SSH to disable root login
          ansible.builtin.lineinfile:
            dest: /etc/ssh/sshd_config
            regexp: "^PermitRootLogin"
            line: "PermitRootLogin no"
            backup: yes
          notify: restart sshd
    
        - name: Configure SSH to disable password authentication
          ansible.builtin.lineinfile:
            dest: /etc/ssh/sshd_config
            regexp: "^PasswordAuthentication"
            line: "PasswordAuthentication no"
            backup: yes
          notify: restart sshd
    
      handlers:
        - name: restart sshd
          ansible.builtin.service:
            name: sshd
            state: restarted

    Ce playbook démontre plusieurs bonnes pratiques de gestion des utilisateurs :

    • Gestion des groupes : Crée des groupes administratifs.
    • Création d'utilisateurs : Met en place des comptes utilisateurs avec des répertoires personnels appropriés.
    • Gestion des clés SSH : Distribue les clés publiques pour l'authentification par clé.
    • Configuration Sudo : Accorde des privilèges administratifs en toute sécurité.
    • Durcissement SSH : Désactive la connexion root et l'authentification par mot de passe.
    • Gestion des services : Redémarre le service SSH lors des changements de configuration.
  6. Exécutez le playbook de gestion des utilisateurs.

    ansible-playbook -i inventory.ini users.yml

    Le playbook créera les utilisateurs, configurera les clés SSH, l'accès sudo et le durcissement de la configuration SSH.

  7. Vérifiez la création des utilisateurs et l'appartenance aux groupes.

    ## Check if users were created
    getent passwd webuser1 webuser2 devuser1
    
    ## Check group membership
    groups webuser1
    groups webuser2
    groups devuser1
    
    ## Verify webadmin group exists
    getent group webadmin
  8. Testez l'authentification par clé SSH pour l'un des utilisateurs créés.

    ## Test SSH key authentication (this will connect to localhost)
    ssh -i files/webuser1.key webuser1@localhost "whoami"
  9. Vérifiez la configuration sudo en testant l'accès sudo sans mot de passe.

    ## Test sudo access for webuser1
    ssh -i files/webuser1.key webuser1@localhost "sudo whoami"
  10. Vérifiez les modifications de configuration SSH.

    ## Verify SSH configuration
    sudo grep "PermitRootLogin\|PasswordAuthentication" /etc/ssh/sshd_config
    
    ## Check sudo configuration
    sudo cat /etc/sudoers.d/webadmin

Vous avez automatisé avec succès la création de comptes utilisateurs, la distribution de clés SSH et la configuration de sécurité à l'aide d'Ansible, établissant ainsi une base pour une gestion sécurisée des utilisateurs sur votre infrastructure.

Automatiser la gestion des services et la planification des tâches

Dans cette étape, vous apprendrez à gérer les services systemd, à planifier des tâches cron et à configurer les cibles de démarrage du système à l'aide d'Ansible. Ceci est essentiel pour maintenir la disponibilité des services et automatiser les tâches routinières sur votre infrastructure.

Vous utiliserez des modules tels que ansible.builtin.service pour la gestion des services, ansible.builtin.cron pour la planification des tâches, ansible.posix.at pour les tâches ponctuelles, et ansible.builtin.systemd pour la gestion des cibles système.

  1. Naviguez vers un nouveau répertoire de projet pour la gestion des services et des processus.

    cd ~/project
    mkdir system-process
    cd system-process
  2. Créez le fichier d'inventaire pour cet exercice.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Créez un playbook pour gérer le service du serveur HTTP Apache. Ceci démontrera la gestion de base des services.

    nano service_management.yml

    Ajoutez le contenu suivant :

    ---
    - name: Manage Apache HTTP Server Service
      hosts: webservers
      become: true
      tasks:
        - name: Start and enable httpd service
          ansible.builtin.service:
            name: httpd
            state: started
            enabled: yes
    
        - name: Create a simple index.html
          ansible.builtin.copy:
            content: |
              <html>
              <head><title>Ansible Managed Server</title></head>
              <body>
              <h1>Welcome to Ansible Managed Apache Server</h1>
              <p>This server is configured and managed by Ansible.</p>
              <p>Service started at: $(date)</p>
              </body>
              </html>
            dest: /var/www/html/index.html
            owner: apache
            group: apache
            mode: "0644"
    
        - name: Verify httpd service is running
          ansible.builtin.service_facts:
    
        - name: Display httpd service status
          ansible.builtin.debug:
            var: ansible_facts.services['httpd.service']
  4. Créez un playbook pour la planification des tâches cron. Ceci démontre la planification automatisée des tâches.

    nano create_crontab_file.yml

    Ajoutez le contenu suivant :

    ---
    - name: Schedule recurring cron jobs
      hosts: webservers
      become: true
      tasks:
        - name: Create labex user for cron jobs
          ansible.builtin.user:
            name: labex
            state: present
            create_home: yes
    
        - name: Schedule system monitoring cron job
          ansible.builtin.cron:
            name: System monitoring log
            job: "date >> /home/labex/system_monitor.log && df -h >> /home/labex/system_monitor.log"
            minute: "*/5"
            hour: "*"
            user: labex
            cron_file: system-monitoring
            state: present
    
        - name: Schedule daily log rotation
          ansible.builtin.cron:
            name: Daily log cleanup
            job: "find /home/labex -name '*.log' -mtime +7 -delete"
            minute: "0"
            hour: "2"
            weekday: "*"
            user: labex
            cron_file: log-cleanup
            state: present
    
        - name: Schedule weekly system update check
          ansible.builtin.cron:
            name: Weekly update check
            job: "dnf check-update > /home/labex/update_check.log 2>&1"
            minute: "0"
            hour: "3"
            weekday: "0"
            user: labex
            cron_file: update-check
            state: present
  5. Créez un playbook pour la planification de tâches ponctuelles à l'aide de at.

    nano schedule_at_task.yml

    Ajoutez le contenu suivant :

    ---
    - name: Schedule one-time tasks with at
      hosts: webservers
      become: true
      become_user: labex
      tasks:
        - name: Schedule immediate system info collection
          ansible.posix.at:
            command: "uname -a > ~/system_info_$(date +%Y%m%d_%H%M%S).txt"
            count: 2
            units: minutes
            unique: yes
            state: present
    
        - name: Schedule delayed service status check
          ansible.posix.at:
            command: "systemctl status httpd > ~/httpd_status_$(date +%Y%m%d_%H%M%S).txt"
            count: 5
            units: minutes
            unique: yes
            state: present
  6. Créez un playbook pour gérer les cibles de démarrage du système.

    nano boot_target_management.yml

    Ajoutez le contenu suivant :

    ---
    - name: Manage system boot targets
      hosts: webservers
      become: true
      tasks:
        - name: Check current default target
          ansible.builtin.command:
            cmd: systemctl get-default
          register: current_target
          changed_when: false
    
        - name: Display current boot target
          ansible.builtin.debug:
            msg: "Current default boot target: {{ current_target.stdout }}"
    
        - name: Set default boot target to multi-user
          ansible.builtin.systemd:
            name: multi-user.target
            enabled: yes
          when: current_target.stdout != "multi-user.target"
    
        - name: Verify the boot target change
          ansible.builtin.command:
            cmd: systemctl get-default
          register: new_target
          changed_when: false
    
        - name: Display new boot target
          ansible.builtin.debug:
            msg: "New default boot target: {{ new_target.stdout }}"
  7. Exécutez le playbook de gestion des services.

    ansible-playbook -i inventory.ini service_management.yml

    Ceci démarrera le service httpd et créera une page d'accueil.

  8. Exécutez le playbook de planification des tâches cron.

    ansible-playbook -i inventory.ini create_crontab_file.yml

    Ceci créera plusieurs tâches planifiées pour la surveillance et la maintenance du système.

  9. Exécutez le playbook de planification des tâches ponctuelles.

    ansible-playbook -i inventory.ini schedule_at_task.yml

    Ceci planifiera des tâches immédiates à l'aide de la commande at.

  10. Exécutez le playbook de gestion des cibles de démarrage.

    ansible-playbook -i inventory.ini boot_target_management.yml

    Ceci vérifiera et potentiellement modifiera la cible de démarrage par défaut du système.

  11. Vérifiez les tâches planifiées et les services.

    ## Check cron jobs
    sudo cat /etc/cron.d/system-monitoring
    sudo cat /etc/cron.d/log-cleanup
    sudo cat /etc/cron.d/update-check
    
    ## Check at jobs
    sudo atq
    
    ## Check httpd service status
    sudo systemctl status httpd
    
    ## Test the web server
    curl localhost
    
    ## Check system monitoring log (wait a few minutes for cron to run)
    sudo cat /home/labex/system_monitor.log
  12. Créez un playbook de nettoyage pour supprimer les tâches planifiées si nécessaire.

    nano remove_scheduled_tasks.yml

    Ajoutez le contenu suivant :

    ---
    - name: Remove scheduled tasks
      hosts: webservers
      become: true
      tasks:
        - name: Remove system monitoring cron job
          ansible.builtin.cron:
            name: System monitoring log
            user: labex
            cron_file: system-monitoring
            state: absent
    
        - name: Remove log cleanup cron job
          ansible.builtin.cron:
            name: Daily log cleanup
            user: labex
            cron_file: log-cleanup
            state: absent
    
        - name: Remove update check cron job
          ansible.builtin.cron:
            name: Weekly update check
            user: labex
            cron_file: update-check
            state: absent

Vous avez automatisé avec succès la gestion des services, la planification des tâches et la configuration du système à l'aide d'Ansible, fournissant ainsi la base pour maintenir et surveiller automatiquement votre infrastructure.

Automatiser la gestion du stockage avec LVM et les systèmes de fichiers

Dans cette étape, vous apprendrez à automatiser la gestion du stockage à l'aide d'Ansible pour créer des volumes physiques LVM, des groupes de volumes, des volumes logiques et des systèmes de fichiers. Ceci est crucial pour gérer les ressources de stockage sur votre infrastructure de manière cohérente et évolutive.

Vous utiliserez des modules tels que ansible.builtin.lvg pour la gestion des groupes de volumes, ansible.builtin.lvol pour la création de volumes logiques, ansible.builtin.filesystem pour la création de systèmes de fichiers, et ansible.posix.mount pour la gestion des points de montage.

  1. Naviguez vers un nouveau répertoire de projet pour la gestion du stockage.

    cd ~/project
    mkdir system-storage
    cd system-storage
  2. Créez le fichier d'inventaire pour cet exercice.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Créez un périphérique de boucle (loop device) pour simuler un stockage supplémentaire, car nous travaillons dans un environnement virtuel.

    ## Create a 1GB file to use as a virtual disk
    sudo dd if=/dev/zero of=/tmp/virtual_disk bs=1M count=1024
    
    ## Set up loop device
    sudo losetup /dev/loop0 /tmp/virtual_disk
    
    ## Verify the loop device
    lsblk | grep loop0
  4. Créez un playbook complet de gestion du stockage. Ceci démontrera les opérations LVM et la gestion des systèmes de fichiers.

    nano storage.yml

    Ajoutez le contenu suivant :

    ---
    - name: Configure LVM storage and filesystems
      hosts: webservers
      become: true
      vars:
        storage_device: /dev/loop0
        volume_group: apache-vg
        content_lv: content-lv
        logs_lv: logs-lv
        backup_lv: backup-lv
      tasks:
        - name: Install LVM utilities
          ansible.builtin.dnf:
            name: lvm2
            state: present
    
        - name: Create physical volume
          community.general.lvg:
            vg: "{{ volume_group }}"
            pvs: "{{ storage_device }}"
            state: present
    
        - name: Create logical volume for web content
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ content_lv }}"
            size: 256m
            state: present
    
        - name: Create logical volume for logs
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ logs_lv }}"
            size: 256m
            state: present
    
        - name: Create logical volume for backup
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ backup_lv }}"
            size: 256m
            state: present
    
        - name: Create XFS filesystem on content volume
          community.general.filesystem:
            fstype: xfs
            dev: "/dev/{{ volume_group }}/{{ content_lv }}"
            force: no
    
        - name: Create XFS filesystem on logs volume
          community.general.filesystem:
            fstype: xfs
            dev: "/dev/{{ volume_group }}/{{ logs_lv }}"
            force: no
    
        - name: Create ext4 filesystem on backup volume
          community.general.filesystem:
            fstype: ext4
            dev: "/dev/{{ volume_group }}/{{ backup_lv }}"
            force: no
    
        - name: Create mount points
          ansible.builtin.file:
            path: "{{ item }}"
            state: directory
            mode: "0755"
          loop:
            - /var/www
            - /var/log/httpd
            - /backup
    
        - name: Mount web content volume
          ansible.posix.mount:
            path: /var/www
            src: "/dev/{{ volume_group }}/{{ content_lv }}"
            fstype: xfs
            opts: defaults
            state: mounted
    
        - name: Mount logs volume
          ansible.posix.mount:
            path: /var/log/httpd
            src: "/dev/{{ volume_group }}/{{ logs_lv }}"
            fstype: xfs
            opts: defaults
            state: mounted
    
        - name: Mount backup volume
          ansible.posix.mount:
            path: /backup
            src: "/dev/{{ volume_group }}/{{ backup_lv }}"
            fstype: ext4
            opts: defaults
            state: mounted
    
        - name: Set appropriate ownership for web content
          ansible.builtin.file:
            path: /var/www
            owner: apache
            group: apache
            recurse: yes
    
        - name: Set appropriate ownership for httpd logs
          ansible.builtin.file:
            path: /var/log/httpd
            owner: apache
            group: apache
            recurse: yes
    
        - name: Create html directory for web content
          ansible.builtin.file:
            path: /var/www/html
            state: directory
            owner: apache
            group: apache
            mode: "0755"
    
        - name: Create sample web content
          ansible.builtin.copy:
            content: |
              <html>
              <head><title>Storage Management Demo</title></head>
              <body>
              <h1>LVM Storage Configuration</h1>
              <p>This content is served from an LVM logical volume managed by Ansible.</p>
              <p>Volume Group: {{ volume_group }}</p>
              <p>Logical Volume: {{ content_lv }}</p>
              <p>Filesystem: XFS</p>
              </body>
              </html>
            dest: /var/www/html/storage.html
            owner: apache
            group: apache
            mode: "0644"
  5. Installez la collection Ansible requise pour la gestion LVM.

    ansible-galaxy collection install community.general
  6. Exécutez le playbook de gestion du stockage.

    ansible-playbook -i inventory.ini storage.yml

    Ceci créera la structure LVM, les systèmes de fichiers et les points de montage.

  7. Créez un playbook pour collecter et afficher les informations de stockage.

    nano get-storage.yml

    Ajoutez le contenu suivant :

    ---
    - name: Gather storage information
      hosts: webservers
      become: true
      tasks:
        - name: Gather disk facts
          ansible.builtin.setup:
            gather_subset:
              - hardware
    
        - name: Display volume group information
          ansible.builtin.command:
            cmd: vgdisplay apache-vg
          register: vg_info
          changed_when: false
    
        - name: Display logical volume information
          ansible.builtin.command:
            cmd: lvdisplay apache-vg
          register: lv_info
          changed_when: false
    
        - name: Display filesystem information
          ansible.builtin.command:
            cmd: df -h /var/www /var/log/httpd /backup
          register: fs_info
          changed_when: false
    
        - name: Display mount information
          ansible.builtin.command:
            cmd: cat /proc/mounts
          register: mount_info
          changed_when: false
    
        - name: Show volume group details
          ansible.builtin.debug:
            var: vg_info.stdout_lines
    
        - name: Show logical volume details
          ansible.builtin.debug:
            var: lv_info.stdout_lines
    
        - name: Show filesystem usage
          ansible.builtin.debug:
            var: fs_info.stdout_lines
    
        - name: Show fstab entries
          ansible.builtin.command:
            cmd: grep apache-vg /etc/fstab
          register: fstab_entries
          changed_when: false
          failed_when: false
    
        - name: Display fstab entries
          ansible.builtin.debug:
            var: fstab_entries.stdout_lines
  8. Exécutez le playbook de collecte d'informations de stockage.

    ansible-playbook -i inventory.ini get-storage.yml

    Ceci affichera des informations détaillées sur la structure de stockage créée.

  9. Vérifiez la configuration du stockage manuellement.

    ## Check LVM structure
    sudo vgs apache-vg
    sudo lvs apache-vg
    sudo pvs /dev/loop0
    
    ## Check filesystems
    df -h /var/www /var/log/httpd /backup
    
    ## Check mount points
    mount | grep apache-vg
    
    ## Check fstab entries
    grep apache-vg /etc/fstab
    
    ## Test the web content
    cat /var/www/html/storage.html
  10. Créez un playbook d'extension de stockage pour démontrer les opérations de mise à l'échelle.

    nano expand_storage.yml

    Ajoutez le contenu suivant :

    ---
    - name: Expand storage volumes
      hosts: webservers
      become: true
      vars:
        volume_group: apache-vg
        content_lv: content-lv
      tasks:
        - name: Extend content logical volume
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ content_lv }}"
            size: 400m
            state: present
    
        - name: Extend XFS filesystem
          community.general.filesystem:
            fstype: xfs
            dev: "/dev/{{ volume_group }}/{{ content_lv }}"
            resizefs: yes
    
        - name: Display updated filesystem size
          ansible.builtin.command:
            cmd: df -h /var/www
          register: new_size
          changed_when: false
    
        - name: Show new filesystem size
          ansible.builtin.debug:
            var: new_size.stdout_lines
  11. Testez l'extension du stockage.

    ## Check current size before expansion
    df -h /var/www
    
    ## Run the expansion playbook
    ansible-playbook -i inventory.ini expand_storage.yml
    
    ## Verify the expansion
    df -h /var/www
    sudo lvs apache-vg/content-lv

Vous avez automatisé avec succès la gestion du stockage LVM, y compris la création de volumes physiques, la gestion des volumes logiques, la création de systèmes de fichiers et la configuration des points de montage à l'aide d'Ansible.

Automatiser la configuration réseau et la collecte d'informations

Dans cette dernière étape, vous apprendrez à automatiser la configuration des interfaces réseau et à collecter des informations système complètes à l'aide d'Ansible. Cela complète le spectre complet de l'automatisation de l'administration système, du logiciel au stockage en passant par le réseau.

Vous utiliserez des modules tels que ansible.builtin.template pour les fichiers de configuration réseau, la collecte des faits réseau et la création de rapports système complets.

  1. Naviguez vers un nouveau répertoire de projet pour la gestion du réseau.

    cd ~/project
    mkdir system-network
    cd system-network
  2. Créez le fichier d'inventaire pour cet exercice.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Créez un playbook complet de collecte d'informations réseau et système.

    nano network_info.yml

    Ajoutez le contenu suivant :

    ---
    - name: Gather comprehensive system information
      hosts: webservers
      become: true
      tasks:
        - name: Gather all system facts
          ansible.builtin.setup:
    
        - name: Create system report directory
          ansible.builtin.file:
            path: /tmp/system_reports
            state: directory
            mode: "0755"
    
        - name: Generate system information report
          ansible.builtin.template:
            src: system_report.j2
            dest: /tmp/system_reports/system_info_{{ ansible_facts['hostname'] }}.html
            mode: "0644"
    
        - name: Generate network configuration report
          ansible.builtin.template:
            src: network_report.j2
            dest: /tmp/system_reports/network_info_{{ ansible_facts['hostname'] }}.html
            mode: "0644"
    
        - name: Collect network interface information
          ansible.builtin.command:
            cmd: ip addr show
          register: ip_info
          changed_when: false
    
        - name: Collect routing information
          ansible.builtin.command:
            cmd: ip route show
          register: route_info
          changed_when: false
    
        - name: Collect DNS configuration
          ansible.builtin.command:
            cmd: cat /etc/resolv.conf
          register: dns_info
          changed_when: false
    
        - name: Display network summary
          ansible.builtin.debug:
            msg: |
              System: {{ ansible_facts['hostname'] }}
              OS: {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}
              Kernel: {{ ansible_facts['kernel'] }}
              Default IPv4: {{ ansible_facts['default_ipv4']['address'] | default('N/A') }}
              Default Interface: {{ ansible_facts['default_ipv4']['interface'] | default('N/A') }}
              Total Memory: {{ ansible_facts['memtotal_mb'] }}MB
              CPU Cores: {{ ansible_facts['processor_vcpus'] }}
  4. Créez les répertoires et fichiers de modèles pour les rapports.

    mkdir templates
    nano templates/system_report.j2

    Ajoutez le contenu suivant pour le modèle de rapport système :

    <!doctype html>
    <html>
      <head>
        <title>System Report - {{ ansible_facts['hostname'] }}</title>
        <style>
          body {
            font-family: Arial, sans-serif;
            margin: 20px;
          }
          .section {
            margin-bottom: 20px;
            padding: 10px;
            border: 1px solid #ccc;
          }
          .header {
            background-color: #f5f5f5;
            padding: 10px;
          }
          table {
            border-collapse: collapse;
            width: 100%;
          }
          th,
          td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
          }
          th {
            background-color: #f2f2f2;
          }
        </style>
      </head>
      <body>
        <div class="header">
          <h1>System Report for {{ ansible_facts['hostname'] }}</h1>
          <p>
            Generated on: {{ ansible_date_time.date }} {{ ansible_date_time.time
            }}
          </p>
        </div>
    
        <div class="section">
          <h2>System Information</h2>
          <table>
            <tr>
              <th>Property</th>
              <th>Value</th>
            </tr>
            <tr>
              <td>Hostname</td>
              <td>{{ ansible_facts['hostname'] }}</td>
            </tr>
            <tr>
              <td>FQDN</td>
              <td>{{ ansible_facts['fqdn'] }}</td>
            </tr>
            <tr>
              <td>Operating System</td>
              <td>
                {{ ansible_facts['distribution'] }} {{
                ansible_facts['distribution_version'] }}
              </td>
            </tr>
            <tr>
              <td>Kernel</td>
              <td>{{ ansible_facts['kernel'] }}</td>
            </tr>
            <tr>
              <td>Architecture</td>
              <td>{{ ansible_facts['architecture'] }}</td>
            </tr>
            <tr>
              <td>CPU Cores</td>
              <td>{{ ansible_facts['processor_vcpus'] }}</td>
            </tr>
            <tr>
              <td>Total Memory</td>
              <td>{{ ansible_facts['memtotal_mb'] }}MB</td>
            </tr>
            <tr>
              <td>Uptime</td>
              <td>{{ ansible_facts['uptime_seconds'] }} seconds</td>
            </tr>
          </table>
        </div>
    
        <div class="section">
          <h2>Storage Information</h2>
          <table>
            <tr>
              <th>Mount Point</th>
              <th>Filesystem</th>
              <th>Size</th>
              <th>Used</th>
              <th>Available</th>
            </tr>
            {% for mount in ansible_facts['mounts'] %}
            <tr>
              <td>{{ mount.mount }}</td>
              <td>{{ mount.fstype }}</td>
              <td>
                {{ (mount.size_total / 1024 / 1024 / 1024) | round(2) }}GB
              </td>
              <td>
                {{ ((mount.size_total - mount.size_available) / 1024 / 1024 /
                1024) | round(2) }}GB
              </td>
              <td>
                {{ (mount.size_available / 1024 / 1024 / 1024) | round(2) }}GB
              </td>
            </tr>
            {% endfor %}
          </table>
        </div>
    
        <div class="section">
          <h2>Services Status</h2>
          <table>
            <tr>
              <th>Service</th>
              <th>Status</th>
            </tr>
            <tr>
              <td>httpd</td>
              <td>
                {{ ansible_facts.services['httpd.service']['state'] |
                default('not installed') }}
              </td>
            </tr>
            <tr>
              <td>sshd</td>
              <td>
                {{ ansible_facts.services['sshd.service']['state'] |
                default('unknown') }}
              </td>
            </tr>
            <tr>
              <td>NetworkManager</td>
              <td>
                {{ ansible_facts.services['NetworkManager.service']['state'] |
                default('unknown') }}
              </td>
            </tr>
          </table>
        </div>
      </body>
    </html>
  5. Créez le modèle de rapport réseau.

    nano templates/network_report.j2

    Ajoutez le contenu suivant :

    <!doctype html>
    <html>
      <head>
        <title>Network Report - {{ ansible_facts['hostname'] }}</title>
        <style>
          body {
            font-family: Arial, sans-serif;
            margin: 20px;
          }
          .section {
            margin-bottom: 20px;
            padding: 10px;
            border: 1px solid #ccc;
          }
          .header {
            background-color: #f5f5f5;
            padding: 10px;
          }
          table {
            border-collapse: collapse;
            width: 100%;
          }
          th,
          td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
          }
          th {
            background-color: #f2f2f2;
          }
          pre {
            background-color: #f9f9f9;
            padding: 10px;
            overflow-x: auto;
          }
        </style>
      </head>
      <body>
        <div class="header">
          <h1>Network Configuration Report</h1>
          <p>Host: {{ ansible_facts['hostname'] }}</p>
          <p>
            Generated on: {{ ansible_date_time.date }} {{ ansible_date_time.time
            }}
          </p>
        </div>
    
        <div class="section">
          <h2>Network Interfaces</h2>
          <table>
            <tr>
              <th>Interface</th>
              <th>IPv4 Address</th>
              <th>IPv6 Address</th>
              <th>MAC Address</th>
              <th>Status</th>
            </tr>
            {% for interface_name in ansible_facts['interfaces'] %} {% if
            interface_name != 'lo' %} {% set interface_facts =
            ansible_facts[interface_name] %}
            <tr>
              <td>{{ interface_name }}</td>
              <td>
                {{ interface_facts.get('ipv4', {}).get('address', 'N/A') }}
              </td>
              <td>
                {{ interface_facts.get('ipv6', [{}])[0].get('address', 'N/A') if
                interface_facts.get('ipv6') else 'N/A' }}
              </td>
              <td>{{ interface_facts.get('macaddress', 'N/A') }}</td>
              <td>
                {{ interface_facts.get('active', false) | ternary('Active',
                'Inactive') }}
              </td>
            </tr>
            {% endif %} {% endfor %}
          </table>
        </div>
    
        <div class="section">
          <h2>Default Gateway</h2>
          <table>
            <tr>
              <th>Property</th>
              <th>Value</th>
            </tr>
            <tr>
              <td>Default IPv4 Address</td>
              <td>
                {{ ansible_facts['default_ipv4']['address'] | default('N/A') }}
              </td>
            </tr>
            <tr>
              <td>Default Interface</td>
              <td>
                {{ ansible_facts['default_ipv4']['interface'] | default('N/A')
                }}
              </td>
            </tr>
            <tr>
              <td>Default Gateway</td>
              <td>
                {{ ansible_facts['default_ipv4']['gateway'] | default('N/A') }}
              </td>
            </tr>
          </table>
        </div>
    
        <div class="section">
          <h2>DNS Configuration</h2>
          <table>
            <tr>
              <th>DNS Servers</th>
            </tr>
            {% for dns in ansible_facts['dns']['nameservers'] %}
            <tr>
              <td>{{ dns }}</td>
            </tr>
            {% endfor %}
          </table>
        </div>
      </body>
    </html>
  6. Créez un playbook de configuration d'interface réseau.

    nano configure_network.yml

    Ajoutez le contenu suivant :

    ---
    - name: Configure network settings
      hosts: webservers
      become: true
      tasks:
        - name: Install NetworkManager if not present
          ansible.builtin.dnf:
            name: NetworkManager
            state: present
    
        - name: Ensure NetworkManager is running
          ansible.builtin.service:
            name: NetworkManager
            state: started
            enabled: yes
    
        - name: Configure hosts file with system information
          ansible.builtin.lineinfile:
            path: /etc/hosts
            line: "{{ ansible_facts['default_ipv4']['address'] }} {{ ansible_facts['hostname'] }}.lab.example.com {{ ansible_facts['hostname'] }}"
            regexp: ".*{{ ansible_facts['hostname'] }}.*"
            backup: yes
    
        - name: Create network monitoring script
          ansible.builtin.copy:
            content: |
              #!/bin/bash
              ## Network monitoring script generated by Ansible
              echo "=== Network Status Report ==="
              echo "Generated at: $(date)"
              echo
              echo "=== Interface Status ==="
              ip addr show
              echo
              echo "=== Routing Table ==="
              ip route show
              echo
              echo "=== DNS Configuration ==="
              cat /etc/resolv.conf
              echo
              echo "=== Network Connectivity Test ==="
              ping -c 3 8.8.8.8
            dest: /usr/local/bin/network-status.sh
            mode: "0755"
    
        - name: Create network information gathering cron job
          ansible.builtin.cron:
            name: Network status monitoring
            job: "/usr/local/bin/network-status.sh >> /var/log/network-status.log 2>&1"
            minute: "*/15"
            user: root
            cron_file: network-monitoring
            state: present
  7. Exécutez le playbook de collecte d'informations réseau.

    ansible-playbook -i inventory.ini network_info.yml

    Ceci générera des rapports système et réseau complets.

  8. Exécutez le playbook de configuration réseau.

    ansible-playbook -i inventory.ini configure_network.yml

    Ceci configurera les paramètres réseau et la surveillance.

  9. Visualisez les rapports générés.

    ## List generated reports
    ls -la /tmp/system_reports/
    
    ## View the system report (you can also open in a browser)
    cat /tmp/system_reports/system_info_*.html
    
    ## Check the network monitoring script
    cat /usr/local/bin/network-status.sh
    
    ## Test the network monitoring script
    sudo /usr/local/bin/network-status.sh
    
    ## Check the network monitoring cron job
    sudo cat /etc/cron.d/network-monitoring
  10. Créez un playbook complet final qui combine tous les concepts appris.

    nano complete_system_setup.yml

    Ajoutez le contenu suivant :

    ---
    - name: Complete system setup and configuration
      hosts: webservers
      become: true
      vars:
        admin_users:
          - webuser1
          - webuser2
      tasks:
        - name: Ensure all required packages are installed
          ansible.builtin.dnf:
            name:
              - httpd
              - lvm2
              - NetworkManager
              - cronie
            state: present
    
        - name: Ensure all services are running
          ansible.builtin.service:
            name: "{{ item }}"
            state: started
            enabled: yes
          loop:
            - httpd
            - NetworkManager
            - crond
    
        - name: Generate final system status report
          ansible.builtin.template:
            src: system_report.j2
            dest: /tmp/final_system_report.html
            mode: "0644"
    
        - name: Display completion message
          ansible.builtin.debug:
            msg: |
              ============================================
              RHEL System Administration Automation Complete!
              ============================================
    
              Summary of configured components:
              - Software: EPEL repository and packages installed
              - Users: {{ admin_users | length }} administrative users created
              - Services: httpd, NetworkManager, and crond configured
              - Storage: LVM volumes and filesystems configured
              - Network: Interface configuration and monitoring set up
              - Scheduling: Cron jobs and at tasks configured
    
              Reports available at:
              - /tmp/system_reports/
              - /tmp/final_system_report.html
    
              Your RHEL system is now fully automated with Ansible!
  11. Exécutez la configuration complète finale.

    ansible-playbook -i inventory.ini complete_system_setup.yml

Vous avez automatisé avec succès les tâches d'administration système RHEL de manière complète à l'aide d'Ansible, couvrant la gestion des logiciels, l'administration des utilisateurs, la gestion des services, la configuration du stockage et la mise en place du réseau.

  1. Prévisualisez les rapports générés dans un navigateur web.

    Naviguez vers le répertoire des rapports :

    cd /tmp/system_reports

    Démarrez un serveur web temporaire à l'aide de Python :

    python -m http.server 8000

    Pour prévisualiser les rapports dans votre navigateur :

    1. Cliquez sur le bouton + dans la barre de menu supérieure
    2. Sélectionnez Web Service
    3. Entrez le numéro de port 8000
    4. Vous pouvez maintenant afficher les rapports HTML générés en ligne
    Preview the generated reports in a web browser

    Le serveur web affichera une liste de répertoires où vous pourrez cliquer sur les fichiers HTML pour visualiser les rapports système et réseau complets générés par vos playbooks Ansible.

    Note: Appuyez sur Ctrl+C pour arrêter le serveur web une fois que vous avez terminé de visualiser les rapports.

Résumé

Dans ce laboratoire complet, vous avez maîtrisé l'automatisation des tâches d'administration essentielles de Red Hat Enterprise Linux (RHEL) à l'aide d'Ansible. Vous avez commencé par la gestion des paquets logiciels, en apprenant à configurer les dépôts, à gérer les clés GPG et à installer des paquets tout en collectant des informations système via les faits des paquets. Cela a fourni la base pour un déploiement logiciel cohérent sur votre infrastructure.

Vous avez ensuite abordé la gestion des utilisateurs et l'authentification, où vous avez automatisé la création de comptes utilisateurs, configuré l'authentification par clé SSH, mis en place des privilèges sudo et renforcé les configurations SSH. Cela a établi des politiques d'accès utilisateur sécurisées et standardisées, cruciales pour les environnements d'entreprise.

Le laboratoire s'est poursuivi avec la gestion des services et la planification des tâches, où vous avez appris à gérer les services systemd, à créer des tâches cron récurrentes, à planifier des tâches uniques avec at et à configurer les cibles de démarrage du système. Ces compétences sont essentielles pour maintenir la disponibilité des services et automatiser les tâches de maintenance de routine.

La gestion du stockage a été abordée par une automatisation LVM complète, comprenant la création de volumes physiques, la gestion des groupes de volumes, le provisionnement de volumes logiques, la création de systèmes de fichiers et la configuration des points de montage. Vous avez également appris à étendre dynamiquement les volumes de stockage, ce qui est essentiel pour la gestion d'une infrastructure évolutive.

Enfin, vous avez terminé l'automatisation de la configuration réseau et la surveillance complète du système. Vous avez appris à collecter les faits réseau, à configurer les interfaces, à créer des rapports système détaillés à l'aide de modèles Jinja2 et à mettre en place des scripts de surveillance automatisés. Cela a fourni une vue complète de la gestion de l'état du système et de la génération de rapports.

Tout au long de ce laboratoire, vous avez appliqué les principes de l'Infrastructure as Code (IaC), garantissant que toutes les configurations système sont reproductibles, contrôlées par version et déployables de manière cohérente. Vous possédez désormais les compétences nécessaires pour automatiser le cycle de vie complet de l'administration système RHEL, du déploiement initial à la maintenance et à la surveillance continues.