Мы продолжаем серию статей о применении подхода 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
Комментарии (8)
smarthomeblog
14.06.2023 06:27Мы сделали проще. В PR при создании или любом последующем коммите добавляем план, сгенерированный Терраформом. При мерже, идет автоматический apply. Крутится все на self-hosted runners, прибитых к AWS аккаунтам. Так что никаких кредов не нужно.
- name: Terraform Plan id: plan run: | terraform plan -refresh=false -no-color -out out.plan - name: Comment PR if: github.event_name == 'pull_request' uses: peter-evans/create-or-update-comment@v2 with: issue-number: ${{ github.event.pull_request.number }} body: ${{steps.plan.outputs.stdout}} - name: Terraform Apply if: github.ref == 'refs/heads/develop' && github.event_name == 'push' run: terraform apply -auto-approve
teamfighter
14.06.2023 06:27Тоже используем atlantis, но терраформ сверху ещё обмазали terragrunt. План для атлантиса можно составлять автоматически, с помощью terraform-atlantis-config.
trublast
>Главный плюс Терраформа в том, что мы можем использовать унифицированное решение для всех сред
Поделитесь, как вы переносите свою IaC, описанную терраформом, например из AWS в GCP, или в какой-нибудь OpenStack?
Numen_Divinum
Думаю, унифицированность здесь в использовании Терраформа как решения для всех сред, т.е. специалистам нужно знать всего один инструмент. Один и тот же код для разных провайдеров, очевидно, использовать не получится
Ezhische
Можно и код унифицировать через собственные модули с интерфейсом независимым от облачного провайдера
smarthomeblog
Terraform-ом можно описывать не только инфраструктуру в AWS, но и сопутсвтующие сервисы тоже - дашборды в Sumo Logic, алерты в PagerDuty или Grafana. Ну и так далее. Плюс подозреваю, найти инженера, знающего Terraform и имеющего опыт работы с ним проще, чем на вендорозависимый CloudFormation.
ALexhha
Легче, только опыт работы с тераформом в aws не особо поможет в gcp или azure. Слишком все разное. Ну а сам по себе terraform, без привязки к провайдеру, осваивается за пару недель.
Hledacek
Не знаю как это делает топикстартер, но мы используем уже существующие YAML файлы как структуру и базу для написания новой конфигурации для нового провайдера, уж слишком много нюансов у каждого вендора. Однако при переходе из одного облака в другое, инфраструктура не самая большая проблама, перенос и обеспечение консистентности данных особенно при zero downtime - реальная боль.