[Open source, Системное администрирование, IT-инфраструктура, GitHub] Управляя Github-ом: через Terraform к самописному решению на Ansible

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
25-Авг-2020 16:38

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

И в качестве платформы выбрали Terraform.
«У меня есть кубики с буквами О, П, А…»
На бумаге все выглядело гладко. Terraform популярен, будет нетрудно найти знающих его людей. У него есть состояние, и TF приводит ресурсы к соответствию — мы всегда сможем быть уверены, что реальная конфигурация именно такая, как её описали. И не надо больше лазить по Web UI — посмотрел в конфиг и всё увидел.
Мы упёрлись в лимиты гитхаба. TF сначала читает всё, а потом меняет нужное. При наших размерах на это уходило около 20 минут, а до следующего изменения нужно было выждать час — мы упирались в лимиты Github-а на количество обращений к API.
Чтобы решить проблемы с ограничениями, мы поделили всё управление на шесть частей:
  • Члены организации.
  • Репозитории.
  • Команды.
  • Состав команд.
  • Репозитории команд.
  • Коллабораторы.

Теперь типичные операции стали выполнять в два захода.  Чтобы добавить нового разработчика, запускаем 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.  Но...
Ёлки-иголки, что ж так сложно-то!

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

Перевели на YAML
Организация
skyeng:
  name: Skyeng
  admin:
    - aleksandr.sergeich
  member:
    - andrey.vadimych
    - denis.andreich
    - mikhail.leonidych
    - vladimir.nickolaich

Группа
qa-team:
  privacy: secret
  maintainer:
    - denis.andreich
  member:
    - andrey.vadimych
    - mikhail.leonidych
    - vladimir.nickolaich

Репозиторий
alerta:
  description: >-
    Alerta monitoring system
  homepage: https://alerta.io
  teams:
    admin:
      - admin-team
    push:
      - dev-team
      - qa-team
  collaborators:
    direct:
      - denis.andreich
    outside:
      - 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
===========

Похожие новости: Теги для поиска: #_open_source, #_sistemnoe_administrirovanie (Системное администрирование), #_itinfrastruktura (IT-инфраструктура), #_github, #_github_i_ansible (github и ansible), #_github_i_terraform (github и terraform), #_zamena_terraform (замена terraform), #_blog_kompanii_skyeng (
Блог компании Skyeng
)
, #_open_source, #_sistemnoe_administrirovanie (
Системное администрирование
)
, #_itinfrastruktura (
IT-инфраструктура
)
, #_github
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 17:13
Часовой пояс: UTC + 5