В этой статье описывается возможность/идея/концепт изменения глобальных настроек на локальных серверах команд в большой инфраструктуре используя Gitlab CI и Ansible.
Допустим у вас имеются 20 команд разработчиков и 1 команда админов/DevOps. Как менять на всех серверах пароли админов? Как добавить корневой сертификат Предприятия на все сервера? И т.д.
Какую задачу решает?
Типичная ситуация:
Есть глобальные администраторы/DevOps.
Есть глобальные настройки (NTP, DNS, Proxy и т.д.)
Ecть локальные команды разработки: TeamA, TeamB, TeamC, TeamD и т.д.
Есть разработчики, которые могут ходить только на сервера своей команды.
Как добавлять/обновлять глобальных администраторов, глобальные настройки?
Задача усложняется тем что глобальные настройки хранятся отдельно от локальных настроек команд в приватных репозиториях.
Если у вас во всей компании немного серверов, то можно запустить Ansible в простом режиме — запустить обновление глобальных администраторов, глобальных настроек на всех серверах сразу.
Для больших инсталляций компании обычно используют Puppet, Chef.
Концепция
Для изменения глобальных настроек на локальных серверах команд в большой инфраструктуре я предлагаю механизм git субмодулей.
В репозиторий с локальными настройками применяются git субмодули с глобальными настройками.
Ниже представлена схематическая схема подключения приватного репозитория с глобальными настройками в локальные репозитории команд.
Вы можете использовать концепцию обновления глобальных настроек используя git submodule в инфраструктуре с Puppet, Chef, Salt, но в статье приводиться пример с Ansible.
Для примера установим tomcat, mysql, nginx и применим к ним глобальные настройки в команде под названием team.
В gitlab есть группа common, которая содержит общие настройки.
В группе common есть проект base-bootstrap, который содержит администраторов, настройки sysctl и т.д.
Обычно в компании есть несколько отделов разработки — чаще их называют командами (team).
В gitlab создаем группу team (у вас будет свое название команды).
В группе team создаем проекты: application, database, loadbalancer.
Скриншот с base-bootstrap, application, database, loadbalancer:
Репозиторий base-bootstrap включен как git submodule в репозитории application, database, loadbalancer.
При каждом коммите в репозитории application, database, loadbalancer запускает обновление субмодуля base-bootstrap.
После этого на сервера application, database, loadbalancer применяются ansible-playbook из base-bootstrap и ansible-playbook из base-bootstrap.
То есть, если добавить нового администратора в base-bootstrap или изменить системные настройки в base-bootstrap, то при коммите application, database, loadbalancer — новые настройки из base-bootstrap применятся в application, database, loadbalancer.
Подготовка
Необходимо прочитать статьи про Ansible для начинающих:
У вас должен быть развернут gitlab и gitlab-runner c установленным docker.
Docker executor здесь используется как пример — вы можете использовать Shell executor.
Как разворачивать gitlab и gitlab-runner:
# Статья о Gitlab-CI от Southbridge
# Непрерывная интеграция и развертывание Docker в GitLab CI
У вас должны быть 3 сервера (например, на ubuntu): application, database, loadbalancer.
Application, database, loadbalancer — это общие названия.
Все примеры можно расширять, улучшать, использовать другие ПО — в статье показывается общий принцип.
Как реализовать
Репозитори и весь код для теста можно взять отсюда: https://github.com/patsevanton/ansible-gitlab-habr
Если вы ходите на сервера по логину/паролю, то в нужной группе (в данном случае это team) создаем переменную userpassword (когда будете менять нужно также поменять переменную и в коде) и укажем там пароль (в коде используется пароль password)
Не забудьте на конечных серверах создать нужного вам пользователя с правами sudo (в коде используется юзер — user).
Для тех кто ходит на сервера по SSH ключам нужно создать в группе team переменную SSH_PRIVATE_KEY и добавить в нее приватный ключ пользователя, который будет подключатся на сервера.
Здесь приводится простой пример подключения к серверам, поэтому вопросы безопасности в статье не рассматриваются.
В каждом репозитории (application, database, loadbalancer) создаем git submodule:
git submodule add git@gitlab.example.com:common/base-bootstrap.git
git submodule add git@gitlab.example.com:team/team-users.git
Submodule нужны чтобы получить доступ к общему приватному репозиторию.
В нашем случае это репозиторий с общими настройками base-bootstrap и репозиторий пользователей команды team-users.
Где gitlab.example.com — ваш gitlab сервер.
Затем в .gitmodules меняем путь до репозитория на относительный
Пример:
[submodule "team-users"]
path = team-users
url = ../team-users.git
[submodule "base-bootstrap"]
path = base-bootstrap
url = ../../common/base-bootstrap.git
В каждом репозитории в hosts меняем IP на свои, в ansible.cfg меняем remote_user на своего пользователя.
Если у вас репозитории в последнее несколько часов/дней не было коммитов, а на сервера нужно выкатить новые общие изменения (например, нужно добавить нового админа) — для таких ситуаций есть ansible-pull.
Настроим чтобы ansible-pull скачивал репозиторий common/base-bootstrap.
Для этого нужно добавить репозиторий deploy token.
Переходим в репозиторий common/base-bootstrap затем идем в settings/repository/Deploy Tokens.
Создаем token. Полученные username и пароль записываем в base-bootstrap/vars/cron.yml.
После того как проверите что все корректно работает — думаю стоит изменить время запуска ansible-pull с "каждые 2 минуты" на подходящее вам.
Если ansible-pull упал — значит и упадет CI этого сервиса, которая запускается при каждом коммите в этот репозиторий сервиса (допустим сервис называется application)
Проверка
Создание нового администратора.
Попробуйте добавить нового администратора в https://github.com/patsevanton/ansible-gitlab-habr/blob/master/commons/base-bootstrap/vars/users.yml
Изменение sysctl
Попробуйте добавить/изменить настройки sysctl в https://github.com/patsevanton/ansible-gitlab-habr/blob/master/commons/base-bootstrap/vars/sysctl.yml
Добавление записей в cron
Попробуйте добавить записи cron в https://github.com/patsevanton/ansible-gitlab-habr/blob/master/commons/base-bootstrap/vars/cron.yml
Расширение или установка ваших приложений
Для начала вам нужно найти роль для установки ваших приложений.
Зайдите на https://galaxy.ansible.com/ и найти роль для установки вашего приложения.
Попробуйте установить ваше приложение с помощью роли из консоли на ваши сервера. Обычно в описаниях у всех ролей есть инструкция.
Например, попробуем рядом с tomcat установить java. Сначала установим роль geerlingguy.java
ansible-galaxy install geerlingguy.java
Создадим стандартный ansible.cfg такое же как репозиториях.
Создадим инвентарь:
[java]
java ansible_host=IP-сервера
Создадим playbook java.yml
- hosts: java
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.java }
Запускаем ansible-playbook java.yml
Если все прошло успешно добавляем в нужный проект (в данном случае application)
Роль geerlingguy.java добавляем в после роли robertdebock.tomcat https://github.com/patsevanton/ansible-gitlab-habr/blob/master/team/application/tomcat-app.yml#L11
Тоже самое и со всеми остальными приложениями, которые вам нужно установить на сервера.
Тестирование playbook и безопасность
Для упрощения статьи вопрос хранения паролей и тестирования не затрагиваем.
Есть статьи по тестированию playbook:
# Ansible: тестируем плейбуки (часть 1)
# Тестирование и непрерывная интеграция для Ansible-ролей при помощи Molecule и Jenkins
Ответы на вопросы
1) Mentat: А почему все-таки не как это в доке ansible написано, с окружениями? С первого прочтения выглядит как попытка переизобрести это все заново. Там достаточно удобно применять это все типа ansible-playbook -i env/teamA personalAPlaybook.yml
Ответ: Эта схема дает возможность менять глобальные настройки. То что описывается в вопросе — это изменение локальных настроек команд.
P.S. Возможно такая же функциональность реализована в Ansible Tower. Но я ничего по этому поводу сказать не могу — не работал с Ansible Tower.
Комментарии (7)
chemtech Автор
06.12.2018 12:37- push/pull рассматривается в статьях про Ansible.
- master-client / agentless здесь рассматривать не нужно, т.к. используется Ansible.
- централизованный репозиторий с обвязками, которые позволяют его
модифицировать согласно прав каждой из команд. — прошу уточнить вопрос - отдельная история — как не светить "секретные" данные всем пользователям (понятно, что если есть доступ к токену на чтение коммон-репозитория, то оттуда можно все вычитать). — В статье написано: "Для упрощения статьи вопрос хранения паролей и тестирования не затрагиваем."
- еще момент: а если конкретной команде нужно переопределить значение из базового общего репозитория (ну, например, sysctl значение особенное поставить). Каким образом будут мержиться значения? — это делается по базовым правилам Ansible, т.к. применение базового общего репозитория — это всего лишь import_playbook
gecube
06.12.2018 13:34это делается по базовым правилам Ansible, т.к. применение базового общего репозитория — это всего лишь import_playbook
это, к сожалению, не ответ. Короче, пример. Есть базовый шаблон sysctl. Нужно переопределить часть параметров, которые описаны в базовом шаблоне. Как будете делать? Какие подводные камни при этом выползут? Какие ограничения на плейбуки будут?
В статье написано: «Для упрощения статьи вопрос хранения паролей и тестирования не затрагиваем.»
без этого — это решение не полноценное.
прошу уточнить вопрос
по-моему, я вполне ясно выразился.
push/pull рассматривается в статьях про Ansible.
Ответ нерелевантен. Т.е. ответа на вопрос «почему ansible» именно в описываемом режиме — не будет и полагаю, что он будет таков, что «так было проще»?chemtech Автор
06.12.2018 13:50это, к сожалению, не ответ. Короче, пример. Есть базовый шаблон sysctl. Нужно переопределить часть параметров, которые описаны в базовом шаблоне. Как будете делать? Какие подводные камни при этом выползут? Какие ограничения на плейбуки будут?
В целях упрощения стать это не рассматривалось.
без этого — это решение не полноценное.
Тут еще очень что можно было бы добавить. Но написание статьи бы затянулось — я думаю что можно это поискать в интернете.
Ответ нерелевантен. Т.е. ответа на вопрос «почему ansible» именно в описываемом режиме — не будет и полагаю, что он будет таков, что «так было проще»?
Ansible был выбран потому эта реализация, которая была в статье, возможна и ansible сейчас довольно популярная система управления конфигурациями.
AlexGluck
06.12.2018 23:02А ниче, что сабмодуль при добавлении ставится на определенный хеш коммита? Каждый раз при пуле, надо апдейтить версию сабмодуля или при апдейте глобального РЕПО надо во всех дочерних апдейтить этот сабмодуль. Я пробовал такое реализовать, но отказался в пользу переменных, которые мерджатся и плейбуки под каждый проект. А роли через Галакси забираются.
chemtech Автор
07.12.2018 06:37Каждый раз при пуле субмодуль автоматически обновляется.
При апдейте глобального РЕПО надо во всех дочерних апдейтить этот сабмодуль. — Да, при коммите в локальный репо обновляется субмодуль. А если локальный репо не обновляется — то можно использовать ansible-pull.
Я пробовал такое реализовать, но отказался в пользу переменных, которые мерджатся и плейбуки под каждый проект. А роли через Галакси забираются. — я думаю всем интересно было бы почитать более подробно о вашем workflow.AlexGluck
07.12.2018 13:11У меня пачка уже недописанным статей. Надеюсь в новогодние праздники допишу, может и по этой теме напишу.
gecube
Не рассмотрены вопросы:
опечатка. Верно — "Salt"