Управление переменными и фактами в RHEL с помощью Ansible

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

Введение

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

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

Определение и использование переменных плейбука для развертывания веб-сервера Apache

На этом этапе вы узнаете, как использовать переменные в плейбуке Ansible. Переменные необходимы для того, чтобы сделать автоматизацию гибкой, пригодной для повторного использования, а также более простой для чтения и поддержки. Вместо того чтобы жестко прописывать значения (например, имена пакетов или пути к файлам) непосредственно в задачах, вы можете определить их как переменные и ссылаться на них по всему плейбуку. Мы создадим простой плейбук, который использует переменные для установки веб-сервера Apache (httpd) и развертывания базовой веб-страницы.

  1. Переход в каталог проекта

    Сначала убедитесь, что вы находитесь в правильном рабочем каталоге. Вся работа в этой лабораторной будет выполняться в каталоге ~/project, который был создан для вас.

    cd ~/project

    Установите пакет ansible-core.

    sudo dnf install -y ansible-core
  2. Создание плейбука Ansible

    Теперь создадим файл плейбука. Назовем его playbook.yml. Вы можете использовать консольный текстовый редактор, например nano, для создания и редактирования файла.

    nano playbook.yml

    Эта команда откроет пустой файл в редакторе nano. Добавьте начальную часть плейбука. В этом разделе определяется имя сценария (play), целевой хост (localhost, так как мы запускаем его на той же машине) и раздел vars, где мы определим наши переменные.

    ---
    - name: Deploy Apache using variables
      hosts: localhost
      become: true
      vars:
        web_pkg: httpd
        web_content: "Hello from Ansible Variables"

    Разбор структуры плейбука:

    • hosts: localhost: Указывает, что плейбук должен выполняться на локальной машине.
    • become: true: Указывает Ansible использовать повышение привилегий (аналог sudo) для задач, что необходимо для установки программного обеспечения.
    • vars: Это словарь, где мы определяем пары «ключ-значение» для переменных. Мы определили web_pkg для имени пакета и web_content для содержимого нашей тестовой веб-страницы.
  3. Добавление задач в плейбук

    Затем, под разделом vars, добавьте tasks (задачи), которые будут использовать эти переменные. Первая задача установит пакет Apache, а вторая создаст файл index.html. Добавьте следующий блок tasks в ваш файл playbook.yml, оставаясь в редакторе nano.

    tasks:
      - name: Install the latest version of Apache
        ansible.builtin.dnf:
          name: "{{ web_pkg }}"
          state: latest
    
      - name: Create a basic index.html file
        ansible.builtin.copy:
          content: "{{ web_content }}"
          dest: /var/www/html/index.html

    Обратите внимание, как мы используем {{ variable_name }} для обращения к ранее определенным переменным. Это шаблонизация Jinja2, которую Ansible использует для переменных. Это делает определения задач универсальными; если бы вы захотели установить Nginx вместо Apache, вам нужно было бы изменить только переменную web_pkg, а не саму задачу.

  4. Проверка и сохранение плейбука

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

    ---
    - name: Deploy Apache using variables
      hosts: localhost
      become: true
      vars:
        web_pkg: httpd
        web_content: "Hello from Ansible Variables"
      tasks:
        - name: Install the latest version of Apache
          ansible.builtin.dnf:
            name: "{{ web_pkg }}"
            state: latest
    
        - name: Create a basic index.html file
          ansible.builtin.copy:
            content: "{{ web_content }}"
            dest: /var/www/html/index.html

    Чтобы сохранить файл в nano, нажмите Ctrl+X, затем Y для подтверждения изменений и, наконец, Enter для записи файла под именем playbook.yml.

  5. Проверка синтаксиса плейбука

    Перед запуском плейбука всегда полезно проверить его синтаксис на наличие ошибок.

    ansible-playbook --syntax-check playbook.yml

    Если синтаксис верен, вы увидите путь к файлу плейбука в выводе, что подтверждает его корректность:

    playbook: playbook.yml

    Если вы видите ошибки, снова откройте файл с помощью nano playbook.yml и исправьте их. Обратите особое внимание на правильные отступы (обычно два пробела).

  6. Запуск плейбука

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

    ansible-playbook playbook.yml

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

    PLAY [Deploy Apache using variables] *******************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Install the latest version of Apache] ************************************
    changed: [localhost]
    
    TASK [Create a basic index.html file] ******************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    Если вы запустите плейбук второй раз, задачи должны сообщить ok вместо changed, так как пакет уже установлен, а файл уже содержит правильное содержимое. Это демонстрирует идемпотентность Ansible.

  7. Ручная проверка конфигурации

    Хотя плейбук завершен, вы можете вручную проверить, что задачи сработали как ожидалось. Сначала проверьте, был ли установлен пакет httpd:

    rpm -q httpd

    Вывод должен показать имя пакета и версию:

    httpd-2.4.57-7.el9.x86_64

    Затем проверьте содержимое файла index.html:

    cat /var/www/html/index.html

    Вывод должен соответствовать значению вашей переменной web_content:

    Hello from Ansible Variables

    Вы успешно использовали переменные в плейбуке Ansible для настройки системы.

Отображение системной информации с помощью фактов Ansible

На этом этапе вы изучите факты Ansible. Факты — это фрагменты информации, которые Ansible собирает о системах, которыми управляет (в данном случае localhost). Эта информация включает такие детали, как операционная система, сетевые интерфейсы, память и многое другое. По умолчанию Ansible собирает факты в начале каждого сценария, делая их доступными в специальной переменной ansible_facts. Использование фактов позволяет создавать динамические плейбуки, которые адаптируются к среде, в которой они работают.

  1. Переход в каталог проекта

    Сначала убедитесь, что вы находитесь в каталоге ~/project, где вы создадите новый плейбук.

    cd ~/project
  2. Создание плейбука для отображения всех фактов

    Начнем с создания плейбука, который просто отображает все факты, которые Ansible может собрать о вашей системе. Это даст вам представление об огромном объеме доступной информации. Используйте nano для создания нового файла с именем display_facts.yml.

    nano display_facts.yml

    Внутри редактора nano добавьте следующее содержимое. Этот плейбук нацелен на localhost и использует модуль ansible.builtin.debug для вывода содержимого переменной ansible_facts.

    ---
    - name: Display all Ansible facts
      hosts: localhost
      tasks:
        - name: Print all available facts
          ansible.builtin.debug:
            var: ansible_facts

    Сохраните файл и выйдите из nano, нажав Ctrl+X, затем Y и Enter.

  3. Запуск плейбука

    Теперь выполните плейбук, чтобы увидеть результат.

    ansible-playbook display_facts.yml

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

    PLAY [Display all Ansible facts] ***********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Print all available facts] ***********************************************
    ok: [localhost] => {
        "ansible_facts": {
            "ansible_all_ipv4_addresses": [
                "172.17.0.2"
            ],
            "ansible_all_ipv6_addresses": [
                "fe80::42:acff:fe11:2"
            ],
            "ansible_apparmor": {
                "status": "disabled"
            },
            "ansible_architecture": "x86_64",
            "ansible_bios_date": "01/01/2011",
            "ansible_bios_version": "1.0",
            "ansible_cmdline": {
                "BOOT_IMAGE": "/boot/vmlinuz-5.14.0-427.16.1.el9_4.x86_64",
                "root": "UUID=...",
                "ro": true
            },
            "ansible_date_time": {
                "date": "2024-05-21",
                "day": "21",
                "epoch": "1716298855",
                ...
            },
            "ansible_distribution": "RedHat",
            "ansible_distribution_major_version": "9",
            "ansible_distribution_version": "9.4",
            ...
        }
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  4. Создание плейбука для отображения конкретных фактов

    Отображение всех фактов полезно для ознакомления, но в большинстве случаев вам нужны только определенные данные. Давайте создадим еще один плейбук, display_specific_facts.yml, чтобы вывести отформатированное сообщение с несколькими ключевыми фактами.

    nano display_specific_facts.yml

    Добавьте следующее содержимое. Этот плейбук использует параметр msg модуля debug для вывода пользовательской строки. Мы обращаемся к отдельным фактам, используя нотацию скобок, например ansible_facts['distribution'].

    ---
    - name: Display specific Ansible facts
      hosts: localhost
      tasks:
        - name: Print a summary of system facts
          ansible.builtin.debug:
            msg: >
              The operating system is {{ ansible_facts['distribution'] }}
              version {{ ansible_facts['distribution_major_version'] }}.
              It has {{ ansible_facts['processor_cores'] }} processor cores and
              {{ ansible_facts['memtotal_mb'] }} MB of total memory.

    Символ > в msg: > — это функция YAML, которая позволяет записывать многострочную строку более аккуратно. Сохраните файл и выйдите из nano.

  5. Запуск плейбука для конкретных фактов

    Теперь запустите этот новый плейбук.

    ansible-playbook display_specific_facts.yml

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

    PLAY [Display specific Ansible facts] ******************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Print a summary of system facts] *****************************************
    ok: [localhost] => {
        "msg": "The operating system is RedHat version 9. It has 2 processor cores and 3925 MB of total memory."
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

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

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

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

Ansible ищет пользовательские факты в каталоге /etc/ansible/facts.d на управляемом хосте. Любой файл в этом каталоге с расширением .fact будет обработан. Эти файлы могут быть простыми текстовыми файлами в стиле INI или файлами JSON.

  1. Создание каталога для пользовательских фактов

    Сначала нужно создать каталог, в котором Ansible будет искать файлы пользовательских фактов. Поскольку это системный каталог, для его создания необходимо использовать sudo.

    sudo mkdir -p /etc/ansible/facts.d

    Флаг -p гарантирует, что команда не вернет ошибку, если каталог уже существует.

  2. Создание файла пользовательских фактов

    Теперь создадим файл пользовательских фактов, чтобы определить приветственное сообщение для нашего веб-сервера. Мы создадим файл в формате INI с именем web_config.fact в каталоге /etc/ansible/facts.d.

    sudo nano /etc/ansible/facts.d/web_config.fact

    Добавьте в файл следующее содержимое. Это определяет секцию [webserver] с ключом welcome_message.

    [webserver]
    welcome_message = Welcome to the server configured by Custom Facts!

    Сохраните файл и выйдите из nano, нажав Ctrl+X, затем Y и Enter.

  3. Создание плейбука для использования пользовательского факта

    Теперь, когда пользовательский факт готов, мы можем создать плейбук, который считывает этот факт и использует его для настройки домашней страницы нашего веб-сервера. В вашем каталоге ~/project создайте новый плейбук с именем configure_web.yml.

    cd ~/project
    nano configure_web.yml

    Добавьте в плейбук следующее содержимое. Этот плейбук обновит файл /var/www/html/index.html сообщением, определенным в нашем пользовательском факте.

    ---
    - name: Configure web server using custom facts
      hosts: localhost
      become: true
      tasks:
        - name: Update index.html with custom message
          ansible.builtin.copy:
            content: "{{ ansible_facts.ansible_local.web_config.webserver.welcome_message }}"
            dest: /var/www/html/index.html

    Разберем переменную {{ ansible_facts.ansible_local.web_config.webserver.welcome_message }}:

    • ansible_facts: Корневой словарь для всех фактов.
    • ansible_local: Ключ, в котором хранятся все пользовательские факты.
    • web_config: Имя нашего файла фактов (web_config.fact) без расширения.
    • webserver: Имя секции [webserver] из нашего INI-файла.
    • welcome_message: Ключ для значения, которое мы хотим использовать.

    Сохраните файл и выйдите из nano.

  4. Запуск плейбука настройки

    Теперь выполните плейбук, чтобы применить конфигурацию.

    ansible-playbook configure_web.yml

    Вывод должен показать, что задача copy изменила (changed) файл index.html.

    PLAY [Configure web server using custom facts] *********************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Update index.html with custom message] ***********************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. Проверка результата

    Наконец, давайте убедимся, что веб-страница была обновлена правильно. Используйте команду cat для просмотра содержимого файла index.html.

    cat /var/www/html/index.html

    Вывод теперь должен отображать сообщение из вашего файла пользовательских фактов:

    Welcome to the server configured by Custom Facts!

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

Создание системного пользователя с использованием зашифрованных переменных с помощью Ansible Vault

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

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

  1. Переход в каталог проекта

    Убедитесь, что вы находитесь в каталоге ~/project для выполнения этой задачи.

    cd ~/project
  2. Создание зашифрованного файла Vault

    Мы будем использовать команду ansible-vault create для создания нового зашифрованного YAML-файла с именем secrets.yml. Эта команда предложит вам создать пароль для хранилища (vault). Этот пароль потребуется для открытия, редактирования или использования файла в дальнейшем.

    Сначала установим редактор nano, чтобы упростить работу:

    export EDITOR=nano

    Теперь создайте файл хранилища:

    ansible-vault create secrets.yml

    При появлении запроса введите пароль для вашего хранилища. Для этой лабораторной работы давайте используем labex в качестве пароля, чтобы упростить задачу. Вам нужно будет ввести его дважды.

    New Vault password:
    Confirm New Vault password:

    После подтверждения пароля команда откроет файл secrets.yml в текстовом редакторе nano.

  3. Добавление секретных переменных в файл Vault

    Внутри редактора nano, который теперь редактирует зашифрованный файл secrets.yml, добавьте следующие переменные. Мы определим имя пользователя и предварительно хешированный пароль для нового пользователя. Использование хешированного пароля гораздо безопаснее, чем хранение пароля в открытом виде.

    username: myappuser
    pwhash: $6$mysalt$QwMzWSEyCAGmz7tzVrAi5o.8k4d05i2QsfGGwmPtlJsWhGjSjCW6yFCH/OEqEsHk7GMSxqYNXu5sshxPmWyxo0
    • username: Имя системного пользователя, которого мы хотим создать.
    • pwhash: Безопасно хешированный пароль. Этот конкретный хеш соответствует паролю AnsibleUserP@ssw0rd и находится в формате, который понимает модуль ansible.builtin.user.

    Сохраните файл и выйдите из nano (Ctrl+X, затем Y, затем Enter). Файл secrets.yml в вашем каталоге ~/project теперь зашифрован. Если вы попытаетесь просмотреть его с помощью cat secrets.yml, вы увидите только зашифрованный текст.

  4. Создание плейбука для использования файла Vault

    Теперь создайте новый плейбук с именем create_user.yml, который будет использовать переменные из вашего зашифрованного файла secrets.yml.

    nano create_user.yml

    Добавьте следующее содержимое. Директива vars_files указывает Ansible загрузить переменные из указанного файла.

    ---
    - name: Create a user from secret variables
      hosts: localhost
      become: true
      vars_files:
        - secrets.yml
      tasks:
        - name: Create the {{ username }} user
          ansible.builtin.user:
            name: "{{ username }}"
            password: "{{ pwhash }}"
            state: present

    Этот плейбук создаст пользователя с именем и хешем пароля, определенными в secrets.yml. Сохраните файл и выйдите из nano.

  5. Запуск плейбука с паролем Vault

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

    ansible-playbook --ask-vault-pass create_user.yml

    Ansible запросит пароль хранилища. Введите labex (пароль, который вы установили на шаге 2).

    Vault password:

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

    PLAY [Create a user from secret variables] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Create the myappuser user] ***********************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  6. Проверка создания пользователя

    Вы можете подтвердить, что myappuser был успешно создан в системе, используя команду id.

    id myappuser

    Если пользователь существует, вы увидите информацию о его идентификаторе пользователя (uid) и идентификаторе группы (gid).

    uid=1002(myappuser) gid=1002(myappuser) groups=1002(myappuser)

    Это подтверждает, что вы успешно использовали Ansible Vault для управления конфиденциальными данными для ваших задач автоматизации.

Запуск плейбука с файлом паролей Vault для применения конфигураций

На этом этапе вы узнаете более автоматизированный способ предоставления пароля хранилища для Ansible. На предыдущем этапе вы использовали --ask-vault-pass для ввода пароля в интерактивном режиме. Хотя это безопасно, это не подходит для автоматизированных сред, таких как CI/CD конвейеры, где нет пользователя, который мог бы ввести пароль.

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

  1. Переход в каталог проекта

    Убедитесь, что вы находитесь в каталоге ~/project, где расположены ваш плейбук и файл хранилища.

    cd ~/project
  2. Создание файла паролей Vault

    Давайте создадим файл для хранения нашего пароля хранилища. Назовем его vault_pass.txt. Мы можем использовать команду echo для создания файла и записи в него пароля (labex) за один шаг.

    echo "labex" > vault_pass.txt

    Вы можете проверить содержимое файла с помощью cat:

    cat vault_pass.txt

    Вывод должен быть:

    labex
  3. Защита файла паролей

    Хранение пароля в текстовом файле рискованно. Вы должны ограничить права доступа к файлу, чтобы защитить его. Команда chmod позволяет изменять права доступа к файлам. Мы установим права 600, что означает, что только владелец файла (в данном случае пользователь labex) имеет права на чтение и запись. Никакие другие пользователи в системе не смогут получить к нему доступ.

    chmod 600 vault_pass.txt

    Вы можете проверить новые права доступа с помощью команды ls -l:

    ls -l vault_pass.txt

    Вывод должен начинаться с -rw-------, подтверждая ограниченные права доступа.

    -rw-------. 1 labex labex 6 May 21 14:30 vault_pass.txt
  4. Изменение плейбука для добавления пользователя в группу

    Давайте изменим наш плейбук create_user.yml для выполнения дополнительного действия. Мы добавим myappuser в группу wheel, которая во многих системах предоставляет административные привилегии (sudo). Это продемонстрирует запуск плейбука, который вносит изменения в существующую конфигурацию.

    Сначала откройте плейбук create_user.yml для редактирования.

    nano create_user.yml

    Измените задачу ansible.builtin.user, чтобы включить параметры groups и append.

    ---
    - name: Create a user from secret variables
      hosts: localhost
      become: true
      vars_files:
        - secrets.yml
      tasks:
        - name: Create the {{ username }} user and add to wheel group
          ansible.builtin.user:
            name: "{{ username }}"
            password: "{{ pwhash }}"
            state: present
            groups: wheel
            append: true
    • groups: wheel: Указывает группу, в которую нужно добавить пользователя.
    • append: true: Гарантирует, что пользователь будет добавлен в эту группу, не удаляясь из других групп, в которых он может состоять.

    Сохраните файл и выйдите из nano.

  5. Запуск плейбука с файлом паролей Vault

    Теперь снова запустите плейбук. На этот раз вместо --ask-vault-pass используйте опцию --vault-password-file (или ее короткий псевдоним --vault-pass-file), чтобы указать путь к вашему файлу паролей.

    ansible-playbook --vault-password-file vault_pass.txt create_user.yml

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

    PLAY [Create a user from secret variables] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Create the myappuser user and add to wheel group] ************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    Статус changed подтверждает, что Ansible изменил пользователя, добавив его в группу wheel.

  6. Проверка членства пользователя в группе

    Наконец, убедитесь, что myappuser теперь является членом группы wheel. Вы можете сделать это с помощью команды groups.

    groups myappuser

    Вывод должен показать как основную группу пользователя (myappuser), так и группу wheel.

    myappuser : myappuser wheel

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

Проверка конфигурации веб-сервера и пользователя

На этом заключительном этапе вы закрепите свои знания, создав специальный плейбук для проверки. До сих пор вы вручную проверяли результаты своих плейбуков с помощью стандартных команд Linux, таких как cat, id и groups. Более мощный и воспроизводимый подход — использовать сам Ansible для аудита и проверки состояния вашей системы.

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

  1. Переход в каталог проекта

    Сначала убедитесь, что вы находитесь в каталоге ~/project.

    cd ~/project
  2. Создание плейбука проверки

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

    nano verify_config.yml
  3. Добавление задач для проверки конфигурации

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

    ---
    - name: Verify system configuration
      hosts: localhost
      become: true
      tasks:
        - name: Check if httpd package is installed
          ansible.builtin.dnf:
            list: httpd
          register: httpd_pkg_info
    
        - name: Assert that httpd is installed
          ansible.builtin.assert:
            that:
              - httpd_pkg_info.results | length > 0
            fail_msg: "Apache (httpd) package is not installed."
            success_msg: "Apache (httpd) package is installed."
    
        - name: Read the content of the index.html file
          ansible.builtin.slurp:
            src: /var/www/html/index.html
          register: index_file
    
        - name: Assert that the web page content is correct
          ansible.builtin.assert:
            that:
              - "'Custom Facts' in (index_file.content | b64decode)"
            fail_msg: "Web page content is incorrect."
            success_msg: "Web page content is correct."
    
        - name: Check if myappuser exists
          ansible.builtin.getent:
            database: passwd
            key: myappuser
          register: user_info
    
        - name: Assert that myappuser exists
          ansible.builtin.assert:
            that:
              - user_info.ansible_facts.getent_passwd['myappuser'] is defined
            fail_msg: "User 'myappuser' does not exist."
            success_msg: "User 'myappuser' exists."
    
        - name: Query the wheel group members
          ansible.builtin.getent:
            database: group
            key: wheel
          register: wheel_group_info
    
        - name: Assert that myappuser is in the wheel group
          ansible.builtin.assert:
            that:
              - "'myappuser' in (wheel_group_info.ansible_facts.getent_group['wheel'][2] | default('') | split(','))"
            fail_msg: "User 'myappuser' is not in the wheel group."
            success_msg: "User 'myappuser' is in the wheel group."

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

    • ansible.builtin.dnf с list: Проверяет наличие пакета и регистрирует результат.
    • ansible.builtin.slurp: «Считывает» все содержимое файла с удаленного хоста. Содержимое кодируется в base64 для безопасной передачи.
    • ansible.builtin.getent: Безопасный способ запроса системных баз данных, таких как passwd и group. Результаты сохраняются в ansible_facts, поэтому доступ к возвращенным данным осуществляется через ключи, такие как user_info.ansible_facts.getent_passwd.
    • ansible.builtin.assert: Это основа нашей проверки. Он проверяет, истинно ли заданное условие. Если нет, он прерывает выполнение сценария. Мы предоставляем пользовательские сообщения об успехе и неудаче.
    • b64decode: Фильтр Jinja2, используемый для декодирования содержимого base64, полученного из модуля slurp.

    Обратите внимание, что мы запрашиваем базы данных passwd и group отдельно. Это позволяет проверке существования пользователя и проверке членства в группе wheel соответствовать фактическим данным, возвращаемым getent.

    Сохраните файл и выйдите из nano (Ctrl+X, Y, Enter).

  4. Запуск плейбука проверки

    Теперь выполните ваш плейбук проверки. Поскольку он не использует никаких зашифрованных файлов, вам не нужно предоставлять пароль.

    ansible-playbook verify_config.yml

    Если все ваши предыдущие шаги были выполнены правильно, плейбук выполнится успешно, и вы увидите пользовательское сообщение об успехе для каждого утверждения.

    PLAY [Verify system configuration] *********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Check if httpd package is installed] *************************************
    ok: [localhost]
    
    TASK [Assert that httpd is installed] ******************************************
    ok: [localhost] => {
        "changed": false,
        "msg": "Apache (httpd) package is installed."
    }
    
    TASK [Read the content of the index.html file] *********************************
    ok: [localhost]
    
    TASK [Assert that the web page content is correct] *****************************
    ok: [localhost] => {
        "changed": false,
        "msg": "Web page content is correct."
    }
    
    TASK [Check if myappuser exists] ***********************************************
    ok: [localhost]
    
    TASK [Assert that myappuser exists] ********************************************
    ok: [localhost] => {
        "changed": false,
        "msg": "User 'myappuser' exists."
    }
    
    TASK [Query the wheel group members] *******************************************
    ok: [localhost]
    
    TASK [Assert that myappuser is in the wheel group] *****************************
    ok: [localhost] => {
        "changed": false,
        "msg": "User 'myappuser' is in the wheel group."
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=9    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    Поздравляем! Вы успешно использовали Ansible для определения переменных, сбора системных фактов, управления секретами с помощью Vault и, наконец, для автоматизированной проверки состояния вашей системы.

Резюме

В этой лабораторной работе вы научились управлять различными типами данных в плейбуках Ansible для настройки системы RHEL. Вы начали с определения и использования стандартных переменных плейбука для гибкой установки и настройки веб-сервера Apache. Затем вы изучили, как использовать встроенные факты Ansible для отображения системной информации, что послужило основой для создания динамических и «осведомленных» о хосте задач автоматизации.

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