Работа с Terraform

Разворачивать облачную инфраструктуру в Selectel и управлять ей можно с помощью утилиты Terraform от HashiCorp.

Через Terraform можно работать с продуктами:

Инфраструктура и ее компоненты описываются на языке HashiCorp Configuration Language (HCL) в конфигурационных файлах с расширением .tf — манифестах.

Для работы с услугами Selectel используется два Terraform-провайдера:

  • OpenStack-провайдер для управления ресурсами OpenStack, например облачными серверами (нодами кластера Managed Kubernetes), дисками, сетями;
  • Selectel-провайдер, который взаимодействует с API Selectel, для управления проектами и квотами, пользователями, их ролями и токенами, DNS, кластерами и группами нод Managed Kubernetes, Облачными базами данных.

Чтобы развернуть инфраструктуру через Terraform:

  1. Установите Terraform.
  2. Создайте манифест, инициализируйте в нем Terraform-провайдеры OpenStack и Selectel, опишите план инфраструктуры.
  3. Проверьте конфигурацию и разверните инфраструктуру.

Установить Terraform

Перед началом работы установите Terraform на облачном сервере или компьютере.

Используйте инструкцию на официальном сайте Terraform в зависимости от операционной системы.

Создать манифест

План инфраструктуры описывается в манифестах — файлах с расширением .tf.

При выполнении команды terraform apply, которая создает инфраструктуру, Terraform загружает все манифесты, лежащие в одной директории — создаются все описанные ресурсы. Поэтому файлы с описанием одной инфраструктуры должны находиться в отдельной директории.

Создайте директорию и файл внутри нее, например main.tf. Файлы с описанием плана могут иметь любое название.

Настроить провайдеры

В манифесте нужно перечислить Terraform-провайдеры, необходимые для создания инфраструктуры. Обычно для работы используются два провайдера: Selectel и OpenStack. В некоторых случаях требуется только OpenStack, например, если проект Облачной платформы уже создан.

Добавьте в файл следующий блок и перечислите в нем провайдеры:

terraform {
required_version = ">= 0.14.0"
  required_providers {
    openstack = {
      source  = "terraform-provider-openstack/openstack"
      version = "~> 1.48.0"
    }
     selectel = {
      source  = "selectel/selectel"
      version = "~> 3.8.4"
   }
  }
}

Актуальные версии провайдеров (version) можно найти в их официальной документации (Selectel и OpenStack), нажав на кнопку 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      = "region"
}

Укажите:

  • auth_url — ссылка для идентификации в API Selectel;
  • domain_name — ID аккаунта Selectel (номер договора), находится в панели управления;
  • tenant_id — ID проекта Облачной платформы;
  • user_nameпользователь OpenStack, привязанный к проекту Облачной платформы;
  • password — пароль пользователя OpenStack;
  • regionпул, в котором будет развернута инфраструктура.

Для авторизации Selectel-провайдера:

provider "selectel" {
  token = "selectel_token"
}

Укажите token — токен аккаунта (ключ Selectel API), получить его можно по инструкции Ключи API.

План инфраструктуры

Опишите план инфраструктуры в файле с расширением .tf. Вы можете:

Ниже вы можете посмотреть пример манифеста для создания проекта и кластера Managed Kubernetes.

Создать инфраструктуру

Выполните следующие команды в директории, в которой находятся созданные манифесты:

  1. Инициализируйте Terraform-окружение:
terraform init
  1. Проверьте, что план составлен без ошибок:
terraform plan

Если ошибок в описании нет, будет выведен список ресурсов, готовых к созданию. Если ошибки есть — их нужно устранить. 3. Разверните инфраструктуру и создайте ресурсы:

terraform apply
  1. Подтвердите создание — введите yes и нажмите Enter.

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

Редактировать или удалить ресурсы

Чтобы изменить уже созданную инфраструктуру или ее компоненты, достаточно отредактировать манифест — Terraform определит, что нужно дополнительно создать или удалить.

Если вы внесли изменения в инфраструктуру через панель управления, в манифестах они не отобразятся.

Для изменения инфраструктуры отредактируйте манифест и затем примените изменения:

terraform apply

Чтобы удалить ресурсы, в директории с манифестами выполните:

terraform destroy

Будет выведен список удаляемых ресурсов. Подтвердите удаление — введите yes и нажмите Enter.

Пример плана инфраструктуры

Применение этого плана создаст проект Облачной платформы с пользователем, а также инфраструктуру в пуле ru-9, которая будет содержать:

  • отказоустойчивый кластер Managed Kubernetes с одной группой нод: две ноды в группе с произвольной конфигурацией с 2 vCPU, 4 ГБ RAM и локальным диском объемом 32 ГБ;
  • приватную сеть с подсетью;
  • облачный роутер, подключенный к внешней сети.

План описан в двух файлах — vars.tf и main.tf. В первом объявлены переменные для создания инфраструктуры, во втором — инициализированы провайдеры и модули для создания ресурсов. Для использования модулей локально клонируйте репозиторий Selectel.

Файл vars.tf

variable "sel_token" {}

variable "os_auth_url" {
  default = "https://api.selvpc.ru/identity/v3/auth/"
}

variable "user_name" {
  default = "user"
}

variable "project_name" {
  default = "project"
}

variable "user_password" {}

variable "region" {
  default = "ru-9"
}

variable "availability_zone" {
  default = "ru-9a"
}

variable "subnet_cidr" {
  default = "10.222.0.0/16"
}

variable "network_id" {
  default = ""
}

variable "subnet_id" {
  default = ""
}

variable "cluster_name" {
  default = "cluster"
}

variable "kube_version" {
  default = "1.24.3"
}

variable "enable_autorepair" {
  default = true
}

variable "enable_patch_version_auto_upgrade" {
  default = true
}

variable "maintenance_window_start" {
  default = "04:00:00"
}

variable "nodes_count" {
  default = 2
}

variable "keypair_name" {
  default = "ssh"
}

variable "cpus" {
  default = 2
}

variable "ram_mb" {
  default = 4096
}

variable "volume_gb" {
  default = 32
}

variable "labels" {
  default = {
    "label1":"value1", 
    "label2":"value2"
  }
}

variable "taints" {
  type = list(object({
    key = string
    value = string
    effect =string
  }))
  default =[ {
    effect = "NoSchedule"
    key = "key1"
    value = "value1"
  },
  {
    effect = "NoSchedule"
    key = "key2"
    value = "value2"
  } ]
}

Здесь:

  • sel_token — токен аккаунта (ключ Selectel API), создается автоматически вместе с проектом;
  • user_name — имя пользователя OpenStack, который будет привязан к проекту Облачной платформы;
  • project_name — имя проекта Облачной платформы;
  • user_password — пароль пользователя, создается автоматически вместе с проектом;
  • regionпул, в котором будет развернута инфраструктура;
  • availability_zone — сегмент пула, в котором будут располагаться все ноды в группе;
  • subnet_cidr— CIDR приватной подсети, в которую будут объединены все ноды кластера;
  • network_id — сеть кластера, создается автоматически вместе с проектом;
  • subnet_id — подсеть кластера, создается автоматически вместе с проектом;
  • cluster_name — имя кластера;
  • kube_version — версия Kubernetes;
  • enable_autorepairавтовосстановление нод кластера: True — включить или False — выключить;
  • enable_patch_version_auto_upgradeавтообновление патч-версий кластера: True — включить или False — выключить;
  • maintenance_window_startокно обслуживания кластера: время UTC в формате hh:mm:ss;
  • nodes_count — количество нод в группе;
  • keypair_name — имя SSH-ключа для безопасного подключения к нодам, ключ можно создать в панели управления или с помощью OpenStack CLI командами ssh-keygen -t rsa и openstack keypair create --public-key ~/.ssh/id_rsa.pub <ssh_name>;
  • cpus — количество vCPU у каждой ноды в группе;
  • ram_mb — объем оперативной памяти в МБ у каждой ноды в группе;
  • volume_gb — объем локального диска в ГБ у каждой ноды в группе;
  • labelsметки группы нод;
  • taintsтейнты группы нод.

Файл main.tf

# Инициализация Terraform
terraform {
  required_providers {
    selectel = {
      source = "selectel/selectel"
    }
    openstack = {
      source = "terraform-provider-openstack/openstack"
      version = ">= 1.48.0"
    }
  }
  required_version = ">= 0.13"
}

# Инициализация провайдера Selectel
provider "selectel" {
  token = var.sel_token
}

# Инициализация провайдера OpenStack
provider "openstack" {
  auth_url            = var.os_auth_url
  user_name           = var.user_name
  tenant_name         = var.project_name
  password            = var.user_password
  project_domain_name = regex("[[:digit:]]+$", var.sel_token)
  user_domain_name    = regex("[[:digit:]]+$", var.sel_token)
  region              = var.region
}

# Создание проекта и пользователя
module "project_with_user" {
  providers = {
    selectel  = selectel,
  }
  source = "../../../modules/vpc/project_with_user"

  project_name  = var.project_name
  user_name     = var.user_name
  user_password = var.user_password
}

# Создание сети и облачного роутера с доступом во внешнюю сеть
module "nat" {
  source = "../../../modules/vpc/nat"

  subnet_cidr = var.subnet_cidr

  depends_on = [
    module.project_with_user
  ]
}

# Создание кластера
module "kubernetes_cluster" {
  source = "../../../modules/mks/cluster"

  cluster_name                      = var.cluster_name
  project_id                        = module.project_with_user.project_id
  region                            = var.region
  kube_version                      = var.kube_version
  enable_autorepair                 = var.enable_autorepair
  enable_patch_version_auto_upgrade = var.enable_patch_version_auto_upgrade
  network_id                        = module.nat.network_id
  subnet_id                         = module.nat.subnet_id
  maintenance_window_start          = var.maintenance_window_start
}

# Создание группы нод
module "kubernetes_nodegroup_local_disk" {
  source = "../../../modules/mks/nodegroup_local_disk"

  cluster_id        = module.kubernetes_cluster.cluster_id
  project_id        = module.kubernetes_cluster.project_id
  region            = module.kubernetes_cluster.region
  availability_zone = var.availability_zone
  nodes_count       = var.nodes_count
  keypair_name      = var.keypair_name
  affinity_policy   = var.affinity_policy
  cpus              = var.cpus
  ram_mb            = var.ram_mb
  volume_gb         = var.volume_gb
  labels            = var.labels
  taints            = var.taints
}