Terraform
Разворачивать облачную инфраструктуру в Selectel и управлять ей можно с помощью утилиты Terraform от HashiCorp.
Через Terraform можно работать с продуктами:
Инфраструктура и ее компоненты описываются на языке HashiCorp Configuration Language (HCL) в конфигурационных файлах с расширением .tf
— манифестах.
Для работы с услугами Selectel используется два Terraform-провайдера:
- OpenStack-провайдер (документация на Terraform Registry и GitHub) для управления ресурсами OpenStack, например облачными серверами, дисками, сетями;
- Selectel-провайдер (документация на Terraform Registry и GitHub), который взаимодействует с API Selectel, для управления проектами и квотами, пользователями, их ролями и токенами, DNS, кластерами и группами нод Managed Kubernetes, облачными базами данных.
Чтобы развернуть инфраструктуру через Terraform:
- Установите Terraform.
- Создайте манифест.
- Инициализируйте Terraform-провайдеры OpenStack и Selectel.
- Опционально: настройте хранение Terraform State в объектном хранилище.
- Составьте план инфраструктуры.
- Проверьте конфигурацию и разверните инфраструктуру.
Установить Terraform
Перед началом работы установите Terraform на облачном сервере или локальном компьютере.
Используйте инструкцию на официальном сайте Terraform в зависимости от операционной системы.
Создать манифест
План инфраструктуры описывается в манифестах — файлах с расширением .tf
.
При выполнении команды terraform apply
, которая создает инфраструктуру, Terraform загружает все манифесты, лежащие в одной директории — создаются все описанные ресурсы (resources). Файлы с описанием одной инфраструктуры должны находиться в отдельной директории.
Создайте директорию и файл внутри нее, например main.tf
. Файлы с описанием плана могут иметь любое название.
Настроить провайдеры
В манифесте нужно перечислить Terraform-провайдеры, необходимые для создания инфраструктуры. Обычно для работы используются два провайдера: Selectel (документация на Terraform Registry и GitHub) и OpenStack (документация на Terraform Registry и GitHub). В некоторых случаях требуется только OpenStack, например, если проект облачной платформы уже создан.
Добавьте в файл блок с описанием провайдеров:
terraform {
required_version = ">= 0.14.0"
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.49.0"
}
selectel = {
source = "selectel/selectel"
version = "~> 3.9.0"
}
}
}
Актуальные версии провайдеров (version
) можно найти в их документации (Selectel — на Terraform Registry и GitHub, OpenStack — на Terraform Registry и GitHub), нажав на кнопку USE PROVIDER.
Для авторизации OpenStack-провайдера добавьте в манифест:
provider "openstack" {
auth_url = "https://api.selvpc.ru/identity/v3"
domain_name = "<selectel_account>"
tenant_id = "<project_id>"
user_name = "<user_name>"
password = "<user_password>"
region = "<pool>"
}
Укажите:
<selectel_account>
— номер аккаунта Selectel (номер договора). Можно посмотреть в панели управления в правом верхнем углу;<project_id>
— ID проекта облачной платформы;<user_name>
— пользователь OpenStack, привязанный к проекту облачной платформы;<user_password>
— пароль пользователя OpenStack;<pool>
— пул, в котором будет развернута инфраструктура.
Для авторизации Selectel-провайдера:
provider "selectel" {
token = "<selectel_token>"
}
Укажите <selectel_token>
— токен аккаунта (ключ Selectel API), его можно получить по инструкции Ключи API.
Настроить хранение Terraform State
Terraform State (состояние Terraform) — это файл с расширением .tfstate
, который хранит описание развернутой инфраструктуры. Файл создается вместе с инфраструктурой и обновляется при ее изменении.
Terraform State можно хранить в объектном хранилище Selectel.
Добавьте блок
backend
в манифест:terraform {
required_version = ">= 0.14.0"
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.49.0"
}
selectel = {
source = "selectel/selectel"
version = "~> 3.9.0"
}
}
backend "s3" {
bucket = "<container_name>"
endpoint = "s3.<pool>.storage.secloud.ru"
key = "<file_name>.tfstate"
region = "<pool>"
skip_region_validation = true
skip_credentials_validation = true
access_key = "<key_id>"
secret_key = "<secret_key>"
}
}Укажите:
<pool>
— пул, в котором находится объектное хранилище (например, ru-1);<container_name>
— имя контейнера в объектном хранилище, в котором будет храниться файл с состоянием Terraform. Имя можно посмотреть в панели управления в разделе Объектное хранилище → Контейнеры;<file_name>
— имя файла с состоянием Terraform;<key_id>
— Access Key ID из S3-ключа, выданного пользователю;<secret_key>
— Secret Access Key из S3-ключа, выданного пользователю.
Составить план инфраструктуры
Составьте план инфраструктуры в файле с расширением .tf
. Вы можете:
- добавить описание ресурсов, используя документацию к Terraform-провайдерам (Selectel — на Terraform Registry и GitHub, OpenStack — на Terraform Registry и GitHub);
- или использовать примеры из GitHub-репозитория Selectel.
Ниже вы можете посмотреть пример манифеста для создания инфраструктуры.
Пример плана инфраструктуры
Применение этого плана создаст инфраструктуру в пуле ru-3, которая будет содержать:
- облачный сервер с загрузочным сетевым диском из образа Ubuntu 20.04 LTS 64-bit, с произвольной конфигурацией с 1 vCPU и 1 ГБ RAM. Все доступные типы конфигураций — в документации;
- приватную сеть с подсетью;
- облачный роутер, подключенный к внешней сети;
- публичный IP-адрес, привязанный к облачному серверу.
В примере используется проект Облачной платформы My First Project, который создается автоматически при регистрации аккаунта, также проект можно создать через Terraform.
План описан в двух файлах — main.tf
и vars.tf
. В первом хранится описание создаваемых ресурсов, во втором — объявлены переменные, которые могут переиспользоваться в main.tf
.
Файл vars.tf
# Пул Облачной платформы
variable "region" {
default = "ru-3"
}
# Значение SSH-ключа для доступа к облачному серверу
variable "public_key" {
default = "key_value"
}
# Сегмент пула
variable "az_zone" {
default = "ru-3b"
}
# Тип сетевого диска, из которого создается сервер
variable "volume_type" {
default = "fast.ru-3b"
}
# CIDR подсети
variable "subnet_cidr" {
default = "10.10.0.0/24"
}
Здесь:
ru-3
— пул облачной платформы, в котором будет развернута инфраструктура;key_value
— значение SSH-ключа. Его можно создать в панели управления или с помощью OpenStack CLI командамиssh-keygen -t rsa
иopenstack keypair create --public-key ~/.ssh/id_rsa.pub <ssh_name>
ru-3b
— сегмент пула;fast.ru-3b
— тип сетевого диска, из которого создается сервер. Доступные для создания типы можно посмотреть с помощью командыopenstack volume type list
10.10.0.0/24
— CIDR подсети.
Файл main.tf
# Инициализация Terraform и хранения Terraform State
terraform {
required_version = ">= 0.14.0"
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.49.0"
}
selectel = {
source = "selectel/selectel"
version = "~> 3.9.0"
}
}
backend "s3" {
bucket = "/container"
endpoint = "s3.storage.selcloud.ru"
key = "terraform.tfstate"
region = "ru-1"
skip_region_validation = true
skip_credentials_validation = true
access_key = "access_key"
secret_key = "secret_key"
}
}
# Инициализация провайдера OpenStack
provider "openstack" {
auth_url = "https://api.selvpc.ru/identity/v3"
domain_name = "selectel_account"
tenant_id = "project_id"
user_name = "user_name"
password = "user_password"
region = var.region
}
# Инициализация провайдера Selectel
provider "selectel" {
token = "selectel_token"
}
# Создание SSH-ключа
resource "openstack_compute_keypair_v2" "key_tf" {
name = "key_tf"
region = var.region
public_key = var.public_key
}
# Запрос ID внешней сети по имени
data "openstack_networking_network_v2" "external_net" {
name = "external-network"
}
# Создание роутера
resource "openstack_networking_router_v2" "router_tf" {
name = "router_tf"
external_network_id = data.openstack_networking_network_v2.external_net.id
}
# Создание сети
resource "openstack_networking_network_v2" "network_tf" {
name = "network_tf"
}
# Создание подсети
resource "openstack_networking_subnet_v2" "subnet_tf" {
network_id = openstack_networking_network_v2.network_tf.id
name = "subnet_tf"
cidr = var.subnet_cidr
}
# Подключение роутера к подсети
resource "openstack_networking_router_interface_v2" "router_interface_tf" {
router_id = openstack_networking_router_v2.router_tf.id
subnet_id = openstack_networking_subnet_v2.subnet_tf.id
}
# Поиск ID образа (из которого будет создан сервер) по его имени
data "openstack_images_image_v2" "ubuntu_image" {
most_recent = true
visibility = "public"
name = "Ubuntu 20.04 LTS 64-bit"
}
# Создание уникального имени флейвора
resource "random_string" "random_name_server" {
length = 16
special = false
}
# Создание конфигурации сервера с 1 ГБ RAM и 1 vCPU
# Параметр disk = 0 делает сетевой диск загрузочным
resource "openstack_compute_flavor_v2" "flavor_server" {
name = "server-${random_string.random_name_server.result}"
ram = "1024"
vcpus = "1"
disk = "0"
is_public = "false"
}
# Создание сетевого загрузочного диска размером 5 ГБ из образа
resource "openstack_blockstorage_volume_v3" "volume_server" {
name = "volume-for-server1"
size = "5"
image_id = data.openstack_images_image_v2.ubuntu_image.id
volume_type = var.volume_type
availability_zone = var.az_zone
enable_online_resize = true
lifecycle {
ignore_changes = [image_id]
}
}
# Создание сервера
resource "openstack_compute_instance_v2" "server_tf" {
name = "server_tf"
flavor_id = openstack_compute_flavor_v2.flavor_server.id
key_pair = openstack_compute_keypair_v2.key_tf.id
availability_zone = var.az_zone
network {
uuid = openstack_networking_network_v2.network_tf.id
}
block_device {
uuid = openstack_blockstorage_volume_v3.volume_server.id
source_type = "volume"
destination_type = "volume"
boot_index = 0
}
vendor_options {
ignore_resize_confirmation = true
}
lifecycle {
ignore_changes = [image_id]
}
}
# Создание публичного IP-адреса
resource "openstack_networking_floatingip_v2" "fip_tf" {
pool = "external-network"
}
# Привязка публичного IP-адреса к серверу
resource "openstack_compute_floatingip_associate_v2" "fip_tf" {
floating_ip = openstack_networking_floatingip_v2.fip_tf.address
instance_id = openstack_compute_instance_v2.server_tf.id
}
Создать инфраструктуру
Выполните следующие команды в директории, в которой находятся созданные манифесты.
Инициализируйте Terraform-окружение:
terraform init
Проверьте, что план составлен без ошибок:
terraform plan
Если ошибок в описании нет, будет выведен список ресурсов, готовых к созданию. Если ошибки есть — их нужно устранить.
Разверните инфраструктуру и создайте ресурсы:
terraform apply
Подтвердите создание — введите yes и нажмите Enter. Созданные ресурсы автоматически отобразятся в панели управления.
Редактировать ресурсы
Чтобы изменить уже созданную инфраструктуру или ее компоненты, достаточно отредактировать манифест — Terraform определит, что нужно дополнительно создать или удалить.
Если вы внесли изменения в инфраструктуру через панель управления, в манифестах они не отобразятся.
Для изменения инфраструктуры отредактируйте манифест и затем примените изменения:
terraform apply
Ограничения произвольных конфигураций
Если вы измените значение vCPU, RAM или локального диска в описании ресурса произвольной конфигурации (флейвора) облачного сервера на недопустимое, то возникнет ошибка — Terraform удалит флейвор и не сможет создать новый.
Чтобы сначала создавался новый флейвор, а затем удалялся старый, добавьте в описание флейвора (пример):
lifecycle {
create_before_destroy = true
}
Удалить ресурсы
Если вы удалили ресурсы через панель управления, это не отобразится в манифестах.
Чтобы удалить ресурсы, в директории с манифестами выполните:
terraform destroy
Будет выведен список удаляемых ресурсов. Подтвердите удаление — введите yes и нажмите Enter.