📜 Использование модуля Shell в Ansible |

📜 Использование модуля Shell в Ansible

Мануал

Модуль shell в Ansible служит мостом между вашими плейбуками и интерфейсом командной строки (CLI) управляемых систем.

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

В этой статье мы покажем:

  • Работа модуля shell
  • Примеры использования модуля shell
  • Выполнение действий по результатам работы модуля shell
  • Разница между модулем shell и командным модулем
  • Почему не рекомендуется использовать модуль shell

Что такое модуль Shell?

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

Модуль shell использует плагины подключения Ansible для установления безопасного соединения с целевыми машинами.

После подключения он запускает сеанс оболочки (обычно /bin/sh на Unix-подобных системах) и выполняет команду, которую вы указали в этой оболочке.

Затем модуль перехватывает вывод команды (stdout и stderr) и код возврата, делая эту информацию доступной для дальнейшей обработки в вашем плейбуке.

Параметры модуля оболочки Ansible

Модуль shell имеет множество различных параметров. Наиболее часто используемые из них следующие:

  • cmd (или свободная форма): Основной параметр модуля, здесь вы указываете команду, которую хотите запустить.
  • creates: Помогает обеспечить идемпотентность. Если указанный файл существует, команда не будет выполнена.
  • chdir: Позволяет изменить рабочий каталог перед выполнением команды.
  • executable (исполняемый): Если вам нужен определенный интерпретатор оболочки (например, /bin/bash), используйте этот параметр.
  • removes: Параметр, обратный параметру create. Если указанный файл не существует, команда не будет выполнена.

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

Использование модуля shell: Практический пример

В этом примере мы создадим резервную копию каталога на удаленном хосте и скопируем в него содержимое /opt/myapp, а затем проверим завершение резервного копирования, выведя список содержимого резервного каталога.

Если резервное копирование прошло успешно, будет выведено сообщение, подтверждающее это.

  ---
- name: Create directory backup using shell module
  hosts: all
  become: true
  tasks:
    - name: Create backup directory
      ansible.builtin.shell: |
      mkdir -p /var/backups/myapp
      
    - name: Copy files to backup directory
      ansible.builtin.shell: |
        cp -r /opt/myapp /var/backups/myapp

    - name: Verify backup completion
      ansible.builtin.shell: |
        ls /var/backups/myapp
      register: backup_result

    - name: Display backup status
      debug:
        msg: "Backup completed successfully: {{ backup_result.stdout_lines }}"
      when: backup_result.rc == 0

Выполнение нескольких команд оболочки

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

---
- name: Run multiple commands
  hosts: all
  become: true
  tasks:
    - name: Execute multiple commands using shell module
      ansible.builtin.shell: |
        echo "Starting setup..."
        mkdir -p /opt/myapp
        touch /opt/myapp/config.yaml
        echo "Setup complete."

Использование Changed_when и Failed_when в модуле Shell

Модуль Shell не возвращает статус changed.

Чтобы определить, когда команда не выполнилась или скрипт что-то изменил в системе, можно использовать инструкции changed_when и failed_when.

Инструкция changed_when позволяет определить, когда задача действительно вносит изменения в цель.

- name: Install dependencies via Composer.
  ansible.builtin.shell: "/usr/local/bin/composer global require phpunit/phpunit --prefer-dist"
  register: composer
  changed_when: "'Nothing to install or update' not in composer.stdout"

Если модули php уже присутствуют на целевой машине, команда composer ничего не делает и просто возвращает сообщение.

Бывают случаи, когда некоторые ошибки допустимы.

Именно в таких случаях мы будем использовать инструкцию failed_when.

- name:
  ansible.builtin.shell: "ls | grep wp-config.php"
  register: thecommand
  failed_when: thecommand.rc not in [0, 1]

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

- name: Making sure the /tmp has more than 2gb
  ansible.builtin.shell: "df -h /tmp|grep -v Filesystem|awk '{print $4}'|cut -d G -f1"
  register: tmpspace
  failed_when: "tmpspace.stdout|float < 2"

Модуль shell или command

В Ansible есть модуль command, который служит для той же цели – выполнения команд на объектах.

Даже если цель этих двух модулей идентична, есть и различия:

  • Модуль shell Ansible выполняет команды непосредственно через оболочку целевых хостов. По умолчанию модуль shell использует sh  для выполнения команд (можно определить другие оболочки с помощью опции executable). С помощью команды module команды не выполняются через оболочку.
  • Модуль command не поддерживает переменные окружения, пайпы и такие операторы, как <, >, &, ;…

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

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

Почему не рекомендуется использовать модуль shell

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

Существует несколько причин, по которым не рекомендуется использовать модуль shell:

  • Идемпотентность: Обеспечить идемпотентность (запуск одного и того же плейбука несколько раз без побочных эффектов) при использовании shell-скриптов довольно сложно.
  • Удобство чтения и обслуживания: скрипты  оболочки может быть сложнее читать, понимать и поддерживать по сравнению с использованием специальных модулей Ansible, и они не возвращают информацию о том, что изменилось или произошло.
  • Труднее отлаживать: Отладка задачи проще и занимает меньше времени, чем длинная цепочка команд оболочки.

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

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

Заключение

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

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

см. также:

 

Пожалуйста, не спамьте и никого не оскорбляйте. Это поле для комментариев, а не спамбокс. Рекламные ссылки не индексируются!
Добавить комментарий