Управление инфраструктурой с помощью terragrunt (terraform) и gitlab ci

от автора

В этом посте:

  • Использование terraform модулей
  • Организуем структуру каталогов с terraform модулями для terragrunt согласно вашей инфраструктуре
  • Создание/Обновление/Удаление инфраструктуры одной terragrunt командой
  • Настройка в gitlab ci для запуска и сохранения terraform lock и state в gitlab
  • Бекап terraform state из gitlab

Terraform — это инструмент для управления инфраструктурой в облаке с использованием описания в виде кода.

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

Terragrunt — это обертка для Terraform, позволяющая решать проблемы, связанные с масштабированием и переиспользованием кода для настройки инфраструктуры.

Он позволяет повторно использовать конфигурационные параметры и поддерживает многоуровневые конфигурации и зависимости.

GitLab CI (Continuous Integration) — это система интеграции продолжения, которая позволяет пользователям автоматизировать процессы сборки, тестирования и деплоя для проектов, использующих репозиторий GitLab.
Он позволяет разработчикам начать проект быстро и просто, а также иметь возможность использовать настраиваемые пайплайны для автоматизации процессов сборки и деплоя.

Использование terraform модулей

Terraform модули — это предварительно настроенные компоненты Terraform, которые можно использовать для создания и управления различными инфраструктурными компонентами.

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

Посты про terraform модули:

Будут использоваться модули:

Организуем структуру каталогов с terraform модулями для terragrunt согласно вашей инфраструктуре

Можно использовать terraform модули с чистым terraform, но c terragrunt это будет удобнее:

  • Код будет компактнее, а значит читабельнее
  • Структура каталогов отражает то, как организована ваша инфраструктура.
  • Можно создать/обновить/удалить инфраструктуру одной командой
  • Можно периодически запускать plan и проверять изменилось что-нибудь

Посты про terragrunt:

Будет рассматриваться репозиторий https://gitlab.com/anton_patsev/gitlab_ci_terragrunt
Структура каталогов этого репозитория минимальная в целях объяснения принципов работы terragrunt:

. ├── dev │ ├── env.hcl │ └── group1 │     ├── dns │     │   └── terragrunt.hcl │     ├── group.hcl │     └── vpc-address │         └── terragrunt.hcl ├── README.md └── terragrunt.hcl

Обычно инфраструктуру разделяют на какие-нибудь группы:

  • dev/uat/prod
  • vpc1/vpc2
  • другие варианты

Пример структуры каталогов от самого terragrunt — https://github.com/gruntwork-io/terragrunt-infrastructure-live-example

Рассмотрим HCL конфиги

Рассмотрим корневой terragrunt.hcl.
Корневой terragrunt.hcl нужен для задания общих переменных, параметров.

# корневой terragrunt.hcl  locals { # переменные общие для всего проекта   env_vars   = read_terragrunt_config(find_in_parent_folders("env.hcl")) # Функция read_terragrunt_config() используется для чтения конфига env.hcl (group.hcl),   group_vars = read_terragrunt_config(find_in_parent_folders("group.hcl")) # найденного с помощью функции find_in_parent_folders() в этой директории или вышележащих директориях до корневой директории.   project_id = "43542597" # project_id в gitlab   env        = "dev" # Переменная, которая описывает директорию dev как dev окружение в этом проекте.   username   = "anton_patsev" # ваш login в gitlab   string_path_relative_to_include = join(".", [replace("${path_relative_to_include()}", "/", "-"), "tfstate"]) # получение из пути dev/group1/dns получить имя tfstate: dev-group1-dns.tfstate }  inputs = merge({   # merge в terragrunt используется для объединения входных параметров из нескольких источников.   # Это позволяет использовать общие параметры для нескольких конфигураций Terraform,   # а также позволяет переопределять параметры для конкретной конфигурации.   cloud_id   = local.env_vars.locals.cloud_id   folder_id  = local.env_vars.locals.folder_id   network_id = local.group_vars.locals.network_id })  remote_state {   # В backend.tf определяется где сохраняется terraform state. В данном случае сохраняется в http сервисе.   backend = "http"   # Параметры для сохранения terraform state   config = {     address        = "https://gitlab.com/api/v4/projects/${local.project_id}/terraform/state/${local.string_path_relative_to_include}"     lock_address   = "https://gitlab.com/api/v4/projects/${local.project_id}/terraform/state/${local.string_path_relative_to_include}/lock"     unlock_address = "https://gitlab.com/api/v4/projects/${local.project_id}/terraform/state/${local.string_path_relative_to_include}/lock"     username       = local.username # Login доступа к http сервису (в данном случае gitlab)     # Пароль доступа берется из переменной окружения     lock_method    = "POST"     unlock_method  = "DELETE"     retry_wait_min = 5   }   generate = {     path      = "backend.tf"     # Создается файл backend.tf в каждом скачанном terraform модуле     if_exists = "overwrite_terragrunt"   } }

Рассмотрим env.hcl.
В директории dev в конфиге env.hcl задаются параметры для dev окружения, например id folder или другие.

locals {   cloud_id  = "b1gvct0b630bbm7i7v90" # cloud-patsevanton   folder_id = "b1g972v94kscfi3qmfmh" # default }

Рассмотрим group.hcl.
В директории group1 в конфиге group.hcl задаются параметры для обособленной группы (group1), например network_id или другие.

locals {   network_id = "enprkje8ae9b74e0himb" # default }

Рассмотрим terragrunt.hcl для вызова определенного terraform модуля. В качестве примера возьмем terragrunt.hcl из директории dns.
В директории group1 присутствуют 2 директории: dns и vpc-address. В каждой директории присутствует terragrunt.hcl.

terraform {   # Ссылка на terraform модуль и его тег или ветку   source = "github.com/patsevanton/terraform-yandex-dns.git//.?ref=main" }  include {   # Этот блок кода используется для поиска и загрузки конфигурационных параметров из родительских папок.   # Это позволяет использовать один и тот же код для конфигурации нескольких подсистем.   path = find_in_parent_folders() }  # Указывается зависимость текущего кода от vpc-address dependency "vpc-address" {   config_path                             = "../vpc-address" # Указываем где искать vpc-address   # Mock_outputs_allowed_terraform_commands используется для того,   # чтобы позволить Terragrunt выполнять имитацию команд Terraform для проверки ваших конфигураций без изменения любого реального состояния.   # Это позволяет проверять и отлаживать ваши конфигурации до того, как вы будете применять их на самом деле.   mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"]   # При выполнении terragrunt init/validate/plan в переменную external_ipv4_address будет подставлено фейковое значение   mock_outputs = {     external_ipv4_address = "fake_external_ipv4_address"   } }  # Параметры, которые могут быть переданы в terraform модуль. inputs = {   description = "grafana"   zone        = "apatsev.org.ru."   name        = "apatsev-org-ru"   public      = true   recordset = [     {       name = "grafana1.apatsev.org.ru."       type = "A"       ttl  = 600       data = [dependency.vpc-address.outputs.external_ipv4_address]     },   ] }

Запуск terragrunt в каждой директории

cd dev/group1/dns terragrunt apply cd .. cd vpc-address terragrunt apply

Создание/Обновление/Удаление инфраструктуры одной terragrunt командой

Можно создать/удалить инфраструктуру одной командой terragrunt run-all:

cd dev terragrunt run-all apply -auto-approve --terragrunt-non-interactive

Если вы хотите отладить и создать инфраструктуру вручную, необходимо закомментировать remote_state в корневом terragrunt.hcl

Настройка в gitlab ci для запуска и сохранения terraform lock и state в gitlab

Создайте Project access token с именем GITLAB_ACCESS_TOKEN согласно инструкции: Project access tokens

Чтобы передать Personal Access Token в переменную окружения GitLab откройте ваш проект, затем откройте Settings —> CI/CD и разверните Variables.

Создайте новую переменную окружения GITLAB_ACCESS_TOKEN и в качестве ее значения укажите содержимое Personal Access Token.

Для безопасности отметьте созданную переменную как protected.

Так же создайте новую переменную окружения YC_TOKEN и в качестве ее значения укажите содержимое OAuth-токена согласно инструкции: OAuth-токен

Для безопасности лучше использовать IAM-токен сервисного аккаунта.

Бекап terraform state из gitlab

curl --header "Content-Type: application/vnd.api+json" --header "Authorization: Bearer glpat-xxxx" \ https://gitlab.com/api/v4/projects/43542597/terraform/state/dev-group1-dns.tfstate

Где 43542597 — id проекта, dev-group1-dns.tfstate — название terraform state

Планы

  • Рассмотреть альтернативу terragrunt — Terramate
  • Рассмотреть использование Runatlantis


ссылка на оригинал статьи https://habr.com/ru/post/719994/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *