Как управлять состояниями Terraform с помощью GitLab Enterprise?


TL;DR: С массовым внедрением Terraform и превращением его в де-факто инструмент для разработчиков для создания и управления облачной инфраструктурой в масштабе, большинство компаний, которые сегодня в значительной степени полагаются на Terraform для управления инфраструктурой, предпочитают делать это с помощью инструмента оркестровки. В этом блоге мы рассмотрим способ управления штатами Terraform с помощью Gitlab Enterprise.

Terraform стал практически повсеместным способом предоставления сервисов в эпоху облачных технологий. Однако, когда мы начинаем строить инфраструктуру, используя подход Terraform as-code, есть несколько моментов, которые необходимо учитывать, чтобы иметь возможность управлять этими операциями в масштабе, для различных децентрализованных сервисов и для распределенных команд. В компании Firefly мы часто сталкиваемся с проблемами управления IaC в масштабе, поскольку мы помогаем организациям обнаруживать и управлять их многочисленными облачными активами.

Управление Terraform в масштабе

С массовым внедрением Terraform и превращением его в де-факто инструмент для разработчиков для создания и управления облачной инфраструктурой в масштабе, большинство компаний, которые сегодня в значительной степени полагаются на Terraform для управления инфраструктурой, выбирают для этого инструмент оркестровки. Эти инструменты дополняют набор инструментов, предоставляемых Hashicorp, чтобы помочь справиться с множеством модулей и провайдеров, фреймворков и сервисов, предоставляемых при огромных масштабах облачных операций, а также удаленный бэкенд для поддержания состояния инфраструктуры.

Компании, которые выбирают полностью управляемый инструмент оркестровки, часто выбирают Terraform Cloud (SaaS-решение) от Hashicorp, однако, как и все инструменты, завоевавшие широкую популярность, существует множество альтернатив, не принадлежащих Hashicorp, которые также могут воспользоваться волной успеха этого инструмента. Преимуществами Terraform Cloud являются полностью удаленный бэкенд, встроенная интеграция с GitHub, государственное версионирование и расширенные возможности для заинтересованных сторон инфраструктуры, таких как инженеры платформы, команды DevOps и облачные инженеры.

Однако есть и другой вариант, который набирает популярность для крупномасштабных операций с Terraform, и это подход GitOps, те, кто решает развернуть свою инфраструктуру с помощью GitHub Actions или других встроенных приложений CI pipelines. Наиболее популярным инструментом для этого случая использования является Atlantis. Atlantis — это базовое решение, которое автоматически интегрируется с каждым запросом pull request (PR) и внедряет лучшие практики развертывания инфраструктуры, как они определены в политике компании, например: владелец кода, рецензенты кода, модульные тесты с использованием таких инструментов, как TerraTest, и др.

Если вы выберете метод GitOps, это не будет сопровождаться управляемым бэкендом, и поэтому он все равно потребуется тем, кто хочет поддерживать состояние своей IaC. В настоящее время Terraform поддерживает интеграцию «из коробки» с: AWS S3, GCS, Hashicorp Consul, Kubernetes и HTTP.

Однако, как мы все знаем, сегодня многие компании по многим причинам предпочитают работать с Gitlab on-prem, и поэтому все интеграции с Github и Github Actions становятся менее актуальными при таком выборе.

Terraform States с использованием Gitlab Enterprise

Те компании, которые выбирают GitLab в качестве основной платформы управления исходным кодом (SCM), также часто предпочитают развертывать свою инфраструктуру с помощью специальных конвейеров GitLab. Это оставляет нас с вопросом: а как насчет состояния Terraform?

Представляем новую функцию для удаленных бэкендов внутри Gitlab. Мы знали, что это именно то, что нам нужно как магазину Gitlab. Однако, когда мы попытались ее включить, мы обнаружили очень мало документации, которая могла бы нам помочь… и поэтому нам пришлось спуститься в кроличью нору, изучая, как сконфигурировать и настроить удаленные бэкенды с учетом специфических требований, продиктованных API Gitlab, и мы хотели бы поделиться с вами некоторыми замечательными сведениями, которые мы обнаружили.

Начнем с некоторых проблем, с которыми мы сразу же столкнулись. Настройка бэкенда Gitlab оказалась довольно сложной: нам пришлось глубоко разобраться в синтаксисе конфигурации Gitlab и различных конфигурациях S3, чтобы все это настроить. Как только нам удалось настроить ведро S3 в качестве специального хранилища данных для наших состояний Terraform, мы обнаружили, что все они шифруются с помощью AES 256 внутри S3 с помощью Gitlab. Это означает, что после шифрования эти состояния больше недоступны в Terraform. Поэтому вам придется использовать API Gitlab, чтобы загрузить их и использовать в своей среде.

Вот тут-то и возникает сложность. Итак, мы выбрали развертывание и оркестровку нашего кода с помощью Gitlab. Отлично. Далее мы хотим использовать их новую возможность управления состоянием — но это означает, что мы не можем управлять состоянием Terraform, если оно зашифровано и недоступно для Terraform.

Это добавляет особый уровень сложности для данного случая использования, поскольку при работе в современном инженерном формате CI/CD Gitlab будет увеличивать номер вашей версии с каждым развертыванием, чтобы вести журнал и историю изменений развернутых версий. Все это хорошо и важно в качестве лучшей инженерной практики — однако это вводит несколько пробелов, когда дело доходит до управления состоянием Terraform.

Если мы посмотрим на документацию Gitlab API, то способ загрузки состояния выглядит следующим образом:

curl --header "Private-Token: " "https://gitlab.example.com/api/v4/projects//terraform/state//versions/"

Это означает, что для того, чтобы иметь возможность загрузить состояние, вы должны иметь несколько важных частей информации:

  • Ваш токен доступа
  • ID вашего проекта
  • Имя вашего штата
  • Номер вашей версии

Мало того, что редко кто знает конкретное имя своей установки, очень редко кто знает номер последней версии (Gitlab не отображает это в пользовательском интерфейсе, только если вы наведете курсор на установку или щелкните на ней, вы увидите этот номер в URL) — поскольку он постоянно меняется в процессе непрерывного развертывания.

В очень крупномасштабных операциях постоянно работают сотни окружений под управлением Terraform, и постоянно развертываются новые. Не говоря уже о различных типах окружений — development, staging, production, причем все они имеют несколько учетных записей dev. Это иголка в стоге сена.

Мы чувствовали, что уперлись в стену. Мы знали, что должен быть лучший способ. Мы вернулись к исследованиям.

Gitlab GraphQL API для управления состоянием Terraform

Покопавшись глубже, мы нашли золотую жилу. Существует другой способ.

Мы нашли скрытый GraphQL API, который раскрывает все ваши окружения Gitlab, созданные с помощью GitLab Pipelines, что позволяет вам извлекать довольно простую всю критическую информацию, необходимую для загрузки и доступа к Terraform State.

Посмотрите на это в действии — ниже приведен фрагмент кода GraphQL, который позволяет вам запросить и извлечь необходимые данные.

POST https://{{GITLAB-HOST}}/api/graphql { "operationName": "getStates", "variables": { "projectPath": "sefi/tf-demo", "first": 50, "after": null, "last": null, "before": null }, "query": "query getStates($projectPath: ID!, $first: Int, $last: Int, $before: String, $after: String) {n project(fullPath: $projectPath) {n idn terraformStates(first: $first, last: $last, before: $before, after: $after) {n countn nodes {n ...Staten __typenamen }n pageInfo {n ...PageInfon __typenamen }n __typenamen }n __typenamen }n}nnfragment State on TerraformState {n idn namen lockedAtn updatedAtn deletedAtn lockedByUser {n ...Usern __typenamen }n latestVersion {n ...StateVersionn __typenamen }n __typenamen}nnfragment User on User {n idn avatarUrln namen usernamen webUrln __typenamen}nnfragment StateVersion on TerraformStateVersion {n idn downloadPathn serialn updatedAtn createdByUser {n ...Usern __typenamen }n job {n idn detailedStatus {n idn detailsPathn groupn iconn labeln textn __typenamen }n pipeline {n idn pathn __typenamen }n __typenamen }n __typenamen}nnfragment PageInfo on PageInfo {n hasNextPagen hasPreviousPagen startCursorn endCursorn __typenamen}n" }
Вход в полноэкранный режим Выйти из полноэкранного режима

Этот API возвращает последнюю версию всех окружений в проекте.


{ "data": { "project": { "id": "gid://gitlab/Project/", "terraformStates": { "count": 1, "nodes": [ { "id": "gid://gitlab/Terraform::State/", "name": "", "lockedAt": null, "updatedAt": "2022-08-02T19:55:26Z", "deletedAt": null, "lockedByUser": null, "latestVersion": { "id": "gid://gitlab/Terraform::StateVersion/", "downloadPath": "/api/v4/projects//terraform/state//versions/0", "serial": 0, "updatedAt": "2022-08-02T19:55:26Z", "createdByUser": null, "job": null, "__typename": "TerraformStateVersion" }, "__typename": "TerraformState" } ], "pageInfo": { "hasNextPage": false, "hasPreviousPage": false, "startCursor": "", "endCursor": "", "__typename": "PageInfo" }, "__typename": "TerraformStateConnection" },
Войти в полноэкранный режим Выйти из полноэкранного режима

Используя полученный ответ, мы можем загрузить последнюю версию Terraform State, используя ранее упомянутый Gitlab API:

https://{{GITLAB-HOST}}/API/v4/projects//terraform/state//versions/

Вот и все! Это так просто.

Для тех, кто использует Gitlab On-Prem или Enterprise, используя Gitlab Pipelines, действительно нет необходимости добавлять в стек дополнительные инструменты для оркестровки и управления Terraform. Вы можете использовать встроенную поддержку Gitlab и интеграцию Terraform с S3. Благодаря доступу к GraphQL API вы теперь можете получить необходимую информацию для загрузки состояния из хранилища через Gitlab API.

Оцените статью
devanswers.ru
Добавить комментарий