Перейти к содержанию

Настройка услуги «Создание ВМ в публичном облаке Яндекс.Облако»

Общая информация

Услуга "Создание ВМ в публичном облаке Яндекс.Облако", реализованная с использованием API Яндекс.Облака. Услуга включает в себя этапы:

  • Задание пользователем статичных данных об ВМ (в т.ч. реквизиты подключения к целевому облаку). На этом этапе предполагается создание диалоговых форм в графическом интерфейсе;
  • Задание(запрос) динамических данных необходимых для создания ВМ (например, список образов ОС). На этом этапе предполагается организация взаимодействия с внешним API облачного провайдера;
  • Подготовка набора файлов, включающих манифесты описывающие целевое состояние создаваемой ВМ, а также вспомогательные скрипты для организации жизненного циклы компонентов terraform.

Для запуска данной услуги необходимо разместить содержимое директории tf_vm_service из дистрибутива на Git, и задать параметры подключения к этому репозиторию в параметрах инстанса: /NIMBIUS_PUBLIC_CLOUD/Integration/Terraform/Terraform.

Пример заполнения (таблица) и конечный вариант (рисунок) заполненных полей:

Рисунок 43

Пример значений параметров /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";
    

Порядок действий при операциях создания и удаления ВМ

Создание/заказ ВМ

  1. Пользователь запускает диалоговое окно услуги "Создание ВМ в публичном облаке Yandex.Cloud".

    • В этот момент генерируется уникальный ID, который в дальнейшем будет использован при создании отдельной директории по хранению манифестов и отдельной БД для хранения «.tfstate» при выполнении «terraform apply»;

    Рисунок 44

  2. Пользователь заполняет поля в форме услуги "Создание ВМ в публичном облаке 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.
  3. После определения параметров из п.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/;
  4. Вызывается команда «terraform apply --auto-approve»;

  5. Создается ВМ.

Удаление ВМ

  1. Пользователь выбирает действие "Удаление ВМ", на основе ранее сформированного уникального ID находится в контейнере nimbius-terraform папка в директории /infra/;
  2. В указанной директории выполняется команда «terraform destroy --auto-approve», созданная ранее ВМ удаляется;
  3. Далее выполняется скрипт /infra/ID/drop_db.sql, удаляется БД PostgreSQL в которой хранился «.tfstate»;
  4. Далее удаляется директория /infra/ID внутри контейнера nimbius-terraform.