В этом посте:
- Использование 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 на будущее. Антон Бабенко (2018г)
- Что такое модули Terraform и как они работают?
- Паттерны модулей Terraform
- Как мы переложили управление инфраструктурой на Terraform — и начали жить
Будут использоваться модули:
- github.com/patsevanton/terraform-yandex-dns.git
- github.com/patsevanton/terraform-yandex-vpc-address.git
Организуем структуру каталогов с terraform модулями для terragrunt согласно вашей инфраструктуре
Можно использовать terraform модули с чистым terraform, но c terragrunt это будет удобнее:
- Код будет компактнее, а значит читабельнее
- Структура каталогов отражает то, как организована ваша инфраструктура.
- Можно создать/обновить/удалить инфраструктуру одной командой
- Можно периодически запускать plan и проверять изменилось что-нибудь
Посты про terragrunt:
- Компоновка кода Terraform и использование Terragrunt
- Миграция с Terraform на Terragrunt
- Terraform 12 и Terragrunt и как это можно применять для Multi-Cloud-инфраструктуры. Александр Довнар
- AWS Meetup Terraform & Terragrunt. Антон Бабенко (2020)
Будет рассматриваться репозиторий 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/
Добавить комментарий