Как работать с Terraform на выделенных серверах
Подробная инструкция для новичков. Разберем, как скачать и установить Terraform, а затем настроить сервер.
Мне давно хотелось протестировать Terraform, но не в привычной среде с виртуальными машинами, а на Bare Metal. В этой инструкции хочу поделиться опытом, как я это сделал. Разберу процесс в деталях: от установки Terraform до создания выделенного сервера.
Подготовка к работе и установка Terraform
Текст подготовил автор Telegram-канала BashDays специально для Академии Selectel.
Перед началом работы определимся с планом.
- Установим Terraform на свою машину.
- Создадим сервисного пользователя.
- Раскатаем железный сервер.
- А дальше будет видно…
План есть, можно переходить к работе. И первым делом установим Terraform. Я возьму чистую Linux-машину с серверной Ubuntu 22.04. Это будет мой центр управления, на ней я буду запускать Terraform-команды.
Terraform сейчас можно установить при помощи разных инструментов — вы можете выбрать любой. Я же обращаюсь к официальной документации:
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
И скачиваю бинарный файл с официального сайта:
https://releases.hashicorp.com/terraform/1.13.3/terraform_1.13.3_linux_amd64.zip \
&& unzip terraform_1.13.3_linux_amd64.zip \
&& sudo mv terraform /usr/local/bin/ \
&& rm terraform_1.13.3_linux_amd64.zip
Проверяем, что Terraform установился:
terraform --version

Хорошо. Начало заложено. Чтобы взаимодействовать с ресурсами Selectel, нужно создать сервисного пользователя. Для этого нужно зарегистрироваться или авторизоваться в панели управления.
Создаем сервисного пользователя
В панели управления переходим в Аккаунт → Сервисные пользователи.

Заполняем поля, выдаем необходимые права, сохраняем. Готово!

Пользователь есть. Приступаем к созданию проекта.
Создаем проект
На локальной машине создаем папку ~/terraform/vds, а в ней — пару файлов: vds.tf и prodiver.tf:
mkdir ~/terraform/vds
cd ~/terrarom/vds
touch vds.tf prodiver.tf
Должна получиться такая структура:

Заполняем файл provider.tf согласно официальной документации:
terraform {
required_providers {
selectel = {
source = "selectel/selectel"
version = "~> 7.0.2-preview"
}
}
}
И делаем первичную инициализацию проекта. В консоли запускаем:
terraform init
И получаем ошибку:

В этом нет ничего страшного, я покажу, как ее исправить. В домашней папке пользователя создаем файл .terraformrc и пропишем в нем:
provider_installation {
network_mirror {
url = "https://tf-proxy.selectel.ru/mirror/v1/"
include = ["registry.terraform.io/*/*"]
}
direct {
exclude = ["registry.terraform.io/*/*"]
}
}
Здесь мы сообщаем Terraform, чтобы он использовал серверы Selectel.
На этом же этапе можно увидеть другую ошибку, если «затянуть» не 7.0.2-preview, а какую-нибудь альфа-версию.

Решается это удалением папки .terraform и повторной инициализацией.
Итак, инициализация прошла успешно. В корневой папке проекта появились еще одна папка .terraform и файл .terraform.lock.hcl:

Файл .terraform.lock.hcl используется Terraform для управления зависимостями провайдеров и их версиями. Он автоматически генерируется и обновляется при выполнении команд, таких как terraform init.
Подключаем провайдер Selectel
Добавляем в файл настройки для провайдера, должно получиться так:
terraform {
required_providers {
selectel = {
source = "selectel/selectel"
version = "~> 7.0.2-preview"
}
}
}
provider "selectel" {
auth_region = "ru-9"
auth_url = "https://cloud.api.selcloud.ru/identity/v3/"
domain_name = "322222"
username = "terraform"
password = "password"
}
Auth_region — это тот самый пул-регион, в котором находится сервис аутентификации. Регионы можно посмотреть в матрице доступности.

Auth_url — эндпоинт, по которому Terraform будет обращаться для аутентификации.
Domain_name — идентификатор вашего аккаунта, его можно посмотреть в правом верхнем углу панели управления Selectel.
Username — имя сервисного пользователя.
Password — пароль сервисного пользователя.
Проверяем:
terraform init
terraform plan
Отлично, все успешно подключилось:

Теперь давайте получим список готовых конфигураций и другую вводную информацию. Создадим временный файл services.tf с содержимым:
resource "selectel_vpc_project_v2" "project_1" {
name = "terraform-demo-project"
}
data "selectel_dedicated_configuration_v1" "server_config" {
project_id = selectel_vpc_project_v2.project_1.id
}
output "dedicated_configurations" {
value = data.selectel_dedicated_configuration_v1.server_config.configurations
}
Это сперва создаст проект и затем выведет все доступные в нем конфигурации:

А в консоли будет так:

Отлично! Нас интересуют поля name, из них мы в дальнейшем возьмем имя готовой конфигурации и на основе его создадим выделенный сервер.
Теперь получим список локаций. Обновляем файл services.tf:
resource "selectel_vpc_project_v2" "project_1" {
name = "terraform-demo-project"
}
# Получаем конфигурации
data "selectel_dedicated_configuration_v1" "server_config" {
project_id = selectel_vpc_project_v2.project_1.id
}
output "dedicated_configurations" {
value = data.selectel_dedicated_configuration_v1.server_config.configurations
}
# Получаем локации
data "selectel_dedicated_location_v1" "server_location" {
project_id = selectel_vpc_project_v2.project_1.id
}
output "dedicated_locations" {
value = data.selectel_dedicated_location_v1.server_location.locations
}
Запускаем и получаем список локаций:

Ну и далее запрашиваем список доступных операционных систем. Модифицируем файл services.tf:
# Создаем проект, если его нет
resource "selectel_vpc_project_v2" "project_1" {
name = "terraform-demo-project"
}
# Получаем конфигурации серверов
data "selectel_dedicated_configuration_v1" "server_config" {
project_id = selectel_vpc_project_v2.project_1.id
}
# Получаем список локаций
data "selectel_dedicated_location_v1" "server_location" {
project_id = selectel_vpc_project_v2.project_1.id
}
# Получаем все доступные операционные системы
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 "dedicated_configurations" {
value = data.selectel_dedicated_configuration_v1.server_config.configurations
}
output "dedicated_locations" {
value = data.selectel_dedicated_location_v1.server_location.locations
}
output "dedicated_os" {
value = data.selectel_dedicated_os_v1.server_os.os
}
В ответ получаем список ОС, которые доступны для установки:

Первичных вводных пока достаточно. Теперь создадим сервер.
Комментируем все в файле services.tf, чтобы не мешало, и чистим тестовый проект:
terraform apply
Проект terraform-demo-project будет удален.
Создаем еще один файл data.tf — в него запишем параметры, с которыми будет создан выделенный сервер.
Все необходимые параметры мы получили выше. Выбирайте те, что подходят под ваши задачи:
data "selectel_dedicated_configuration_v1" "server_config" {
project_id = selectel_vpc_project_v2.project_1.id
deep_filter = "{\"name\":\"AEL10-SSD\"}"
}
data "selectel_dedicated_location_v1" "server_location" {
project_id = selectel_vpc_project_v2.project_1.id
filter {
name = "SPB-3"
}
}
data "selectel_dedicated_os_v1" "server_os" {
project_id = selectel_vpc_project_v2.project_1.id
filter {
name = "SelectOS"
version = "1"
}
}
Здесь я выбрал сервер AEL10-SSD. Его можно найти в панели управления:

Доступные параметры можно посмотреть также в панели управления.
В файл vds.tf пишем:
resource "selectel_vpc_project_v2" "project_1" {
name = "vds-server"
}
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 день"
}
- project_id — уникальный идентификатор связанного проекта.
- configuration_id — уникальный идентификатор конфигурации сервера.
- location_id— пул, в котором находится сервер.
- location_id— пул, в котором находится сервер.
- os_id — уникальный идентификатор операционной системы для установки.
- price_plan_name — название тарифного плана.
Здесь меня заинтересовал параметр price_plan_name. Получается, можно создать выделенный сервер на какое-то время? Это было бы очень удобно. Представьте, у вас есть пайплайн на GitLab, который поднимает такой сервер раз в сутки на пару часов, собирает тяжелые билды и потом уничтожает сервер. В итоге не нужно арендовать железо на постоянной основе и ежемесячно его оплачивать.
Вернемся к параметру price_plan_name. Чтобы посмотреть его содержимое, придется воспользоваться API-запросами. Да, тут придется попотеть и получить токен через командную строку.
Ладно, нужно, так нужно. Очень велико желание узнать начинку price_plan_name. Вдруг и правда там есть почасовые тарифы.
Получаем токен для API-запросов
Готовим запрос и забираем токен. Не забываем в запрос подставить свои данные от сервисного аккаунта.
curl -i -XPOST \
-H 'Content-Type: application/json' \
-d '{"auth":{"identity":{"methods":["password"],"password":{"user":{"name":"terraform","domain":{"name":"123456"},"password":"my_password"}}},"scope":{"domain":{"name":"123456"}}}}' \
'https://cloud.api.selcloud.ru/identity/v3/auth/tokens' | grep x-subject-token
В ответ получаем длинную строчку — это и будет токен.
Получаем информацию о тарифных планах:
export SELECTE_TOKEN="123456789"
curl -X GET "https://api.selectel.ru/servers/v2/plan" -H "Content-Type: application/json" -H "X-Auth-Token:$SELECTEL_TOKEN"' | jq
А вот и тарифные планы price_plan_name:

На скриншоте небольшая часть, но уже видим, что есть план «1 час». А рядом “not_available_for_a_reason”: “unavailable”, видимо, тарифный план недоступен.
Кстати, для тех, кто не любит так усложнять: тарифные планы можно посмотреть и в панели для каждого отдельного сервера:

Все сходится.
Итак, один час недоступен, поэтому попробуем создать сервер на день:
terraform plan
terraform apply
Готово!


Подождем, когда сервер поднимется, а пока можем посмотреть его параметры:

Отлично! То, что мы и заказывали. Проверим еще, правильный ли тариф:

Все верно, сервер арендован на один день. Можно смело заниматься своими делами: собирать тяжелые билды и что-то тестировать.
Спустя 10 минут сервер успешно создан:


Видим, что сервер оплачен на один день. Попробуем к нему подключиться:
ssh root@84.38.186.250
Есть контакт. Проверяем ресурсы и ОС:



Ожидаемый результат. Теперь мы умеем арендовать железные серверы через Terraform. Поздравляю!