Недавно мы в Selectel выпустили новую версию собственного Terraform-провайдера, в которую добавили ресурс для управления выделенными серверами. Теперь при работе с физическими машинами можно использовать все преимущества IaC и управлять гибридной инфраструктурой из единой точки.

Привет, Хабр! Меня зовут Наталья Белоусова, я технический менеджер в отделе развития выделенных серверов Selectel. В этой статье расскажу, как использовать обновленный Terraform при работе с нашими продуктами, и разберу реальный кейс. Материал будет полезен системным администраторам, DevOps-инженерам и разработчикам. Подробности под катом!

Внимание! Материал написан для специалистов, которые умеют работать с Terraform на базовом уровне. Если вы в их числе, рекомендуем начать с основ. 

Возможности Terraform-провайдера

Как мы знаем, Terraform — довольно популярный инструмент для автоматизации управления инфраструктурой в соответствии с методологией Infrastructure-as-a-code, IaaC. Но зачастую в реальном проекте нужно не просто создать сервер, а решить куда больше технических и административных задач. И чем больше процессов автоматизировано, тем меньше ручных действий, которые могут приводить к проблемам. 

Ресурсы нашего Terraform-провайдера позволяют автоматизировать решение множества задач.

  • Управление политиками доступа. Вы можете настроить процессы таким образом, чтобы при добавлении сотрудника в вашей внутренней системе учета автоматически создавался пользователь с соответствующими ролями.

  • Развертывание тестового окружения. Terraform позволяет организовать пайплайн для запуска тестового окружения «по кнопке» и удаления по завершении тестов.

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

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

Сегодня с помощью ресурса и источников данных Terraform для выделенных серверов можно заказывать серверы фиксированной конфигурации, устанавливать ОС из доступных образов или выбрать No OS для самостоятельной установки и гибко управлять ее параметрами. А также — настраивать сети на сервере и автоматически подбирать конфигурации, локации и ОС под заданные параметры (тестовый режим).

Разворачиваем сервер с n8n для автоматизации бизнес-процессов

Давайте рассмотрим пример развертывания инфраструктуры на выделенном сервере. С созданием проекта, пользователя и настройки доступа к серверу по доменному имени — с помощью комбинации ресурсов Terraform-провайдера Selectel.

Итак, нам понадобится отдельный проект и сервисный пользователь с доступом только к управлению ресурсами внутри проекта. Доступ на сервер будет осуществляться с помощью SSH-ключа, диски будут собраны в RAID1 для большей надежности, а после установки сервис должен быть доступен по домену. 

Настройка провайдера

Для работы с выделенными серверами нам потребуется версия 7.1.0 или выше.

terraform {
  required_providers {
    selectel = {
      source = "selectel/selectel"
      version = "7.1.0"
    }
  }
}

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

1. Перейдите в панель управления и создайте сервисного пользователя с ролью member уровня доступа Аккаунт и iam_admin в разделе Аккаунт → Сервисные пользователи

2. Добавьте в конфигурационный файл параметры для авторизации:

provider "selectel" {
 domain_name = "123456"
 username    = "user"
 password    = "password"
 auth_region = "ru-9"
 auth_url    = "https://cloud.api.selcloud.ru/identity/v3/"
}

Здесь domain_name это ID вашего аккаунта, а username и password данные от созданного сервисного пользователя. 

3. Рекомендуем использовать наше зеркало для доступа к провайдеру. Создайте отдельный конфигурационный файл Terraform CLI и добавьте в него такой блок:

provider_installation {
 network_mirror {
   url     = "https://tf-proxy.selectel.ru/mirror/v1/"
   include = ["registry.terraform.io/*/*"]
 }
 direct {
   exclude = ["registry.terraform.io/*/*"]
 }
}

4. После инициализируйте провайдер:

$ terraform init 

В случае успеха вы увидите такую картину:

Создание проекта и пользователя

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

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

1. Создаем проект:

resource "selectel_vpc_project_v2" "project_1" {
 name = "new-terraform-project"
}

В значении параметра name указываем произвольное имя проекта.

2. Создаем сервисного пользователя с ролью member в области доступа «Проект»:

resource "selectel_iam_serviceuser_v1" "serviceuser_1" {
 name         = "username"
 password     = "password"
 role {
   role_name  = "member"
   scope      = "project"
   project_id = selectel_vpc_project_v2.project_1.id
 }
}

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

Мы также можем сохранить username и password в отдельном файле tfvars. Так, можно создать сразу несколько пользователей в одном проекте или добавить их позже.

3. Проверяем, что все хорошо:

$ terraform plan 

4. Выполняем команду:

$ terraform apply 

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

Создание сервера

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

Минимально необходимый набор параметров для создания сервера включает project_id, location_id, configuration_id, os_id и price_plan_name.

project_id

Это ID проекта, в котором будет создан сервер. Мы будем использовать созданный в предыдущем блоке проект, однако в панели управления значение можно задать вручную, перейдя в разделе Продукты → Серверы и оборудование и скопировав идентификатор проекта.

location_id

Это уникальный ID конфигурации. Мы будем использовать data source для получения ID по названию пула из матрицы доступности.

data "selectel_dedicated_location_v1" "server_location" {
  project_id = selectel_vpc_project_v2.project_1.id
  filter {
    name = "SPB-2"
  }
}

configuration_id

Это уникальный ID конфигурации. Мы будем использовать data source для получения ID по параметрам. Выбрать подходящий сервер можно также на сайте или странице заказа выделенного сервера в панели управления.

Например, нужно найти все доступные к заказу конфигурации с одной видеокартой. Для этого в фильтре указываем:

data "selectel_dedicated_configuration_v1" "server_config" {
  project_id = "d21ffe60f6a14322ad5236e1ba96b108"
  deep_filter = <<EOT
    {
        "gpu": {
           "count": 1
        },
        "state": "Active",
        "is_manual_erase": false
    }
  EOT
}

И добавляем в файл манифеста вывод полученной в фильтре информации:

output “available_configs” { 
  value = data.selectel_dedicated_configuration_v1.server_config.configurations
}

Выполняем команду:

$ terraform plan 

В выводе получаем список подходящих конфигураций и их ID.

Узнать подробную информацию о конфигурации можно запросом в API, указав ее ID:

$ curl https://api.selectel.ru/servers/v2/pub/service/e5488288-0202-4825-a1b6-4f8f0844944e | jq 

Найдем в полученном ответе информацию о стоимости конфигурации: 

$ curl https://api.selectel.ru/servers/v2/pub/service/e5488288-0202-4825-a1b6-4f8f0844944e | jq | grep -v location_price_collection | grep price_collection -A6 | tail -n

Подробнее о том, как работать с API выделенных серверов Selectel, мы рассказали в отдельной статье.

После выбора конфигурации указываем ее имя в параметрах фильтра:

data "selectel_dedicated_configuration_v1" "server_config" {
  project_id = selectel_vpc_project_v2.project_1.id
  deep_filter = <<EOT
    {
       "name": "CL25-SSD"
    }
  EOT
}

Блок outputs “available_configs” на этом этапе можно удалить из манифеста. 

os_id 

Это уникальный ID ОС для установки на сервер. Будем использовать data source для фильтрации доступных для выбранной конфигурации и локации ОС.

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

Получить список доступных ОС можно следующим образом: 

data "selectel_dedicated_os_v1" "server_os" {
  project_id = selectel_vpc_project_v2.project_1.id
  filter {
    configuration_id = data.selectel_dedicated_configuration_v1.server_config.configurations[0].id
    location_id      = data.selectel_dedicated_location_v1.server_location.locations[0].id
  }
}

output “available_os” { 
  value = data.selectel_dedicated_os_v1.server_os.os
}

В выводе получаем список образов и доступные для них параметры 

На официальном сайте рекомендуется деплоить n8n с помощью Docker. Воспользуемся готовым образом Container Ready, который автоматически развернет еще и Portainer для более удобного управления контейнерами через веб-интерфейс. Ознакомиться с другими доступными образами с уже установленным ПО можно в нашей документации.

data "selectel_dedicated_os_v1" "server_os" {
  project_id = selectel_vpc_project_v2.project_1.id
  filter {
    name             = "Pre-installed Apps"
    version_name          = "Container Ready"
    configuration_id = data.selectel_dedicated_configuration_v1.server_config.configurations[0].id
    location_id      = data.selectel_dedicated_location_v1.server_location.locations[0].id
  }
}

name — семейство ОС (Ubuntu, Debian, Windows etc).

version_name — позволяет находить нужный образ по частичному названию образа.

price_plan_name

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

$ curl -H “Accept-Language: en-US” https://api.selectel.org/servers/v2/pub/plan | jq | grep name

Ресурс для создания сервера

Используем полученные ранее данные для создания ресурса:

resource "selectel_dedicated_server_v1" "server_1" {
  project_id = selectel_vpc_project_v2.project_1.id
  configuration_id = data.selectel_dedicated_configuration_v1.server_config.configurations[0].id
  location_id      = data.selectel_dedicated_location_v1.server_location.locations[0].id
  os_id = data.selectel_dedicated_os_v1.server_os.os[0].id
  price_plan_name  = "1 day"
}

Проверяем, что все хорошо, с помощью команды:

$ terraform plan

В целом мы можем создать сервер уже сейчас:

$ terraform apply

В зависимости от выбранной ОС, объема дисков и параметров, например партиций, создание сервера может занимать от 5 до 30 минут. Если в течение этого времени процесс не завершился, рекомендуем обратиться в поддержку.

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

Дополнительные параметры ОС

Добавление SSH-ключа

Чтобы после установки ОС иметь доступ к серверу с помощью SSH-ключа, достаточно указать его следующим образом:

ssh_key = “%ваш ключ%”

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

ssh_key_name = “my-key”

Разбивка дисков

Данный параметр возможен только для ОС семейства Linux. При этом, если в сервере есть два диска одинакового размера, они будут собраны в RAID1 по умолчанию — задавать дополнительные параметры не потребуется.

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

Запускаем контейнер с помощью user-data   

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

Документация по использованию user-data для Container Ready доступна нашем сайте. 

Для запуска контейнера с n8n сразу при создании сервера передадим данные для docker-compose.yaml с помощью cloud-init в user-data.

1. Создадим файл init.sh:

#cloud-config

write_files:
 - path: "/opt/containers/docker-compose.yaml"
   permissions: "0644"
   content: |
     version: "3.9"
     services:
       n8n:
         image: n8nio/n8n:latest
         container_name: n8n
         environment:
          - NODE_ENV=production
         ports:
          - "5678:5678"
         volumes:
           - ~/.n8n:/home/node/.n8n
         restart: unless-stopped

2. Укажем путь до файла в значении параметра user-data:

user-data = “/path-to-folder/init.sh”м
Полный код манифеста

data "selectel_dedicated_configuration_v1" "server_config" {

  project_id = selectel_vpc_project_v2.project_1.id

  deep_filter = <<EOT

    {

       "name": "EL50-SSD"

    }

  EOT

}

data "selectel_dedicated_location_v1" "server_location" {

  project_id = selectel_vpc_project_v2.project_1.id

  filter {

    name = "SPB-2"

  }

}

data "selectel_dedicated_os_v1" "server_os" {

  project_id = selectel_vpc_project_v2.project_1.id

  filter {

    name            = "Pre-installed Apps"

    version_name    = "Container Ready"

    configuration_id = data.selectel_dedicated_configuration_v1.server_config.configurations[0].id

  }

}

resource "selectel_dedicated_server_v1" "server_1" {

  project_id = selectel_vpc_project_v2.project_1.id

  configuration_id = data.selectel_dedicated_configuration_v1.server_config.configurations[0].id

  location_id      = data.selectel_dedicated_location_v1.server_location.locations[0].id

   os_id = data.selectel_dedicated_os_v1.server_os.os[0].id

  os_host_name = "n8n-dev"

  ssh_key = “%ваш_ключ%”

  price_plan_name  = "1 day"

  user_data = file("init.sh")

}

Отлично — можно выполнить терраформ apply. Установка сервера может занимать от 5 до 30 минут в зависимости от выбранного образа, размера и разбивки дисков. 

В случае успешного создания сервера в выводе в консоли будет информация о завершении установки и ID сервера. 

По завершении установки n8n будет доступен по адресу http://server-ip:5678 — можно приступать к настройке ваших агентов. Может потребоваться еще некоторое время после сдачи сервера до запуска контейнера.

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

Убедимся, что в панели Portainer все работает корректно. 

Управление контейнерами в Portainer

Логин для авторизации – admin.  Также потребуется пароль root, который был создан при установке. Узнать его можно в разделе Серверы и оборудованиеСерверы → карточка сервера → вкладка Операционная система. Пароль будет доступен для просмотра в течение 24 часов после установки ОС. Рекомендуем изменить его на свой после первой авторизации. Portainer работает по адресу http://ip_сервера:9000 

Чтобы увидеть запущенные контейнеры, перейдем на вкладку Home →  Stacks в левом меню:

На открывшейся странице видим список всех запущенных «стаков». Stacks — это запущенные Docker Compose, в которых может быть как один контейнер (как в нашем примере ранее), так и сразу несколько. Например, сайт + БД + Redis и так далее. 

Теперь добавим еще один сервис. 

Portainer позволяет запускать контейнеры из файлов compose, созданных в веб-редакторе панели, загруженных с локального устройства, и размещенных в git-репозитории. Воспользуемся последним вариантом, так как для него можно настроить автоматический перезапуск контейнеров в случае обновления. 

  1. Нажимаем кнопку Add stack и переходим во вкладку repositories. Заполняем поля: ссылку на репозиторий и путь к файлу docker-compose.yaml

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

2. Ниже есть блок для настройки переменных окружения — если файл .env отсутствует в репозитории, вы можете создать его в веб-интерфейсе или загрузить с локального устройства. 

3. Нажимаем кнопку Deploy Stack. При успешном деплое у нас откроется вкладка со стеками. 

4. Открываем стек с нашим приложением. Включаем опцию GitOps uptades и настраиваем необходимые параметры. 

  • Mechanism — способ проверки изменений: Polling — Portainer будет самостоятельно проверять изменения исходя из установленной частоты проверки; Webhook — инициализация проверки изменений при отправке запроса на указанный URL. Удобно для CI/CD.

  • Fetch interval — актуален для механизма Polling. Устанавливает частоту проверки репозитория на наличие изменений. По умолчанию установлено пять минут.

5. Сохраняем настройки. 

Вывод: с помощью Portainer можно легко запускать контейнеры для продакшен-версий приложений с автообновлением и быстро создавать тестовые окружения с помощью редактора в браузере или загрузки файла с локального устройства.  

Подключение присвоенного IP к домену

Итак, наш сервер готов, а приложение запущено. Следующая задача — настроить доступность приложения по доменному имени. Если домен зарегистрирован не в Selectel, в панели регистратора укажите наши DNS-серверы.

1. Создаем зону домена:

resource "selectel_domains_zone_v2" "zone_1" {
 name       = "example.com."
 project_id = selectel_vpc_project_v2.project_1.id
}

2. Добавляем А-запись, которая будет указывать на IP созданного сервера:

resource "selectel_domains_rrset_v2" "a_rrset_1" {
 zone_id    = selectel_domains_zone_v2.zone_1.id
 name       = selectel_domains_zone_v2.zone_1.name
 type       = "A"
 ttl        = 60
 project_id = selectel_vpc_project_v2.project_1.id
 records {
   content = "IP_сервера”
 }

3. В значении параметра content укажите IP-адрес сервера — его можно найти в панели управления в разделе Серверы и оборудованиеСерверы → карточка сервера.

4. Проверяем и отображаем все предстоящие изменения в инфраструктуре и применяем их:

terraform plan
terraform apply

5. Чтобы убедиться, что запись добавилась корректно, выполним команду:

dig example.com @ns1.selectel.ru 

Заключение

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

Собственный сервер Selectel

В основе — самые современные процессоры Intel® Xeon® 6, до 8 ТБ DDR5 и специально разработанная материнская плата. Арендуйте сервер у нас или закажите в свой дата-центр.

Узнать подробности →

Хотите протестировать Terraform в выделенных серверах? Зарегистрируйтесь в панели управления и напишите в поддержку сообщение с кодовым словом Terraform, чтобы получить промокод. 

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