В этой статье описывается возможность/идея/концепт изменения глобальных настроек на локальных серверах команд в большой инфраструктуре используя 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.