Русский
Русский
English
Статистика
Реклама

Управляя Github-ом через Terraform к самописному решению на Ansible

У нас 350+ человек и 400+ репозиториев на Github-е. В каждой репе может быть несколько админов, и они творят, что считают нужным, естественно, случается так, что один человек не знает, что делает другой. Когда нам в инфре надоело смотреть на мучения других и добавлять/удалять людей вручную, мы решили, что перейдем централизованное управление, Infrastructure as Code.


image


И в качестве платформы выбрали Terraform.


У меня есть кубики с буквами О, П, А


На бумаге все выглядело гладко. Terraform популярен, будет нетрудно найти знающих его людей. У него есть состояние, и TF приводит ресурсы к соответствию мы всегда сможем быть уверены, что реальная конфигурация именно такая, как её описали. И не надо больше лазить по Web UI посмотрел в конфиг и всё увидел.


Мы упёрлись в лимиты гитхаба. TF сначала читает всё, а потом меняет нужное. При наших размерах на это уходило около 20 минут, а до следующего изменения нужно было выждать час мы упирались в лимиты Github-а на количество обращений к API.


Чтобы решить проблемы с ограничениями, мы поделили всё управление на шесть частей:


  1. Члены организации.
  2. Репозитории.
  3. Команды.
  4. Состав команд.
  5. Репозитории команд.
  6. Коллабораторы.

Теперь типичные операции стали выполнять в два захода. Чтобы добавить нового разработчика, запускаем Terraform с разными параметрами: 1 и 4. Чтобы добавить новый репозиторий, выполняем 2 и 5. Это стало занимать довольно много времени: запустить TF один раз, вернуться через несколько минут, запустить повторно.Вернуться ещё раз ответить автору запроса, что всё сделано.Или не сделано, если где-то в конфиге или пулл-реквесте закралась ошибка Однажды принесли PR, где в нескольких местах вместо английской c была написана русская с. Отлавливать пришлось долго


Да и синтаксис не зашел. Описание чего угодно довольно многословное. Вот пример:


resource "github_membership" "membership_for_юзер" {    username = "юзер"    role     = "member"}resource "github_team" "team_команда" {    name           = "команда"    description    = ""    privacy        = "closed"    parent_team_id = "123456"}resource "github_team_membership" "team_команда_юзер_membership" {    team_id  = "${data.terraform_remote_state.teams.team_команда_id}"    username = "юзер"    role     = "member"}resource "github_repository" "репа" {    name          = "репа"    description   = ""    homepage_url  = ""    has_projects  = false    has_wiki      = true    has_issues    = true    has_downloads = true    private       = true    archived      = false    topics        = ["yii", "school", "mobile"]}resource "github_team_repository" "team_команда_repo_репа" {    team_id    = "${data.terraform_remote_state.teams.team_команда_id}"    repository = "${data.terraform_remote_state.repos.repo_репа_name}"    permission = "push"}resource "github_repository_collaborator" "репа_юзер_collaborator" {    repository = "репа"    username   = "юзер"    permission = "admin"}

При том, что такие вещи обычно копипастят, после чего что-то меняют, можно запросто это что-то недоменять или убрать лишнее. Поставили минус вместо подчерка и никто не заметит.Цена ошибки минуты ожидания. Представьте себе дебаг с минутами между итерациями...


Ссылаться на ресурсы по именам нельзя, можно только по id. Ресурсы репозитории описываются в одном файле, а переменные с их id в другом. Юзеры и команды аналогично. Также лежат в разных местах параметры самого репозитория и список команд с доступом к нему. А коллабораторы где-то в третьем месте. Типичный вопрос у кого есть доступ к этой репе? Попробуй собери всё в кучу.


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


Спустя месяцы после внедрения TF, особенно весело было узнавать, что какой-то репозиторий был сделан втихую вручную. И когда теперь понадобилось кому-то дать права, мы не можем это сделать. Ведь Terraform про него ничего не знает! Разумеется, эту проблему тоже можно решить: удалить репу и сделать её снова средствами TF, или же как-то переинициализировать сам TF. Но...


Ёлки-иголки, что ж так сложно-то!


image


Добавить человека в организацию это всего одно обращение к API. Дать права команде на репозиторий аналогично. Наконец, когда Terraform просто стал падать на управлении составом команд со словами, что он хочет удалить 800 ресурсов, добавить 801 и почему-то не может это сделать, мы сели прикидывать, как оно могло бы быть в идеальном мире.


  • Изменения применяются точечно.
  • Простой синтаксис, понятный без чтения документации. Без лишних слов вроде resource, value и без идентификаторов типа 123456, которые непонятно, откуда брать.
  • Все параметры какой-то сущности например, репозитория -- описаны в одном месте.
  • Одна репа / группа / организация один файл.

Перевели на YAML


Организация


skyeng:name: Skyengadmin:- aleksandr.sergeichmember:- andrey.vadimych- denis.andreich- mikhail.leonidych- vladimir.nickolaich

Группа


qa-team:privacy: secretmaintainer:- denis.andreichmember:- andrey.vadimych- mikhail.leonidych- vladimir.nickolaich

Репозиторий


alerta:description: >-Alerta monitoring systemhomepage: https://alerta.ioteams:  admin:   - admin-teampush:- dev-team- qa-teamcollaborators:direct:- denis.andreichoutside:- william.shakespeare

Хотелось заюзать готовое решение, но не нашли и написали своё


Наверно, TF это клёвая штука, но для нас оказался прокрустовым ложем И мы пошли реализовывать собственное видение на Ansible, который активно используем для управления инфраструктурой.


Оно отрабатывает за считанные секунды: типичные изменения это всего несколько вызовов, для больших проектов несколько десятков. Легко делается CI/CD. Параметры чего-либо собраны в один файл: изменения локальные, их просто отследить. И теперь действительно получается заглянуть в файл и всё увидеть. Ссылка на код в конце, а пока пара примеров.


Теперь сделать новый репозиторий или обновить существующий можно так:


ansible-playbook gitwand.yml    -e github_repos__state=present    -e github_repos__include=my_repo

Сделать что-то с группой вот так:


ansible-playbook gitwand.yml    -e github_teams__state=present    -e github_teams__include=my_team

Если надо обновить все группы, то просто не указываем параметр github_teams__include.


И ещё небольшой побочный эффект. У нас есть LDAP, и везде, где можно, мы берём юзеров и группы юзеров из него. Логин человека состоит из имени и фамилии, и это лучше, чем ник, придуманный кем-то в бурной молодости и понятный только его владельцу. Теперь у нас появилась возможность использовать эти же имена вместо ников на Github-е.


Если хотите попробовать наше решение


Оно лежит здесь.

Источник: habr.com
К списку статей
Опубликовано: 25.08.2020 14:18:31
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании skyeng

Open source

Системное администрирование

It-инфраструктура

Github

Github и ansible

Github и terraform

Замена terraform

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru