Ansible

Ansible

Содержание

Начало работы

Установка

Наверх

Установить Ansible можно 2 способами:

  • Через пакетный менеджер Linux.

  • Через менеджер python - pip.

Полная документация по установке для Linux.

Словарь

Наверх

  • Hosts - инвентарный файл, где описываются хосты, группы хостов, а так же хранятся переменные для этих хостов.

  • Inventories - директория, где хранятся инвентарные файлы, а также переменные для групп и хостов.

  • Task - минимальный элемент описания конфигурации в котором описано состояние объекта.

  • Role - логически завершенный и обосновано выделенный набор tasks, который в дальнейшем используется для применения повторяющейся конфигурации в разных playbooks.

  • Playbook - файл с полным описанием конфигурации для конкретных хоста/группы, включает в себя tasks и roles.

  • Vars - переменные, используемые для вариативности параметров конфигурации в зависимости от хоста/группы/роли/etc.

  • Module - многоразовый автономный сценарий, который возможно конфигурировать от своих задач.

  • Requirements - файл с перечнем Ansible-ролей.

Список всех терминов в документации.

Структура файлов

Наверх

  • ansible.cfg - первоначальная настройка для ansible.

  • playbook-name.yml - ansible-playbook, в котором описаны задачи.

  • requirements.yml - файл с перечнем ansible-ролей, отдельно вынесенных задач.

  • inventories - директория для инвентарей ansible.

  • hosts - файл инвентаризации для рабочих серверов.

Первоначальная настройка ansible

Наверх

Конфигурационный файл ansible.cfg может находиться в таких местах, и в таком приоритете происходит поиск файла.

  • ANSIBLE_CONFIG - переменная среды, если установлена.

  • ./ansible.cfg – в текущей директории.

  • ~/.ansible.cfg — в домашней директории пользователя.

  • /etc/ansible/ansible.cfg — в стандартной директории ansible.

Полная документация по ansible.cfg.

Полный список параметров.

Древовидная структура файлов

Наверх

Один из вариантов правильной структуры директории.

inventories/
   production/
      hosts                 # файл инвентаризации для рабочих серверов
      group_vars/
         group1.yml         # назначение переменных определенным группам
         group2.yml
      host_vars/
         hostname1.yml      # назначение переменных определенным системам
         hostname2.yml

   development/
      hosts
      group_vars/
         group1.yml
         group2.yml
      host_vars/
         hostname1.yml
         hostname2.yml

library/                    # если есть пользовательские модули (опционально)
module_utils/               # если какие-либо пользовательские утилиты для поддержки модулей (опционально)
filter_plugins/             # если какие-либо настраиваемые плагины фильтров (опционально)

site.yml                    # playbooks
webservers.yml
dbservers.yml

roles/
    role1/
    role2/
    role3/
    role4/

Инвентарный файл

Наверх

Инвентарный файл - хост или перечень хостов, с которыми будет происходить работа.

Инвентарный файл можно описать в формате ini или yml.

ini

Наверх

[] - В скобки указывается название группы серверов.

[web]
web1
web2

[db]
db1
db2

Частоиспользуемые ключи:

  • ansible_host - ip адрес.

  • ansible_user - имя пользователя для подключения на удаленный сервер.

  • ansible_sudo_pass - Пароль для подключения sudo пользователя.

  • ansible_pass - Пароль пользователя.

  • ansible_ssh_private_key_file - путь до закрытого ключа. Для входа без участия пароля.

  • ansible_port - порт подключения ssh.

Пример:

[example]
example1
ansible_host=0.0.0.0
ansible_user=user
ansible_ssh_private_key_file=/home/user/.ssh/id_rsa
ansible_port=2222

Все ключи можно посмотреть в документации.

yml

Наверх

hosts - указываются точки доступа, которые не имеют какой-то группы.

children - указываются названия группы серверов и внутри идёт имя группы. И дальше идёт перечисление названий серверов, и как подключаться.

Пример yml файла.

---
all:
  hosts:
    dev:
  children:
    web:
      hosts:
        web1:
        web2:
    db:
      hosts:
        db1:
        db2:

Также можно указывать нужные прараметры как и в ini формате.

Пример:

---
all:
  children:
    example:
      example1:
        ansible_host: 0.0.0.0
        ansible_user: user
        ansible_ssh_private_key_file: /home/user/.ssh/id_rsa
        ansible_port: 2222
      example2:
        ansible_host: 0.0.0.0
        ansible_user: user
        ansible_ssh_private_key_file: /home/user/.ssh/id_rsa
        ansible_port: 2222

Playbook

Переменные

Наверх

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

Для инициализации или переопределения в плэйбуке переменных, используется vars.

vars:
  <variable>: <value>

Для использования переменных нужно заключать их в двойные фигурные скобки - {{ }}, и обязательно внутри скобочек переменная должна отделяться пробелами.

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

Примеры:

file:
  path: "{{ path_to_file }}"

file:
  path: "~/directory/{{ file_name }}.txt"

Также переменные можно задавать в отдельном файле.

<variable>: <value>

И после этого подключить этот файл к плейбуку. Для этого используется vars_files.

vars_files:
  - <paht-to-file>

Переменные можно определять как лист.

list:
  - var_1
  - var_2
  - var_3

Применение.

"{{ list[0] }}"

Переменные можно определять как словарь.

<dictionary>:
  <variable_1>: <value_1>
  <variable_2>: <value_2>

Применение.

dictionary['variable_1']
dictionary.variable_1

Переменные можно переопределять, и у них есть свои приоритеты.

Полный приоритет переменных.

Модули

Наверх

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

Пример на модуле file. Модуль file нужен для создания/удаления файла.

- name: create file
  file:
    path: /home/user/file.txt
    owner: user
    group: user
    mode: '0777'
    state: touch
  • name - описание модуля.

  • file - имя модуля, в версиях выше 2.9 он называется ansible.builtin.file.

  • path - путь к файлу.

  • owner - владелец файла.

  • group - группа файла.

  • mode - права файла.

  • state - что требуется сделать. touch - создать файл.

Каждый модуль имеет свои параметры и не имеет смысла расписывать их, и все модули можно найти на официальном сайте Ansible.

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

shell - запуск /bin/sh.

command - команды не будут обрабатываться через оболочку, поэтому такие переменные, как $HOME, и такие операции, как <, >, |, ; и & не будут работать.

Почему лучше использовать модули, а не команды shell. При исполнении сценария, asnible проверяет сделано ли уже это (скопирован ли файл, установлена ли программа и пр.), И если уже это сделано, то он ничего не делает.

Есть специальный модуль для отладки плэйбука - debug.

Условия

Наверх

Для проверки условия используется специальный параметр when.

В условиях в Ansible для сравнения используются:

  • == - равно.

  • != - не равно.

  • > больше.

  • < меньше.

  • >= больше равно.

  • <= меньше равно.

Можно указать несколько условий с помощью операторов and и or.

Для проверки вхождения символа или подстроки в строку используются операторы in и not.

Примеры:

Проверка семейства ОС.

- name: Check OS family
  debug: msg="This is Debian"
  when: ansible_os_family == "Debian"

Так же можно сохранить результат выполнения модуля в переменную. Для этого используется параметр register.

- name: Check if admin logged
  command: who
  register: who_check

- name: Print message if user admin not logged
  debug: msg="User admin is not logged on remote host"
  when: not 'admin' in who_check.stdout

Циклы

Наверх

Для циклов используется специальный параметр loop.

В данном примере просто будет выведено сообщение с номерами массива prime. В параметр loop, просто передаётся массив, который требуется обойти, а дальше с помощью переменной item вызывается по одному элементу.

vars:
  prime: [2, 3, 5, 7, 11]
tasks:
  - name: Show first five prime numbers
    debug:
      msg: "{{ item }}"
    loop: "{{ prime }}"

Как один из реальных примеров применения циклов. Создание пользователей из списка.

- name: add users
  ansible.builtin.user:
    name: "{{ item.username }}"
    password: "{{ item.pass }}"
  loop:
    - { username: user1, pass: password1 }
    - { username: user2, pass: password2 }

Роли

Создание роли

Наверх

Для создание роли используется ansible galaxy. И после этой команды будут созданы все стандартные директории для роли.

ansible-galaxy init <role-name>

Директории в роли

Наверх

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

  • files - хранения файлов, которые могут быть скопированы, конкретно для роли.

  • handlers - специльные обработчки событий, для совершение действий.

  • meta - информация о роли, создатель, компания, для каких платформ, зависимости, теги.

  • tasks - директория, где хранятся все таски.

  • templates - директория, где хранятся шаблоны.

  • tests - директория для тестов.

  • vars - перечень переменных, но их нельзя переопределить выше.

Requirements

Наверх

Для того чтобы вести зависимости проекта от требуемых ролей используется файл requirements.yml.

Параметры в файле:

  • src - источник роли, указывается URL-адрес репозитория.

  • scm - если src является URL-адресом, нужно указать scm. Поддерживаются только git или hg. По умолчанию git.

  • version - версия роли для загрузки. Используется тег, хэш коммита или имя ветки. По умолчанию master.

  • name - переопределение имени роли. По умолчанию используется имя репозитория.

Примеры:

Использование https.

- src: https://github.com/bennojoy/nginx
  scm: git
  version: master
  name: nginx_role

Использование ssh.

- src: git+ssh://git@github.com/bennojoy/nginx
  version: master
  name: nginx_role

При установке ролей по стандарту используется директория ~/.ansible/roles.

Установка из requirements.

ansible-galaxy install -r requirements.yml

Если требуется изменить путь до директории, то используется флаг --roles-path.

ansible-galaxy install --roles-path "<path>" -r requirements.yml

Пример:

ansible-galaxy install --roles-path ./roles -r requirements.yml

Handlers

Наверх

Handlers - это специальные задачи. Они вызываются из других задач ключевым словом notify.

Эти задачи срабатывают после выполнения всех задач в сценарии (play). При этом, если несколько задач вызвали одну и ту же задачу через notify, она выполнится только один раз.

Для этого используется специальная директория handlers.

Пример на установке nginx. Когда устанавливается nginx и то устанавливаются какие-то настройки конфигурации, и требуется после изменения настроек перезапустить nginx.

Конфигурация задач для установки nginx в файле tasks/main.yml. Здесь, устанавливается последняя версия nginx, а также копируются конфигурационные файлы, для настройки nginx.

- name: Install packages
  ansible.builtin.apt:
    name: nginx
    state: latest

- name: Create nginx config
  ansible.builtin.template:
    src: nginx.j2
    dest: "{{ setting_nginx__path_nginx_conf }}"
    mode: "0644"
  notify:
    - "Reload service nginx"

Файл handlers/main.yml, где указываются специальные задачи.

---
- name: Reload service nginx
  ansible.builtin.service:
    name: nginx
    state: reloaded

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

ansible.builtin.meta: flush_handlers

Шаблоны

Наверх

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

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

Параметры в файлах

Наверх

Файл с шаблоном имеет расширение .j2 - механизм создания шаблонов Jinja2.

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

Пример:

Пример небольшого шаблона, для подстановки значений (все переменные должны быть объявлены).

Файл nginx.conf.j2.

server {
    listen {{ nginx_http_port }}
    server_name {{ server_name }};
    location / {
        proxy_pass http://{{ ip_forward }}:{{ port_forward }};
    }
}

Копирование шаблона.

- name: Create nginx ssl config
  ansible.builtin.template:
    src: "nginx.conf.j2"
    dest: "/etc/nginx/conf.d/defaults.conf"
    mode: "0644"

Условие

Наверх

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

Шаблон:


<div data-gb-custom-block data-tag="if">

<div data-gb-custom-block data-tag="elif"></div>

<div data-gb-custom-block data-tag="else"></div>

</div>

Пример:

server {
    

<div data-gb-custom-block data-tag="if" data-0='80' data-1='80' data-2='80' data-3='80'>

        listen {{ nginx_port }}

    

<div data-gb-custom-block data-tag="elif" data-0='443' data-1='443' data-2='443'></div>

        listen {{ nginx_port }} ssl;
        server_name example.com;
        ssl_certificate example.com.crt;
        ssl_certificate_key example.com.key;

    

</div>

    server_name {{ server_name }};
    location / {
        proxy_pass http://{{ ip_forward }}:{{ port_forward }};
    }
}

Цикл

Наверх

Цикл предназначен для перебора и обрабоки массива значений.

Шаблон:


<div data-gb-custom-block data-tag="for">

</div>

Пример:


<div data-gb-custom-block data-tag="for">

    {{ person }}

</div>

Фильтры

Наверх

Фильтры позволяют преобразовывать данные JSON в данные YAML, разбивать URL-адреса для извлечения имени хоста, получать хеш SHA1 строки, добавлять или умножать целые числа и многое другое.

Примеры:

Указание значение переменной по умолчанию.

{{ some_variable | default(5) }}

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

{{ some_list | unique }}

Объединение двух списков.

{{ some_list1 | union(some_list2) }}

Пересечение 2 списков (уникальный список всех элементов в обоих):

{{ some_list1 | intersect(some_list2) }}

Разница в 2 списках (элементы в 1, которые не существуют во 2):

{{ some_list1 | difference(some_list2) }}

Полная документация по фильтрам.

Тестирование

Наверх

Molecule - фрэймворк, предназначенный для тестирования ролей в Ansible.

Установка

Наверх

Установка molecule.

python3 -m pip install molecule

Документация по molecule

Иницилизация роли

Наверх

Molecule использует ansible-galaxy под капотом для создания обычных макетов ролей. Дополнительно создаётся директория molecule с нужными файлами.

molecule init role [namespace].[role_name] --driver-name [driver]

Файлы:

  • molecule.yml - это центральная точка входа. Можно настроить каждый инструмент, который Molecule будет использовать при тестировании.

  • converge.yml - это файл playbook, содержащий вызов роли.

  • verify.yml - это файл Ansible, позволяет писать специальные тесты для состояния контейнера после завершения выполнения роли.

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

Примеры:

Создание роли nginx с использованием драйвера docker.

molecule init role acme.nginx --driver-name docker

Запуск тестирования

Наверх

Тестирование с помощью molecule запускается в корневой директории роли.

Запуск создания экземпляра.

molecule create

Просмотр создания экзепляра.

molecule list

Запустить проверку роли.

molecule converge

Запуск тестирования роли.

molecule verify

Если требуется проверить экземпляр руками.

molecule login

Уничтожение экзепляра.

molecule destroy

Также есть команда, если требуется запустить сразу create, converge, verify и destroy по очереди.

molecule test

Тесты для проверки состояния

Наверх

Для инфраструктуры можно (и нужно) писать тесты, которые проверяют, что нужный код исполнилняется верно, все нужные сервисы запускаются, файлы верно настроены и т.д.

Сейчас по стандарту используется проверка инфраструктуры с помощью Ansible. Раньше было использование с применением testinfra написанная на Python.

Полезные ссылки

Наверх

Специальные переменные от ansible.

Last updated