Мы продолжаем серию статей о применении подхода GitOps к инфраструктуре нашей организации. Первую часть можно почитать тут.
Я – ведущий DevOps инженер в IT-хабe группы компаний Dyninno. Мы (команда больше 300 человек) занимаемся разработкой ПО и отвечаем за IT инфраструктуру всех компаний группы. Dyninno – международный холдинг, который работает в трех сегментах бизнеса: авиаперелеты, финансовый сектор и индустрия развлечений (кастинг актеров). В прошлой статье я рассказывал о нашем переходе на GitOps, а сегодня хочу остановиться подробнее на управлении инфраструктурой в рамках этого перехода. Эта статья может быть интересна тем, кто задумывается о внедрении GitOps в свою инфраструктуру.
Для большей связанности повествования повторим два ключевых тезиса из предыдущего материала:
Все наши сервисы в процессе миграции на Kubernetes.
Мы используем подход GitOps с ArgoCD для управления Kubernetes.
Уже написано много материалов о том, что такое “Инфраструктура-как-Код” (IaC), поэтому я не буду останавливаться на общих вещах, и расскажу подробнее про наш опыт.
Итак, когда зашла речь о том, какое же IaC решение использовать, мы остановили свой выбор на Terraform, а не на CloudFormation или других аналогах, даже несмотря на то, что большая часть нашей инфраструктуры расположена в AWS. Главный плюс Терраформа в том, что мы можем использовать унифицированное решение для всех сред.
Терраформ дает возможность сосредоточиться на освоении одного инструмента, и при необходимости легко переключаться между провайдерами, которые отвечают за взаимодействие с конкретным сервисом или облаком. Более того, существует возможность создавать свои собственные интеграции тогда, когда каких-то конкретных интеграций не хватает. Например, мы почти полностью переписали провайдер для работы с Dkron чтобы он отвечал нашим требованиям.
C чем мы столкнулись
В какой-то момент у нас назрела необходимость в решении, которое позволяло бы управлять доступом к инфраструктуре для большого количества операционных команд с различными ролями и правами. Мы рассматривали несколько вариантов решения этой задачи. Например, изучали возможность разделения Терраформа на несколько проектов, давая каждому члену команды доступ только к той части инфраструктуры, за которую он отвечает. Также мы рассматривали вариант раздавать IAM-роли по пользователям или группам пользователей. Оба эти варианта приводили к усложнению всей схемы и существенному увеличению времени необходимого для сопровождение этого сетапа.
В итоге мы пришли к выводу, что нам необходим вариант построения IaC, не требующий раздачи поголовного доступа к облаку. К тому же, нельзя было забывать о том, что все изменения, сделанные во время написания Терраформ кода, должны быть отражены в гит репозитории.
В результате мозгового штурма на тему улучшения workflow мы решили запускать Терраформ через GitLab-ci пайплайн. Такой подход сразу же показал качественное улучшение процесса по сравнению с локальным запуском Терраформа. Так, больше не нужно было предоставлять всем учетные данные для доступа к облаку. Но мы не были полностью удовлетворены таким решением. Во-первых, было неудобно каждый раз заходить в детали пайплайна, и искать в логах джоба результаты исполнения Терраформ команд. Это занимало много времени, особенно когда изменения вносились десятки раз в день. Во-вторых, конфигурацию пайплайна нельзя было назвать user-friendly. Например, один из темплейтов пайплайн джобов выглядел вот так:
.plan:
stage: plan
rules:
# run on merge requests, when TF folder changes
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
- $TF_ROOT/*
# run on default branch, when TF folder changes
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
changes:
- $TF_ROOT/*
script:
# run terraform
- cd ${TF_ROOT}
- terraform init -input=false -reconfigure
# create plan for apply
- terraform plan -input=false -out="${PLAN_CACHE}"
# print plan for gitlab reports
- terraform show -json "${PLAN_CACHE}" | jq -r "${JQ_PLAN}" > "${PLAN_JSON}"
artifacts:
paths:
- ${TF_ROOT}/${PLAN_CACHE}
reports:
terraform: ${TF_ROOT}/${PLAN_JSON}
Такая конфигурация — это не бином Ньютона, но все же хотелось использовать что-то более простое. И в-третьих, нам нужно было передавать кеш Терраформа между джобами init/plan/apply, что требовало дополнительной конфигурации, а этого хотелось бы избежать. К тому же, поскольку мы используем временные поды, которые поднимаются только для исполнения конкретного пайплайна, нам пришлось выделить внешнее хранилище кеша, что усложнило сетап еще больше. И чем больше команд начинало работать в этом сетапе, тем больше не самых положительных отзывов мы получали. Поэтому мы начали искать другой подход.
К чему мы пришли
В итоге очередного мозгового штурма мы решили поднять тестовый сетап на базе Atlantis, который является альтернативным решением для управления взаимодействиями Терраформа. Как и в предыдущих вариантах, Atlantis устраняет необходимость в создании учетных данных для каждого пользователя. Кроме того, Atlantis выгодно отличается тем, что добавляет комментарии с результатами исполнения команд Терраформа к соответствующему Merge Request. Эта функция позволяет всем членам команды просматривать историю взаимодействия с Терраформом и управлять этим взаимодействием без чтения километровых логов.
Проще говоря, в Atlantis реализован эффективный подход к взаимодействию с Терраформом, который позволяет команде легко управлять инфраструктурой через комментарии в Merge Request. И для этого нам нужно было сделать лишь одну небольшую конфигурацию, которая выглядит так:
version: 3
projects:
- dir: terraform/provision
terraform_version: v1.2.0
workflow: terraform
autoplan:
enabled: true
when_modified: ["**/*.tf", "**/*.tfvars"]
В итоге мы пришли к следующей схеме, которая полностью перекрывает наши потребности:
Что мы получили в результате
Приведу несколько преимуществ, которые мы ощутили, перейдя на подход Инфраструктура-как-Код (IaC) с помощью Терраформа и Atlantis:
Больше нет необходимости давать прямой доступ к облаку каждому члену команды, что повысило безопасность и снизило сложность управления доступами.
Все изменения легко отслеживаются и ими можно управлять через IaC с Терраформом. Вся история доступна через контроль версий, что улучшило управляемость.
Мы пришли к стандартизированному подходу, который можно использовать на всех наших проектах, что сокращает время адаптации при переходе специалистов с одного проекта на другой.
Используя Терраформ и IaC в целом, мы смогли оптимизировать управление нашей инфраструктурой и снизили влияние человеческого фактора.
Автор:
Вадим Гедзь, ведущий DevOps инженер, Dyninno Group
https://github.com/shini4i