
Недавно мы в 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-репозитории. Воспользуемся последним вариантом, так как для него можно настроить автоматический перезапуск контейнеров в случае обновления.
Нажимаем кнопку 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, чтобы получить промокод.