В предыдущих сериях 1 2 3, были примеры того какие возможности в плане расширения предоставляет ansible, на примере работы с пакетами в archlinux. Сейчас я попробую решить пару - задач декларативными средствами ansible, принципиально не используя самописные плагины и вызов внешних скриптов напрямую. Заодно будет повод ознакомиться с тем, что собственно ansible предоставляет из коробки. Тем более, что они в playbook умудрились добавить поддержку циклов, условий, переменных и т.п. Интересно понять насколько удобно ими пользоваться.
Задача 1
Для хранения конфигов, удобно использовать символьные ссылки, что бы одна ссылка указывала на реальную директорию с настройками приложения, а вторая на директорию в ansible, которая будет заливаться в репозиторий. Синхронизация с такой организацией файлов становится очень удобной: меняем как угодно настройки приложений, потом в одном каталоге с ansible делаем commit сразу для всех настроек машины. На другой машине, для синхронизации достаточно сделать "git pull" и все настройки автоматически попадут в нужные места. Думаю идея понятна. Единственное, что необходимо сделать - это изначально создать нужные ссылки. Распишу по шагам, что для этого нужно, что бы было понятно что за манипуляции я буду проделывать в ansible:
Объясню каждую из задач по отдельности:
Т.е. в результирующей переменной получаем исходные данные с парами директорий и результаты их обработки, до всех значений можно в дальнейшем доступаться. Вот тут, можно почитать про ключевое слово "register" подробнее.
Задача 2
Ещё пример типичной задачи - добавить в скрипт развёртывания ssh ключ. В открытом виде по соображениям безопасности его не выложишь, а подкладывать руками - не удобно. Нужно хранить в шифрованном виде. Ansible содержит встроенный модуль для шифрования. Например шифруется файл вот так:
Во время выполнения второй команды, ansible спросит пароль и зашифрует им "file.txt", теперь его без опасения можно выкладывать хоть на GitHub (с известной долей паранойи конечно). Дальше было бы логично иметь возможность написать playbook, который этот файл расшифрует и положит в нужное место. Но увы и ах, несмотря на просьбы на github ansible с кучей плюсов, готовые pull-request, какие-то внешние плагины добавляющие что-то похожее, разработчики неумолимы, такой функциональности нет. Её вроде как обещают добавить во второй версии, но нужно то сейчас. А пока будьте добры запускайте отдельный command-line скрипт, который нужные файлы расшифрует на конечной машине:
Ух ты, с первого раза заработало. Ну хоть что-то.
Итоги: назвать удобными и самодостаточными поставляемые по умолчанию плагины и модули - язык не поворачивается. Пока читаешь документацию, все понятно и просто, как только начинаешь решать какие-то свои реальные задачи, почти всегда приходится рыться в google. Декларативный синтаксис - нефункционален и неудобен, за редким исключением руки тянутся к python.
Но не смотря ни на что, я все же попытаюсь довести до конца свой проект по сохранению конфигурации своей машины.
Задача 1
Для хранения конфигов, удобно использовать символьные ссылки, что бы одна ссылка указывала на реальную директорию с настройками приложения, а вторая на директорию в ansible, которая будет заливаться в репозиторий. Синхронизация с такой организацией файлов становится очень удобной: меняем как угодно настройки приложений, потом в одном каталоге с ansible делаем commit сразу для всех настроек машины. На другой машине, для синхронизации достаточно сделать "git pull" и все настройки автоматически попадут в нужные места. Думаю идея понятна. Единственное, что необходимо сделать - это изначально создать нужные ссылки. Распишу по шагам, что для этого нужно, что бы было понятно что за манипуляции я буду проделывать в ansible:
- В качестве конфигурации у нас будет набор пар директорий допустим такой:
[("~/.config/ansible/config/dir1", "~/tmp/config/dir1"), ("~/.config/ansible/config/dir2", "~/tmp/config/dir2")]
- При запуске playbook с синхронизацией нужно пройтись по всем парам в конфигурации и если второй элемент - не является ссылкой, то удалить его и заменить ссылкой на первый элемент. Обращу внимание, что в случае, когда второй элемент все же окажется ссылкой, то трогать его не нужно.
- hosts: all tasks: - name: Check the symlink stat: path={{ item.dst | expanduser }} with_items: - { src: '~/.config/ansible/config/dir1', dst: '~/tmp/config/dir1' } - { src: '~/.config/ansible/config/dir2', dst: '~/tmp/config/dir2' } register: output - name: Remove the directory (only if it is exist) file: path="{{item.item.dst | expanduser }}" state=absent when: item.stat.exists and item.stat.isdir with_items: output.results - name: Create symlink file: path="{{ item.item.dst | expanduser }}" src="{{ item.item.src | expanduser }}" state=link owner=rean group=users with_items: output.results
- "Check the symlink" - организовываем цикл по парам директорий (исходной и конечной), применяем к директории "dst" модуль stat, что бы выяснить что находится по этому пути (лежит ли там что-то вообще, если лежит то, что это - директория или файл и т.п.). Что бы развернуть исходный путь в полный, применяем фильтр expanduser. Результаты, которые выдаёт модуль stat будем складывать в переменную output. Упрощенно, в псевдокоде в переменную output результат записывается примерно вот так:
output.results = [] for it in items: output.results.append({"item": it, "stat": {"exists": os.path.exists(it.dst), "isdir": os.path.isdir(it.dst)}})
- "Remove the directory (only if it is exist)" - организовываем цикл по результатам, которые были записаны в переменную "output". Из интересного - тут используется ключевое слово when, которое позволяет сделать удаление только если на предыдущем этапе выяснили, что по "конечному" пути находится директория. Т.е. мы удаляем только директории, а если там была уже создана ссылка - оставляем как есть.
- "Create symlink" - ну и тут все совсем просто, делаем цикл по всем парам папок и создаём ссылки, если нужно. Нужность определяет модуль "file".
Задача 2
Ещё пример типичной задачи - добавить в скрипт развёртывания ssh ключ. В открытом виде по соображениям безопасности его не выложишь, а подкладывать руками - не удобно. Нужно хранить в шифрованном виде. Ansible содержит встроенный модуль для шифрования. Например шифруется файл вот так:
$ echo "hello" > ~/.config/ansible/config/file.txt
$ ansible-vault encrypt ~/.config/ansible/config/file.txt
$ ansible-vault decrypt ~/.config/ansible/config/file.txt
Задача 3
Должно же хоть что-то полноценно заработать без костылей. Попробуем задачу извлечения git репозитория с github. Идём в документацию, копируем пример:
Должно же хоть что-то полноценно заработать без костылей. Попробуем задачу извлечения git репозитория с github. Идём в документацию, копируем пример:
- hosts: all user: rean tasks: - name: get git repo git: repo=git@github.com:ReanGD/LearningEnglish.git dest=~/tmp/checkout
Итоги: назвать удобными и самодостаточными поставляемые по умолчанию плагины и модули - язык не поворачивается. Пока читаешь документацию, все понятно и просто, как только начинаешь решать какие-то свои реальные задачи, почти всегда приходится рыться в google. Декларативный синтаксис - нефункционален и неудобен, за редким исключением руки тянутся к python.
Но не смотря ни на что, я все же попытаюсь довести до конца свой проект по сохранению конфигурации своей машины.
Комментариев нет:
Отправить комментарий