Настройка услуги «Создание ВМ в публичном облаке Яндекс.Облако»
Общая информация¶
Услуга "Создание ВМ в публичном облаке Яндекс.Облако", реализованная с использованием API Яндекс.Облака. Услуга включает в себя этапы:
- Задание пользователем статичных данных об ВМ (в т.ч. реквизиты подключения к целевому облаку). На этом этапе предполагается создание диалоговых форм в графическом интерфейсе;
- Задание(запрос) динамических данных необходимых для создания ВМ (например, список образов ОС). На этом этапе предполагается организация взаимодействия с внешним API облачного провайдера;
- Подготовка набора файлов, включающих манифесты описывающие целевое состояние создаваемой ВМ, а также вспомогательные скрипты для организации жизненного циклы компонентов terraform.
Для запуска данной услуги необходимо разместить содержимое директории tf_vm_service из дистрибутива на Git, и задать параметры подключения к этому репозиторию в параметрах инстанса: /NIMBIUS_PUBLIC_CLOUD/Integration/Terraform/Terraform.
Пример заполнения (таблица) и конечный вариант (рисунок) заполненных полей:
Пример значений параметров /NIMBIUS_PUBLIC_CLOUD/Integration/Terraform/Terraform
Поле | Значение | Комментарий |
---|---|---|
tf-host | terraform | Имя сервиса коннектора к Terraform. По умолчанию: terraform |
git_login | имя пользователя | Имя пользователя на Git, где размещаются шаблоны манифестов Terraform |
git_password | пароль | Пароль пользователя на Git, где размещаются шаблоны манифестов Terraform |
git_path | url.domain.ru | URL Git БЕЗ префикса http/https. Включая имя группы проектов, если она есть |
git_repository | имя репозитория | Имя репозитория в Git, где размещаются шаблоны манифестов Terraform |
cloud_dir | имя папки | Имя папки в репозитории шаблонов манифестов Terraform |
tf_host_login | root | Имя пользователя в контейнере Terraform. По умолчанию: root |
execute | имя метода | Имя метода для вызова. Без необходимости не менять |
Создание диалоговых форм¶
В примере уже есть созданная форма "public_cloud_vm_provision", ее при необходимости можно скопировать и в дальнейшем изменить.
В форме обязательно должно присутствовать поле «terraform_session_id» которое должно быть динамическое и ссылаться на метод: Service/DynamicDialogs get_session_id.
Далее необходимо определить поля для передачи токенов или иных данных для подключения.
Важно
Чтобы все переменные, которые должны быть переданы в terraform должны быть вида:terraform_
После этого создаются поля значения, которых будут передаваться в качестве переменных в файлы конфигурации terraform.
Работа с API публичного облака Yandex.Cloud¶
При заполнении пользователем значений в полях создаваемой ВМ, некоторые значения такие, как например версия или тип ОС могут меняться со стороны облачного провайдера.
Для того чтобы иметь актуальную информацию об этих значения, подобные данные возможно запрашивать у облачного провайдера напрямую через запросы к API облачного провайдеру.
Для выполнения запроса, может понадобится сформировать токен для доступа к Yandex.Cloud (токен может быть как OAuth-токен (срок действия 1 год), так и iam-токен (срок действия 24 часа)).
Создание iam-токена через yc cli:
yc iam create-token
Далее формируется REST запрос для получения актуального списка доступных образов ОС (не забыв указать токен)
https://compute.api.cloud.yandex.net/compute/v1/images?folderId=standard-images
Вывод запроса будет содержать информацию обо всех образах (включая старые релизы) ОС в Yandex.Cloud, для того чтобы сформировать сокращенный список, запрос обрабатывается и фильтруется, на выходе получается список основных ОС последних версий.
Создание манифестов¶
Работа Terraform основана на использовании манифестов, в которых определяется создаваемая ИТ-инфраструктура. При создании объектов ИТ-инфраструктуры на основе манифестов так же создаются файлы состояний (.tfstate) которые отражают текущее состояние созданной ИТ инфраструктуры. Файлы состояний могут хранится как локально, так и удаленно, в нашем случае данные файлы храниться удаленно в backend на базе БД PostgreSQL.
Для того чтобы описать создаваемую ВМ в виде манифестов и определить БД для хранения «.tfstate» необходимо подготовить набор файлов в общем виде, включающих в себя:
- env.sh
- cloud-init.tpl.yml
- create_db_sql
- create_user.sql
- data.tf
- drop_db.sql
- instance.tf
- provider.tf
- vars.tf
Каждый из них будет отвечать за:
-
.env.sh - определяет глобальные переменные, например такие как - имя БД для хранения «.tfstate», логин/пароль для подключения к этой БД, реквизиты подключения к аккаунту Yandex.Cloud (TOKEN/CLOUD_ID/FOLDER_ID), переменные будут переданы в файлы: vars.tf, create_db.sql, create_user.sql, drop_db.sql;
Пример содержимого:
#Database server. By default database container use name 'db' #DB_SRV=db #Database server port #DB_PORT=5432 #Database user TF_DB_USER=terraform #Database password TF_DB_PASSWD=terraform-password #Database name TF_DB_NAME=%session_id%-tfstate #Access to Yandex Cloud YC_FOLDER_ID=%yc_folder_id% YC_CLOUD_ID=%yc_cloud_id% YC_TOKEN=%yc_token%
-
cloud-init.tpl.yml - задает параметры выполнения действий на целевой ОС через cloudinit. Например, задаются значения логина/пароля (или public key) для подключения по ssh, устанавливаются доп. пакеты в ОС, изменяются системные настройки. При необходимости данный файл можно дополнять, корректировать;
Пример содержимого:
#cloud-config datasource: Ec2: strict_id: false write_files: - content: | net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.default.disable_ipv6=1 path: /etc/sysctl.d/88-disable.conf owner: root users: - default - name: %user_name% groups: wheel shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL ssh_authorized_keys: - "${ssh_key}" packages: - netplan.io - openssh-server package_update: true package_reboot_if_required: true runcmd: - sysctl -w net.ipv6.conf.all.disable_ipv6=1 - sysctl -w net.ipv6.conf.default.disable_ipv6=1
-
файлы «.tf» определяют параметры создаваемой ВМ, а именно:
- data.tf - задает какие параметры ВМ будут использоваться при создании - версия ОС, ссылки на файл cloudinit и его вспомогательные файлы;
Пример содержимого:
data "yandex_compute_image" "ubuntu" { family = "${var.boot_disk_image_family}" } data "template_file" "cloud_init" { template = "${file("cloud-init.tpl.yaml")}" vars = { ssh_key = "${file(var.public_key_path)}" } }
-
instance.tf - задает все остальные параметры ВМ для ее создания. Например, кол-во vCPU/объем RAM/Disk/нахождении в той или иной подсети и прочее. Все эти переменные определяются в другом файле vars.tf;
Пример содержимого:
# Create VM resource "yandex_compute_instance" "VM" { name = "${var.name}" zone = "${var.zone}" hostname = "${var.hostname}" description = "${var.description}" resources { cores = "${var.cores}" memory = "${var.memory}" } boot_disk { initialize_params { image_id = "${data.yandex_compute_image.ubuntu.id}" type = "${var.disktype}" size = "${var.size}" } } network_interface { subnet_id = "${var.subnet_id}" nat = "${var.nat}" } metadata = { user-data = "${data.template_file.cloud_init.rendered}" } }
-
vars.tf - в этот файл передаются значения переменных, который задает пользователь в GUI при заполнении мастера услуги;
Пример содержимого:
### Main Section variable "yandex-token" { default = "%yc_token%" } variable "yandex-cloud-id" { default = "%yc_cloud_id%" } variable "yandex-folder-id" { default = "%yc_folder_id%" } ### ### VM Section variable "zone" { description = "Name of AZ" default = "%zone%" } variable "name" { description = "Name of VM" type = string default = "%name%" } variable "description" { description = "Description of VM" type = string default = "%description%" } variable "hostname" { description = "Hostname of VM" type = string default = "%hostname%" } variable "boot_disk_image_family" { description = "OS family for VM (ubuntu-2204-lts, centos-7, debian-11, fedora-35)" type = string default = "%boot_disk_image_family%" } variable "subnet_id" { description = "ID of subnet for VM" type = string default = "%subnet_id%" } variable "nat" { description = "Enable/disable NAT for VM" type = string default = "%nat%" } variable "disktype" { description = "Disk type for VM (network-ssd, network-hdd, network-ssd-nonreplicated)" type = string default = "%disktype%" } variable "size" { description = "Size of the boot disk in GB" type = string default = "%size%" } variable "cores" { description = "CPU cores for the instance" type = number default = "%cores%" } variable "memory" { description = "Memory size for the instance in GB" type = number default = "%memory%" } variable "public_key_path" { description = "path to pub key" type = string default = "/root/.ssh/id_rsa.pub" }
-
provider.tf - определяет настройки подключения terraform провайдера относительно указанных пользователем значений TOKEN/CLOUD_ID/FOLDER_ID. Помимо этого в файле задаются настройки подключения к БД PostgreSQL (хранения информации об «.tfstate»).
Пример содержимого:
terraform { required_providers { yandex = { source = "yandex-cloud/yandex" } } required_version = ">= 0.80.0" backend "pg" { conn_str = "postgres://${TF_DB_USER}:${TF_DB_PASSWD}@${DB_SRV}/${TF_DB_NAME}?sslmode=disable" } } provider "yandex" { token = var.yandex-token cloud_id = var.yandex-cloud-id folder_id = var.yandex-folder-id }
Вспомогательные файлы:
-
create_db.sql, create_user.sql, drop_db.sql - скрипты соответственно создания БД/пользователя с доступом к БД для размещения «.tfstate» будущего применения манифестов. В текущей версии - БД создается в том же PostgreSQL контейнере, который используется для хранения БД Нимбиус. Скрипт удаления БД срабатывает после того момента, когда происходит ручное удаление ранее созданной ВМ.
Пример содержимого «create_db.sql»:
CREATE DATABASE "%database%-tfstate" WITH OWNER = terraform ENCODING = \'UTF8\' LC_COLLATE = \'en_US.utf8\' LC_CTYPE = \'en_US.utf8\' TABLESPACE = pg_default CONNECTION LIMIT = -1;
Пример содержимого «create_user.sql»:
CREATE USER terraform WITH PASSWORD 'terraform-password';
Пример содержимого «drop_db.sql»:
DROP DATABASE IF EXISTS "%database%-tfstate";
Порядок действий при операциях создания и удаления ВМ¶
Создание/заказ ВМ¶
-
Пользователь запускает диалоговое окно услуги "Создание ВМ в публичном облаке Yandex.Cloud".
- В этот момент генерируется уникальный ID, который в дальнейшем будет использован при создании отдельной директории по хранению манифестов и отдельной БД для хранения «.tfstate» при выполнении «terraform apply»;
-
Пользователь заполняет поля в форме услуги "Создание ВМ в публичном облаке Yandex.Cloud", такие как:
- token, cloud-id, folder-id (токен возможно получить через yc iam create-token, cloud-id, folder-id возможно получить из GUI облака);
- зона доступность YC;
- имя/hostname ВМ;
- тип образа ОС;
- тип диска ВМ;
- «subnet_id» где будет располагаться ВМ;
- должен ли быть внешний IP-адрес;
- величины vCPUI/RAM/Disk;
- имя пользователя и «public key» для доступа по ssh.
-
После определения параметров из п.2 и уникального ID из п.1 происходит:
- создание контейнера с nimbius-terraform, создание внутри контейнера директории /infra/ID/;
- копирование набора файлов из GIT в директорию /infra/ID/;
- передача определенных параметров из п.1,2 в файлы vars.tf, create_db.sql, create_user.sql, drop_db.sql;
- создание БД и пользователя для нее, путем выполнения скриптов create_db.sql, create_user.sql;
- выполнение «terraform init» в директории /infra/ID/;
-
Вызывается команда «terraform apply --auto-approve»;
- Создается ВМ.
Удаление ВМ¶
- Пользователь выбирает действие "Удаление ВМ", на основе ранее сформированного уникального ID находится в контейнере nimbius-terraform папка в директории /infra/;
- В указанной директории выполняется команда «terraform destroy --auto-approve», созданная ранее ВМ удаляется;
- Далее выполняется скрипт /infra/ID/drop_db.sql, удаляется БД PostgreSQL в которой хранился «.tfstate»;
- Далее удаляется директория /infra/ID внутри контейнера nimbius-terraform.