Автоматизация управления с помощью Ansible

от автора

Автоматизация управления с помощью Ansible

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

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

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

Сначала нам необходимо будет развернуть сервер управления Ansible. В качестве ОС я буду использовать Ubuntu 22.04. Предварительно сделав апгрейд и апдейт, выполним следующую команду: 

Установка не должна вызвать каких-либо сложностей. После ее завершения мы получим узел управления со всем необходимым ПО для администрирования целевых узлов. Как настоящие DevOps мы будем работать через консоль и для начала нам необходимо внести правки в файл инвентаризации /etc/ansible/hosts. Это файл содержит информацию о тех хостах, которыми будем управлять, параметры конфигурации и переменные.

В качестве примера пропишем в этот файл два сервера .150 и .137. Также пропишем путь к интерпретатору Python.

[servers]  server1 ansible_host=192.168.222.150  server2 ansible_host=192.168.222.137  [all:vars]  ansible_python_interpreter=/usr/bin/python3

С этим значением параметра удаленный сервер использует исполняемый файл Python 3 /usr/bin/python3, который может отсутствовать в некоторых версиях Ubuntu.

Об аутентификации

С настройками по умолчанию Ansible пытается подключиться ко всем нодам по протоколу SSH и с помощью аутентификации по ключам. Однако, не всегда есть возможность аутентифицироваться по ключам, и в качестве альтернативы вы можете указывать пароль при подключении. Но для использовании парольной аутентификации необходимо предварительно установить на сервере управления Ansible утилиту sshpass:

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

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

Если такого файла нет, его можно создать:

Далее необходимо зайти на клиентскую машину, перейти в сессию root и открыть файл  nano ~/.ssh/authorized_keys и поместить в него открытый ключ сервера управления:

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

Используем плейбуки

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

Немного о терминологии. В последнее время есть тенденция к отказу от англоязычных терминов, поэтому в некоторых источниках, особенно связанных с ИБ можно встретить замену иностранного слова “плейбук” российским аналогом – карта реагирования. Однако в данной статье мы будем использовать термин плейбук.

Итак, что из себя представляет плейбук: по сути это набор сценариев, которые выполняются в заданном порядке. Сценарий – это список задач для определенной группы хостов.

Инструментом для создания плейбуков является язык YAML. При написании сценариев большое значение имеет отступы, которые необходимо делать только с помощью пробелов, TAB использовать нельзя. У одинаковых элементов отступы тоже должны быть одинаковые. Вот пример Hello world в Ansible:

---  - hosts: all    tasks:      - name: Print message        debug:          msg: Hello Ansible World

В этом сценарии мы указываем в качестве целей все узлы из нашего hosts файла. Наименование задачи Print message, и вывод сообщения Hello Ansible World.

Сохраним этот плейбук в файл и запустим на выполнение.

Задача успешно выполнена. В случае, если нам необходимо выполнить плейбук только на одном управляемом узле, необходимо указать параметр –limit и имя данного узла, указанное в файле hosts.

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

Перед началом блока определяемых в плейбуке переменных мы указываем vars:, далее указываем сами переменные и их значения. В нашем примере мы определяем переменную txt со значением IP_address. В блоке tasks, в разделе msg переменные указываются в двойных фигурных скобках с отступом с каждой стороны. Сначала мы указываем нашу переменную txt, а затем встроенную переменную ansible_default_ipv4.address. Определять данную переменную не надо, так как она уже определена в самом Ansible.

- hosts: all    vars:      txt: IP_address    tasks:      - name: print facts        debug:          msg: "{{ txt }}: {{ ansible_default_ipv4.address }}"

Сохраним созданный файл и выполним плейбук для всех узлов.

 

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

Для этого мы сначала определим переменные user и file_name

vars:      - user: otus      - file_name: test1   Затем выполним команду ls          command: ls /home/{{ user }}/{{ file_name }}

Далее мы используем ключевое слово register, которое создает новую переменную file_exists и присваивает ей выходные данные, полученные из команды.

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

      register: file_exists

      ignore_errors: yes

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

Далее в случае, если fail_exists имеет значение failed, мы создаем новый файл.

    - name: create file for user        file:          path: /home/{{ user }}/{{ file_name }}          state: touch        when: file_exists is failed

Если файл уже существует, мы просто выводим соответствующее сообщение:

  - name: show message if file exists        debug:          msg: The user file already exists.        when: file_exists is succeeded

Далее приведен полный текст всего плейбука:

---  - hosts: all    vars:      - user: otus      - file_name: test1     tasks:      - name: Check if file already exists        command: ls /home/{{ user }}/{{ file_name }}        register: file_exists        ignore_errors: yes         - name: create file for user        file:          path: /home/{{ user }}/{{ file_name }}          state: touch        when: file_exists is failed         - name: show message if file exists        debug:          msg: The user file already exists.        when: file_exists is succeeded

Запустим наш плейбук на выполнение:

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

При повторном запуске плейбука:

Получаем сообщения, что файлы уже существуют.

Циклы в Ansible

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

В следующем примере мы объявляем в переменной file_name значение ansible, затем создаем файлы с именами, содержащими значение file_name и через дефис значение одной из переменных внутри loop.

---  - hosts: all    vars:      - user: otus      - file_name: ansible        tasks:      - name: creates users files        file:          path: /home/{{ user }}/{{ file_name }}-{{ item }}          state: touch        loop:          - test10          - test20          - test30

Запустим получившийся плейбук:

В результате работы сценария получаем три файла с именами, соответствующими заданному шаблону:

Заключение

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

Также хочу порекомендовать всем бесплатный урок курса DevOps практики и инструменты от OTUS, где мои коллеги расскажут про 3 основных принципа безопасности инфраструктуры. В уроке будет демо, где эксперты OTUS разберут одну проблему на инфраструктуре — очень интересный протокол Диффи-Хеллмана на примере больших чисел с отсылкой на эллиптические кривые и криптографию.Преподаватель на пальцах покажет как работает алгоритм и как исправить проблему связанную с ним в nginx.


ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/711136/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *