Автоматизация задач администрирования RHEL с помощью Ansible

AnsibleBeginner
Практиковаться сейчас

Введение

В этой комплексной лабораторной работе вы освоите автоматизацию критически важных задач администрирования Linux с помощью Ansible. Опираясь на ваши знания в области управления файлами, вы теперь изучите, как управлять полным жизненным циклом системного администрирования, от установки программного обеспечения до управления пользователями, настройки служб, подготовки хранилищ и сетевой конфигурации.

Вы начнете с автоматизации управления пакетами программного обеспечения и настройки репозиториев с использованием таких модулей, как ansible.builtin.dnf, ansible.builtin.yum_repository и ansible.builtin.rpm_key. Далее вы будете создавать и управлять учетными записями пользователей, настраивать доступ по SSH и устанавливать привилегии sudo. Лабораторная работа переходит к управлению службами, запланированным задачам с помощью cron и systemd, прежде чем перейти к управлению хранилищами с использованием LVM и операциям с файловой системой. Наконец, вы настроите сетевые интерфейсы и соберете системную информацию.

Эта лабораторная работа подчеркивает реальные сценарии, часто встречающиеся в корпоративных средах Linux, подготавливая вас к эффективному внедрению практик Infrastructure as Code.

Настройка репозитория и управление пакетами программного обеспечения

На этом этапе вы научитесь автоматизировать управление пакетами программного обеспечения в системах RHEL с помощью Ansible. Вы настроите репозиторий Yum, будете управлять GPG-ключами RPM и собирать информацию о пакетах на управляемых хостах. Это необходимо для поддержания единообразных установок программного обеспечения в вашей инфраструктуре.

Вы будете использовать несколько ключевых модулей: ansible.builtin.yum_repository для управления репозиториями, ansible.builtin.rpm_key для работы с GPG-ключами, ansible.builtin.package_facts для сбора информации о пакетах и ansible.builtin.dnf для установки пакетов.

  1. Сначала настройте среду проекта и установите Ansible.

    Установите пакет ansible-core и перейдите в каталог проекта.

    sudo dnf install -y ansible-core
    cd ~/project
    mkdir system-software
    cd system-software
  2. Создайте файл инвентаря Ansible для определения наших управляемых хостов. Для этой лабораторной работы мы будем управлять локальной машиной.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    
    [all:children]
    webservers
    EOF
  3. Создайте основной плейбук repo_playbook.yml, который будет управлять конфигурацией репозитория и установкой пакетов. Этот плейбук демонстрирует полный рабочий процесс управления программным обеспечением.

    nano repo_playbook.yml

    Добавьте следующее содержимое, чтобы создать комплексный плейбук управления программным обеспечением:

    ---
    - 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']

    Примечание: Конфигурационный файл в этой лабораторной работе довольно длинный, поэтому мы не будем предоставлять подробные объяснения, чтобы документация оставалась краткой. Если вам требуется пояснение какой-либо части, нажмите кнопку "Explain Code" в левом нижнем углу блока кода для получения подробных объяснений от Labby.

    Этот плейбук демонстрирует несколько важных концепций:

    • Сбор фактов о пакетах: Показывает, как собирать информацию об установленных пакетах.
    • Управление репозиториями: Настраивает репозиторий EPEL с надлежащей проверкой GPG.
    • Управление GPG-ключами: Импортирует GPG-ключ репозитория для обеспечения безопасности.
    • Установка пакетов: Устанавливает указанный пакет с помощью модуля dnf.
    • Проверка: Подтверждает установку пакета с обновленными фактами.
  4. Выполните плейбук, чтобы увидеть полный рабочий процесс управления программным обеспечением в действии.

    ansible-playbook -i inventory.ini repo_playbook.yml

    Вы должны увидеть вывод, показывающий:

    • Первоначальная проверка пакета (вероятно, пропущена, так как httpd не установлен)
    • Конфигурация репозитория
    • Импорт GPG-ключа
    • Установка пакета
    • Финальная проверка с отображением установленного пакета
  5. Проверьте конфигурацию репозитория, просмотрев созданный файл репозитория.

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

    Вы должны увидеть конфигурацию репозитория EPEL с настройками baseurl, gpgcheck и gpgkey.

  6. Протестируйте идемпотентность управления пакетами, повторно запустив плейбук.

    ansible-playbook -i inventory.ini repo_playbook.yml

    Обратите внимание, что Ansible сообщает "ok" для задач, которые не требуют изменений, демонстрируя идемпотентность.

Вы успешно автоматизировали управление пакетами программного обеспечения, включая настройку репозитория, управление GPG-ключами и проверку установки пакетов с помощью Ansible.

Автоматизация управления пользователями и настройки SSH

На этом этапе вы научитесь автоматизировать управление учетными записями пользователей, настройку SSH и привилегии sudo с помощью Ansible. Это крайне важно для поддержания единообразного доступа пользователей и политик безопасности в вашей инфраструктуре.

Вы будете использовать такие модули, как ansible.builtin.user для управления пользователями, ansible.builtin.group для создания групп, ansible.posix.authorized_key для управления ключами SSH и ansible.builtin.lineinfile для модификации конфигурационных файлов.

  1. Перейдите в новый каталог проекта для задач управления пользователями.

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

    Установите коллекцию ansible.posix.

    ansible-galaxy collection install ansible.posix
  2. Создайте файл инвентаря для этого упражнения.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Создайте файл переменных для определения пользователей и групп, которыми мы хотим управлять.

    mkdir vars
    nano vars/users_vars.yml

    Добавьте следующее содержимое для определения учетных записей пользователей и их членства в группах:

    ---
    users:
      - username: webuser1
        groups: webadmin
      - username: webuser2
        groups: webadmin
      - username: devuser1
        groups: webadmin
  4. Сгенерируйте пары SSH-ключей для наших пользователей. В реальной среде пользователи предоставляли бы свои публичные ключи.

    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. Создайте основной плейбук управления пользователями users.yml. Этот плейбук будет создавать группы, пользователей, распространять SSH-ключи и настраивать доступ sudo.

    nano users.yml

    Добавьте следующий комплексный плейбук управления пользователями:

    ---
    - 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

    Этот плейбук демонстрирует несколько лучших практик управления пользователями:

    • Управление группами: Создает административные группы.
    • Создание пользователей: Настраивает учетные записи пользователей с правильными домашними каталогами.
    • Управление ключами SSH: Распространяет публичные ключи для аутентификации по ключам.
    • Настройка sudo: Безопасно предоставляет административные привилегии.
    • Укрепление SSH: Отключает вход для root и аутентификацию по паролю.
    • Управление службами: Перезапускает службу SSH при изменении конфигурации.
  6. Выполните плейбук управления пользователями.

    ansible-playbook -i inventory.ini users.yml

    Плейбук создаст пользователей, настроит SSH-ключи, настроит доступ sudo и укрепит конфигурацию SSH.

  7. Проверьте создание пользователей и членство в группах.

    ## 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. Протестируйте аутентификацию по SSH-ключам для одного из созданных пользователей.

    ## Test SSH key authentication (this will connect to localhost)
    ssh -i files/webuser1.key webuser1@localhost "whoami"
  9. Проверьте конфигурацию sudo, протестировав доступ sudo без пароля.

    ## Test sudo access for webuser1
    ssh -i files/webuser1.key webuser1@localhost "sudo whoami"
  10. Проверьте изменения конфигурации SSH.

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

Вы успешно автоматизировали создание учетных записей пользователей, распространение SSH-ключей и настройку безопасности с помощью Ansible, заложив основу для безопасного управления пользователями в вашей инфраструктуре.

Автоматизация управления службами и планирования задач

На этом этапе вы научитесь управлять службами systemd, планировать задания cron и настраивать цели загрузки системы с помощью Ansible. Это необходимо для поддержания доступности служб и автоматизации рутинных задач в вашей инфраструктуре.

Вы будете использовать такие модули, как ansible.builtin.service для управления службами, ansible.builtin.cron для планирования задач, ansible.posix.at для одноразовых задач и ansible.builtin.systemd для управления системными целями.

  1. Перейдите в новый каталог проекта для задач управления службами и процессами.

    cd ~/project
    mkdir system-process
    cd system-process
  2. Создайте файл инвентаря для этого упражнения.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Создайте плейбук для управления службой веб-сервера Apache HTTP. Это продемонстрирует базовое управление службами.

    nano service_management.yml

    Добавьте следующее содержимое:

    ---
    - 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. Создайте плейбук для планирования заданий cron. Это демонстрирует автоматизированное планирование задач.

    nano create_crontab_file.yml

    Добавьте следующее содержимое:

    ---
    - 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. Создайте плейбук для планирования одноразовых задач с использованием at.

    nano schedule_at_task.yml

    Добавьте следующее содержимое:

    ---
    - 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. Создайте плейбук для управления целями загрузки системы.

    nano boot_target_management.yml

    Добавьте следующее содержимое:

    ---
    - 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. Выполните плейбук управления службами.

    ansible-playbook -i inventory.ini service_management.yml

    Это запустит службу httpd и создаст приветственную страницу.

  8. Выполните плейбук планирования заданий cron.

    ansible-playbook -i inventory.ini create_crontab_file.yml

    Это создаст несколько запланированных задач для мониторинга и обслуживания системы.

  9. Выполните плейбук планирования одноразовых задач.

    ansible-playbook -i inventory.ini schedule_at_task.yml

    Это запланирует немедленные задачи с использованием команды at.

  10. Выполните плейбук управления целями загрузки.

    ansible-playbook -i inventory.ini boot_target_management.yml

    Это проверит и, возможно, изменит целевую загрузку системы по умолчанию.

  11. Проверьте запланированные задачи и службы.

    ## 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. Создайте плейбук очистки для удаления запланированных задач при необходимости.

    nano remove_scheduled_tasks.yml

    Добавьте следующее содержимое:

    ---
    - 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

Вы успешно автоматизировали управление службами, планирование задач и настройку системы с помощью Ansible, предоставив основу для автоматического обслуживания и мониторинга вашей инфраструктуры.

Автоматизация управления хранилищем с помощью LVM и файловых систем

На этом этапе вы научитесь автоматизировать управление хранилищем с помощью Ansible для создания физических томов LVM (physical volumes), групп томов (volume groups), логических томов (logical volumes) и файловых систем. Это крайне важно для управления ресурсами хранения в вашей инфраструктуре последовательным и масштабируемым образом.

Вы будете использовать такие модули, как ansible.builtin.lvg для управления группами томов, ansible.builtin.lvol для создания логических томов, ansible.builtin.filesystem для создания файловых систем и ansible.posix.mount для управления точками монтирования.

  1. Перейдите в новый каталог проекта для управления хранилищем.

    cd ~/project
    mkdir system-storage
    cd system-storage
  2. Создайте файл инвентаря для этого упражнения.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Создайте блочное устройство (loop device) для имитации дополнительного хранилища, поскольку мы работаем в виртуальной среде.

    ## 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. Создайте комплексный плейбук управления хранилищем. Это продемонстрирует операции LVM и управление файловыми системами.

    nano storage.yml

    Добавьте следующее содержимое:

    ---
    - 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. Установите необходимую коллекцию Ansible для управления LVM.

    ansible-galaxy collection install community.general
  6. Выполните плейбук управления хранилищем.

    ansible-playbook -i inventory.ini storage.yml

    Это создаст структуру LVM, файловые системы и точки монтирования.

  7. Создайте плейбук для сбора и отображения информации о хранилище.

    nano get-storage.yml

    Добавьте следующее содержимое:

    ---
    - 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. Выполните плейбук сбора информации о хранилище.

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

    Это отобразит подробную информацию о созданной структуре хранилища.

  9. Проверьте конфигурацию хранилища вручную.

    ## 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. Создайте плейбук расширения хранилища для демонстрации операций масштабирования.

    nano expand_storage.yml

    Добавьте следующее содержимое:

    ---
    - 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. Протестируйте расширение хранилища.

    ## 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

Вы успешно автоматизировали управление хранилищем LVM, включая создание физических томов, управление логическими томами, создание файловых систем и настройку точек монтирования с помощью Ansible.

Автоматизация сетевой конфигурации и сбора информации

На этом заключительном этапе вы научитесь автоматизировать настройку сетевых интерфейсов и собирать исчерпывающую системную информацию с помощью Ansible. Это завершает полный цикл автоматизации системного администрирования, от программного обеспечения до хранения данных и сетевых настроек.

Вы будете использовать такие модули, как ansible.builtin.template для файлов сетевой конфигурации, собирать сетевые факты и создавать подробные системные отчеты.

  1. Перейдите в новый каталог проекта для управления сетью.

    cd ~/project
    mkdir system-network
    cd system-network
  2. Создайте файл инвентаря для этого упражнения.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Создайте комплексный плейбук для сбора сетевой информации и системных данных.

    nano network_info.yml

    Добавьте следующее содержимое:

    ---
    - 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. Создайте каталоги и файлы шаблонов для отчетов.

    mkdir templates
    nano templates/system_report.j2

    Добавьте следующее содержимое для шаблона системного отчета:

    <!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. Создайте шаблон отчета о сети.

    nano templates/network_report.j2

    Добавьте следующее содержимое:

    <!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. Создайте плейбук для настройки сетевого интерфейса.

    nano configure_network.yml

    Добавьте следующее содержимое:

    ---
    - 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. Выполните плейбук сбора сетевой информации.

    ansible-playbook -i inventory.ini network_info.yml

    Это сгенерирует подробные системные и сетевые отчеты.

  8. Выполните плейбук настройки сети.

    ansible-playbook -i inventory.ini configure_network.yml

    Это настроит сетевые параметры и мониторинг.

  9. Просмотрите сгенерированные отчеты.

    ## 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. Создайте финальный комплексный плейбук, объединяющий все изученные концепции.

    nano complete_system_setup.yml

    Добавьте следующее содержимое:

    ---
    - 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. Выполните финальную комплексную настройку.

    ansible-playbook -i inventory.ini complete_system_setup.yml

Вы успешно завершили комплексную автоматизацию задач администрирования системы RHEL с помощью Ansible, охватив управление программным обеспечением, администрирование пользователей, управление службами, настройку хранилища и сетевые настройки.

  1. Предварительный просмотр сгенерированных отчетов в веб-браузере.

    Перейдите в каталог отчетов:

    cd /tmp/system_reports

    Запустите временный веб-сервер с помощью Python:

    python -m http.server 8000

    Чтобы предварительно просмотреть отчеты в браузере:

    1. Нажмите кнопку + в верхней строке меню.
    2. Выберите Web Service.
    3. Введите номер порта 8000.
    4. Теперь вы можете просматривать сгенерированные HTML-отчеты онлайн.
    Preview the generated reports in a web browser

    Веб-сервер отобразит список каталогов, где вы можете нажать на HTML-файлы, чтобы просмотреть исчерпывающие системные и сетевые отчеты, сгенерированные вашими плейбуками Ansible.

    Примечание: Нажмите Ctrl+C, чтобы остановить веб-сервер, когда закончите просмотр отчетов.

Резюме

В этой комплексной лабораторной работе вы освоили автоматизацию основных задач администрирования Red Hat Enterprise Linux (RHEL) с помощью Ansible. Вы начали с управления пакетами программного обеспечения, научились настраивать репозитории, управлять GPG-ключами и устанавливать пакеты, собирая системную информацию через факты пакетов. Это заложило основу для последовательного развертывания программного обеспечения в вашей инфраструктуре.

Затем вы перешли к управлению пользователями и аутентификации, где автоматизировали создание учетных записей пользователей, настроили аутентификацию на основе SSH-ключей, установили привилегии sudo и укрепили конфигурации SSH. Это позволило установить надежные и стандартизированные политики доступа пользователей, что крайне важно для корпоративных сред.

Лабораторная работа продолжилась управлением службами и планированием задач, где вы научились управлять службами systemd, создавать повторяющиеся задания cron, планировать одноразовые задачи с помощью at и настраивать цели загрузки системы. Эти навыки необходимы для поддержания доступности служб и автоматизации рутинных задач обслуживания.

Управление хранилищем было охвачено комплексной автоматизацией LVM, включая создание физических томов, управление группами томов, выделение логических томов, создание файловых систем и настройку точек монтирования. Вы также научились динамически расширять тома хранения, что критически важно для масштабируемого управления инфраструктурой.

Наконец, вы завершили автоматизацию сетевой конфигурации и комплексный мониторинг системы. Вы научились собирать сетевые факты, настраивать интерфейсы, создавать подробные системные отчеты с использованием шаблонов Jinja2 и настраивать автоматизированные скрипты мониторинга. Это дало полное представление об управлении состоянием системы и отчетности.

На протяжении всей этой лабораторной работы вы применяли принципы Infrastructure as Code (IaC), гарантируя, что все системные конфигурации воспроизводимы, контролируются версиями и могут быть последовательно развернуты. Теперь у вас есть навыки для автоматизации полного жизненного цикла администрирования системы RHEL, от первоначального развертывания до текущего обслуживания и мониторинга.