Привет всем читающим. Меня зовут Данил, я DevOps-инженер компании Nixys.

В современных условиях бизнеса компании всё чаще сталкиваются с необходимостью быстрой развёртки и управления различными облачными окружениями. Нередко заказчики ставят задачу развернуть типовые окружения в облаке в сжатые сроки. Как-то раз и к нам обратились с подобным запросом.

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

В таких ситуациях традиционные методы могут оказаться недостаточно эффективными, и тогда на помощь приходят инфраструктурные инструменты как код (IaC) — например, Terraform.

Как мы пришли к написанию собственных Terraform-ролей

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

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

Просим любить и пользоваться — nxs-marketplace-terraform.

Какими подходами мы пользуемся и почему

S3 хранилище как хранилище tfstate

Когда мы работаем с Terraform для управления инфраструктурой, крайне важно сохранять состояние (state) этой инфраструктуры. Его содержит файл состояния (terraform.tfstate), который используется Terraform'ом для отслеживания изменений и управления ресурсами.

Хранение состояния (tfstate) в Terraform бывает нескольких видов:

  1. Локальное хранение: файл состояния сохраняется на локальной машине. Это простой способ для небольших проектов и разработок, но он не подходит для командной работы из-за риска потери данных.

  2. Удаленное хранилище: используется для централизованного управления состоянием, что особенно важно для команд. Поддерживаются различные бекенды, такие как S3, Consul и Terraform Cloud.

  3. S3: облачные хранилища часто используется для хранения tfstate из-за их надёжности и возможности легко настраивать блокировки с помощью DynamoDB, предотвращая конфликты в состоянии.

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

Если файл состояния хранится локально, это создает несколько проблем:

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

  • Риск потери данных: локально сохранённый файл состояния может быть случайно удалён или повреждён, что приведёт к потере критически важной информации об инфраструктуре.

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

Для решения этих проблем используется удалённое хранилище состояния (Remote State). Оно обеспечивает централизованное, доступное и надёжное хранение файла состояния для всех членов команды.

Terraform предоставляет механизм Remote Backend, который позволяет хранить состояние в удалённых системах хранения. Remote Backend решает следующие задачи:

  • Централизованное хранение. Состояние инфраструктуры хранится в одном месте, доступном для всех членов команды.

  • Безопасность. Удалённые хранилища часто предлагают возможности для шифрования данных и управления доступом.

  • Скалируемость. Удалённые хранилища могут обрабатывать большие объёмы данных и множество операций параллельно.

Terraform поддерживает различные типы удалённых хранилищ, включая AWS S3, Google Cloud Storage, Azure Blob Storage и другие.

Почему рекомендуется использовать S3, а не git

Использование git для хранения состояния может привести к нескольким проблемам:

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

  • Ограниченная безопасность. Хранение файлов состояния в git-репозитории требует дополнительных усилий для обеспечения их безопасности и конфиденциальности.

  • Отсутствие версионности состояния. Хотя git предоставляет контроль версий для исходного кода, он не оптимизирован для хранения и управления файлами состояния инфраструктуры.

В свою очередь S3-хранилища хорошо подходят для хранения состояния Terraform. И вот почему:

  • Постоянная доступность: S3 обеспечивает высокую доступность и отказоустойчивость данных, что критически важно для файлов состояния.

  • Версионность: S3 поддерживает версионность объектов, что позволяет отслеживать и восстанавливать предыдущие версии файлов состояния.

  • Шифрование и безопасность: S3 предлагает встроенные механизмы шифрования данных как на уровне хранения, так и на уровне передачи, а также возможности управления доступом с помощью Identity and Access Management (IAM).

  • Скорость и масштабируемость: S3 оптимизировано для быстрой и масштабируемой работы с большими объемами данных, что делает его более подходящим для хранения файлов состояния, чем git.

Динамические блоки

Давайте вначале разберемся, что это и зачем это использовать.

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

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

Какие бенефиты приносят динамические блоки

Использование динамических блоков в Terraform имеет множество преимуществ:

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

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

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

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

  5. Примеры использования:

    • Управление набором ресурсов с одинаковыми настройками, например, виртуальными машинами, базами данных или сетевыми ресурсами.

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

Пример динамического блока в Terraform

Для иллюстрации приведем пример использования динамического блока для создания множества виртуальных машин с разными параметрами:

variable "instances" {
  type = list(object({
    name = string
    size = string
  }))
  default = [
    { name = "vm1", size = "small" },
    { name = "vm2", size = "medium" },
    { name = "vm3", size = "large" }
  ]
}

resource "aws_instance" "example" {
  for_each = { for instance in var.instances : instance.name => instance }

  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = each.value.size

  tags = {
    Name = each.value.name
  }
}

В этом примере переменная instances содержит список конфигураций для виртуальных машин. Динамический блок for_each используется для создания ресурсов aws_instance для каждой виртуальной машины в списке. Это позволяет легко добавлять или удалять машины, изменяя только переменнуюinstances.

Особенности работы в РФ

Ни для кого не секрет HashiCorp, разработчик Terraform, ограничил доступ к своим сервисам для пользователей из России. Это создает определённые сложности в использовании Terraform для управления своей инфраструктурой. Однако есть альтернативные способы продолжать использование Terraform, обходя эти ограничения. Одним из таких способов является использование зеркала Terraform на Яндексе.

Яндекс предоставляет зеркало официального репозитория HashiCorp, что позволяет скачивать и обновлять Terraform даже при ограничениях доступа.

Если для запуска ваших Terraform модулей вы используете Gitlab-CI, то использовать зеркало можно просто добавив в before_scipt следующее:

before_script:
  - |
    cat << EOF > ~/.terraformrc
    provider_installation {
      network_mirror {
        url = "https://terraform-mirror.yandexcloud.net/"
        include = ["registry.terraform.io/*/*"]
      }
      direct {
        exclude = ["registry.terraform.io/*/*"]
      }
    }
    EOF

При этом в вашем versions.tf могут использоваться оригинальные источники с hashicorp.

Если вы запускаете ваши модули мануально, то использовать зеркала Yandex можно вот так: 

terraform {
  required_version = ">= v1.0.0"

  backend "http" {}

  required_providers {
    template = {
      source = "terraform-registry.storage.yandexcloud.net/hashicorp/template"
      version = "= 2.2.0" 
    }
    helm = {
      source = "terraform-registry.storage.yandexcloud.net/hashicorp/helm"
      version = "= 2.4.1"
    }
  }
}

А теперь перейдём к практике.

Практическая часть: развертываем Terraform-модули в Yandex Cloud

Давайте рассмотрим процесс развертывания инфраструктуры в Yandex Cloud с использованием Terraform-модулей из репозитория nixys/nxs-marketplace-terraform. Мы будем развертывать S3-бакет и Managed Kubernetes с worker-нодами.

Предварительный этап: Получение доступов для работы с Yandex Cloud

Перед началом работы необходимо выполнить следующие шаги для получения доступов к Yandex Cloud:

  1. Создание сервисного аккаунта и ключа доступа:

В консоли управления Yandex Cloud, создайте сервисный аккаунт и назначьте ему необходимые роли (например, storage.admin, editor, viewer).

Сгенерируйте ключ доступа (IAM key) для сервисного аккаунта. Этот ключ будет использоваться для аутентификации при работе с Terraform.

  1. Установка Yandex CLI:

Установите Yandex CLI (yc) и выполните аутентификацию.

curl -sSL https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
yc init
  1. Экспорт переменных окружения:

Экспортируйте переменные окружения с данными для аутентификации.

export YC_SERVICE_ACCOUNT_KEY_FILE=<path_to_service_account_key>
export YC_CLOUD_ID=<your_cloud_id>
export YC_FOLDER_ID=<your_folder_id>

Разворачивание S3 через Terraform модуль

Для развертывания S3-бакета используем модуль YandexCloud/Storage/buckets.

Создайте рабочую директорию и инициализируйте проект:

mkdir terraform-yc-storage
cd terraform-yc-storage
terraform init

Создайте файл main.tf и добавьте конфигурацию для S3-бакета:

module "yc_storage_buckets" {
  source = "github.com/nixys/nxs-marketplace-terraform//YandexCloud/Storage/buckets?ref=main"

  yc_cloud_id    = var.yc_cloud_id
  yc_folder_id   = var.yc_folder_id
  yc_sa_key_file = var.yc_sa_key_file

  buckets = [
    {
      name        = "my-tfstate-bucket"
      access_key  = var.access_key
      secret_key  = var.secret_key
    }
  ]
}

Создайте файл variables.tf для определения переменных:

variable "yc_cloud_id" {}
variable "yc_folder_id" {}
variable "yc_sa_key_file" {}
variable "access_key" {}
variable "secret_key" {}

Создайте файл terraform.tfvars и задайте значения переменных:

yc_cloud_id    = "<your_cloud_id>"
yc_folder_id   = "<your_folder_id>"
yc_sa_key_file = "<path_to_service_account_key>"
access_key     = "<your_access_key>"
secret_key     = "<your_secret_key>"

Запустите Terraform для развертывания S3-бакета:

terraform apply

Почему nxs-marketplace-terraform

Использование nxs-marketplace-terraform имеет множество преимуществ, которые делают управление инфраструктурой более эффективным. Вот основные из них:

Готовые протестированные роли

  • Надёжность и проверка: все роли и модули, предоставляемые в nxs-marketplace-terraform, тщательно протестированы. Мы сами используем их в работе на реальных проектах.

  • Снижение рисков: использование проверенных ролей снизит вероятность ошибок и упростит процесс развёртывания и управления инфраструктурой. Меньше ошибок — меньше простоев.

Единый стиль

  • Унифицированный подход: все модули и роли мы разработали в едином стиле, чтобы всем было проще их понимать и ими пользоваться. Например, в случае смены облачного провайдера вам не придётся разбираться с новыми подходами и переписывать конфигурации с нуля.

  • Снижение затрат времени: унифицированный стиль позволит команде быстрее адаптироваться к новому окружению и эффективней управлять инфраструктурой независимо от используемого облачного провайдера.

Постоянные обновления и улучшения

  • Актуальность: мы постоянно следим за новыми тенденциями в мире облачных технологий. Поэтому все модули регулярно обновляются, чтобы соответствовать последним стандартам и лучшим практикам.

  • Поддержка сообщества: будем рады увидеть вас среди участников проекта! Чем больше людей будут предлагать свои улучшения и сообщать о найденных проблемах, тем быстрее nxs-marketplace-terraform станет ещё удобнее и полезнее.

nxs-marketplace-terraform упростит и ускорит вашу работу. Следите за обновлениями и присоединяйтесь к сообществу пользователей, чтобы извлечь максимум пользы из этого инструмента. Будем ждать вас :)

Заключение

В этой статье мы рассмотрели, как с помощью Terraform-ролей настроить и развернуть различные компоненты в Yandex Cloud, включая S3-хранилище, Managed Kubernetes и Managed PostgreSQL. Кроме того, мы обсудили важность правильного хранения состояния Terraform (tfstate) и преимущества использования удалённых хранилищ, таких как S3.

Применение готовых и протестированных ролей из nxs-marketplace-terraform позволяет значительно упростить процесс развертывания, сократить риски и обеспечить надежность инфраструктуры. Единый стиль модулей обеспечивает легкость в понимании и адаптации к новым облачным провайдерам, а регулярные обновления и поддержка сообщества гарантируют актуальность и улучшение инструментов.

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

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

Не забывайте следить за обновлениями и участвовать в сообществе пользователей nxs-marketplace-terraform, чтобы извлечь максимум пользы из этого мощного инструмента. А ещё подписывайтесь на наши соц.сети: соцсети: Telegramvc.ru и YouTube. Везде публикуется разный контент.

Комментарии (1)


  1. slisli
    21.07.2024 10:21

    Как минимум неудобно, и даже опасно ссылаться на модуль по имени ветки. А теги в репозитории одни сразу на все модули. Если будут несовместимые изменения в одном модуле, то будет не очень удобно.