Terraform-провайдер Selectel

yfsipfz7j0lfweuvzxwwqzqr94a.png

Мы запустили официальный Terraform-провайдер для работы с Selectel. Этот продукт позволяет пользователям полностью реализовать управление ресурсами через методологию Infrastructure-as-code (инфраструктура как код).
В настоящее время провайдер поддерживает управление ресурсами услуги «Виртуальное приватное облако» (далее VPC). В будущем мы планируем добавить в него управление ресурсами других услуг, предоставляемых Selectel.

Как вы уже знаете, услуга VPC построена на базе OpenStack. Однако, в силу того, что OpenStack не предоставляет нативных средств для обслуживания публичного облака, мы реализовали недостающую функциональность в наборе дополнительных API, которые упрощают управление сложными составными объектами и делают работу более удобной. Часть функциональности, доступной в OpenStack, закрыта от использования напрямую, но доступна через наш API.

В Terraform-провайдере Selectel сейчас реализована возможность управления следующими ресурсами VPC:

  • проекты и их квоты;
  • пользователи, их роли и токены;
  • публичные подсети, в том числе кросс-региональные и VRRP;
  • лицензии ПО.


Провайдер использует нашу публичную Go-библиотеку для работы с API VPC. И библиотека и сам провайдер являются open-source, их разработка ведется на Github:
Для управления остальными ресурсами облака, такими как виртуальные машины, диски, кластеры Kubernetes, вы можете использовать Terraform-провайдер OpenStack. Официальная документация для обоих провайдеров доступна по следующим ссылкам:

Начало работы


Для начала работы необходимо установить Terraform (инструкции и ссылки на установочные пакеты можно посмотреть на официальном сайте).

Для работы провайдеру требуется ключ Selectel API, который создается в панели управления для аккаунта.

Манифесты для работы с Selectel создаются посредством Terraform либо используя набор готовых примеров, которые доступны в нашем Github-репозитории: terraform-examples.

Репозиторий с примерами разбит на две директории:

  • modules, содержащая небольшие переиспользуемые модули, которые принимают на вход набор параметров и управляют небольшим набором ресурсов;
  • examples, содержащая примеры полного набора связанных между собой модулей.


После установки Terraform, создания ключа Selectel API и ознакомления с примерами, переходим к практическим примерам.

Пример создания сервера с локальным диском


Рассмотрим пример создания проекта, пользователя с ролью и виртуальной машиной с локальным диском: terraform-examples/examples/vpc/server_local_root_disk.

В файле vars.tf описаны все параметры, которые будут использованы при вызове модулей. Некоторые из них имеют значения по умолчанию, например, сервер будет создан в зоне ru-3a со следующей конфигурацией:

variable "server_vcpus" {
default = 4
}

variable "server_ram_mb" {
default = 8192
}

variable "server_root_disk_gb" {
default = 8
}

variable "server_image_name" {
default = "Ubuntu 18.04 LTS 64-bit"
}


В файле main.tf происходит инициализация провайдера Selectel:

provider "selectel" {
token    = "${var.sel_token}"
}


Также в этом файле указано значение по умолчанию для SSH-ключа, который будет установлен на сервер:

module "server_local_root_disk" {
...
server_ssh_key      = "${file("~/.ssh/id_rsa.pub")}"
}


При необходимости можно указать другой публичный ключ. Ключ не обязательно указывать в виде пути к файлу, также можно добавить значение в виде строки.

Далее в этом файле запускаются модули project_with_user и server_local_root_disk, которые управляют необходимыми ресурсами.

Разберем подробнее эти модули.

Создание проекта и пользователя с ролью


Первый модуль создает проект и пользователя с ролью в этом проекте: terraform-examples/modules/vpc/project_with_user.

Созданный пользователь сможет авторизоваться в OpenStack и управлять его ресурсами. Модуль простой и управляет всего тремя сущностями:

  • selectel_vpc_project_v2,
  • selectel_vpc_user_v2,
  • selectel_vpc_role_v2.

Создание виртуального сервера с локальным диском


Второй модуль занимается управлением объектами OpenStack, которые необходимы для создания сервера с локальным диском.

Следует обратить внимание на некоторые аргументы, которые указаны в этом модуле для ресурса openstack_compute_instance_v2:

resource "openstack_compute_instance_v2" "instance_1" {
  ...

  lifecycle {
    ignore_changes = ["image_id"]
  }

  vendor_options {
    ignore_resize_confirmation = true
  }
}


Аргумент ignore_changes позволяет игнорировать изменение атрибута id для образа, используемого для создания виртуальной машины. В сервисе VPC большинство публичных образов обновляется автоматически раз в неделю и при этом их id также меняется. Это обусловлено особенностями работы компонента OpenStack — Glance, в котором образы считаются неизменяемыми сущностями.

Если создается или изменяется существующий сервер или диск, у которого в качестве аргумента image_id используется id публичного образа, то после того как этот образ будет обновлен, повторный запуск манифеста Terraform приведет к пересозданию сервера или диска. Использование аргумента ignore_changes позволяет избежать такой ситуации.

Примечание: аргумент ignore_changes появился в Terraform достаточно давно: pull#2525.

Аргумент ignore_resize_confirmation нужен для успешного изменения размера локального диска, ядер или памяти сервера. Такие изменения производятся через компонент OpenStack Nova при помощи запроса resize. По умолчанию Nova после запроса resize переводит сервер в статус verify_resize и ждет от пользователя дополнительного подтверждения. Однако это поведение можно изменить так, чтобы Nova не дожидалась от пользователя дополнительных действий.

Указанный аргумент позволяет Terraform не дожидаться статуса verify_resize для сервера и быть готовым к тому, что сервер окажется в активном статусе после изменения его параметров. Аргумент доступен с версии 1.10.0 Terraform-провайдера OpenStack: pull#422.

Создание ресурсов


Перед запуском манифестов следует учесть, что в нашем примере запускаются два разных провайдера, причем провайдер OpenStack зависит от ресурсов провайдера Selectel, так как без создания пользователя в проекте управлять принадлежащими ему объектами невозможно. К сожалению, по этой же причине мы не можем просто запустить команду terraform apply внутри нашего примера. Нам потребуется вначале сделать apply для модуля project_with_user и уже после этого для всего остального.

Примечание: указанная проблема еще не решена в Terraform, за ее обсуждением можно следить на Github в issue#2430 и issue#4149.

Для создания ресурсов перейдем в директорию terraform-examples/examples/vpc/server_local_root_disk, ее содержимое должно быть таким:

$ ls
README.md          main.tf              vars.tf


Инициализируем модули при помощи команды:

$ terraform init


В выводе видно, что Terraform скачивает последние версии используемых провайдеров и проверяет все модули, описанные в примере.

Вначале применим модуль project_with_user. При этом требуется вручную передать значения для переменных, которые не были установлены:

  • sel_account с номером вашего аккаунта Selectel;
  • sel_token с вашим ключом для Selectel API;
  • user_password с паролем для пользователя OpenStack.


Значения для первых двух переменных надо взять из панели управления.

Для последней переменной можно придумать любой пароль.

Для применения модуля необходимо заменить значения SEL_ACCOUNT, SEL_TOKEN и USER_PASSWORD запуском команды:

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform apply -target=module.project_with_user


После запуска команды Terraform покажет, какие ресурсы он хочет создать и потребует подтверждения:

Plan: 3 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes


Как только проект, пользователь и роль будут созданы, можно запустить создание остальных ресурсов:

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform apply


При создании ресурсов обратите внимание на вывод Terraform с внешним IP-адресом, по которому будет доступен созданный сервер:

module.server_local_root_disk.openstack_networking_floatingip_associate_v2.association_1: Creating...
  floating_ip: "" => "x.x.x.x"


C созданной виртуальной машиной можно работать через SSH по указанному IP.

Редактирование ресурсов


Помимо создания ресурсов через Terraform, их также можно изменять.

Для примера увеличим количество ядер и памяти для нашего сервера, изменив значения для параметров server_vcpus и server_ram_mb в файле examples/vpc/server_local_root_disk/main.tf:

-  server_vcpus        = "${var.server_vcpus}"
-  server_ram_mb       = "${var.server_ram_mb}"
+  server_vcpus        = 8
+  server_ram_mb       = 10240


После этого проверяем, к каким изменениям это приведет, при помощи следующей команды:

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform plan


В результате Terraform произвел изменение ресурсов openstack_compute_instance_v2 и openstack_compute_flavor_v2.

Обратите внимание, что это повлечет за собой перезагрузку созданной виртуальной машины.

Для применения новой конфигурации виртуальной машины используйте команду terraform apply, которую мы уже запускали ранее.

Все созданные объекты будут отображаться в панели управления VPC:

eqe53anrxqpnpd6qn7hlcrnuxec.png

В нашем репозитории примеров также можно ознакомиться с манифестами для создания виртуальных машин с сетевыми дисками.

Пример создания кластера Kubernetes


Перед тем как перейти к следующему примеру, мы очистим созданные ранее ресурсы. Для этого в корне проекта terraform-examples/examples/vpc/server_local_root_disk запустим команду удаления объектов OpenStack:

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform destroy -target=module.server_local_root_disk


Затем запустим команду очищения объектов Selectel VPC API:

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform destroy -target=module.project_with_user


В обоих случаях потребуется подтвердить удаление всех объектов:

Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.

Enter a value: yes


Следующий пример находится в директории terraform-examples/examples/vpc/kubernetes_cluster.

Этот пример создает проект, пользователя с ролью в проекте и поднимает один кластер Kubernetes. В файле vars.tf можно увидеть значения по умолчанию, такие как количество нод, их характеристики, версия Kubernetes и прочее.

Для создания ресурсов аналогично первому примеру первым делом запустим инициализацию модулей и создание ресурсов модуля project_with_user, а затем создание всего остального:

$ terraform init

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform apply -target=module.project_with_user

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform apply


Передадим создание и управление кластерами Kubernetes через компонент OpenStack Magnum. Подробнее о том, как работать с кластером, вы можете узнать в одной из наших предыдущих статей, а также в базе знаний.

При подготовке кластера будут созданы диски, виртуальные машины и произойдет установка всех необходимых компонентов. Подготовка занимает около 4 минут, в это время Terraform будет выводить сообщения вида:

module.kubernetes_cluster.openstack_containerinfra_cluster_v1.cluster_1: Still creating... (3m0s elapsed)


После завершения установки Terraform сообщит, что кластер готов и отобразит его идентификатор:

module.kubernetes_cluster.openstack_containerinfra_cluster_v1.cluster_1: Creation complete after 4m20s (ID: 3c8...)

Apply complete! Resources: 6 added, 0 changed, 0 destroyed.


Для управления созданным кластером Kubernetes через утилиту kubectl необходимо получить файл доступа к кластеру. Для этого перейдите в проект, созданный через Terraform, в списке проектов вашего аккаунта:

pp7yrtw_q-79pkx1j6mr5ebbsyi.png

Далее перейдите по ссылке вида xxxxxx.selvpc.ru, которая отображается ниже имени проекта:

yrinwkfne83cenropq9t3szxt6c.png

В качестве данных для входа используйте имя и пароль пользователя, которые были созданы через Terraform. Если вы не изменяли vars.tf или main.tf для нашего примера, то пользователь будет иметь имя tf_user. В качестве пароля нужно использовать значение переменной TF_VAR_user_password, которое было указано при запуске terraform apply ранее.

Внутри проекта вам нужно перейти на вкладку Kubernetes:

ftbpdjhjrgxkgzomuxegaujj3wu.png

Здесь расположен кластер, созданный через Terraform. Скачать файл для kubectl можно на вкладке «Доступ»:

y_peovkv0kjznzx95c_vw4wc-4e.png

На этой же вкладке находится инструкция по установке kubectl и использованию скачанного config.yaml.

После запуска kubectl и установки переменной окружения KUBECONFIG можно использовать Kubernetes:

$ kubectl get pods --all-namespaces

NAMESPACE        NAME                                    READY  STATUS  RESTARTS AGE
kube-system   coredns-9578f5c87-g6bjf                      1/1   Running   0 8m
kube-system   coredns-9578f5c87-rvkgd                     1/1   Running   0 6m
kube-system   heapster-866fcbc879-b6998                 1/1   Running   0 8m
kube-system   kube-dns-autoscaler-689688988f-8cxhf             1/1   Running   0 8m
kube-system   kubernetes-dashboard-7bdb5d4cd7-jcjq9          1/1   Running   0 8m
kube-system   monitoring-grafana-84c97bb64d-tc64b               1/1   Running   0 8m
kube-system   monitoring-influxdb-7c8ccc75c6-dzk5f                1/1   Running   0 8m
kube-system   node-exporter-tf-cluster-rz6nggvs4va7-minion-0 1/1   Running   0 8m
kube-system   node-exporter-tf-cluster-rz6nggvs4va7-minion-1 1/1   Running   0 8m
kube-system   openstack-cloud-controller-manager-8vrmp        1/1   Running   3 8m
prometeus-monitoring   grafana-76bcb7ffb8-4tm7t       1/1   Running   0 8m
prometeus-monitoring   prometheus-75cdd77c5c-w29gb           1/1   Running   0 8m


Количество нод кластера легко изменяется через Terraform.
В файле main.tf указано следующее значение:

cluster_node_count = "${var.cluster_node_count}"

Это значение подставляется из vars.tf:

variable "cluster_node_count" {
default = 2
}


Можно изменить либо значение по умолчанию в vars.tf, либо указать требуемое значение напрямую в main.tf:

-  cluster_node_count = "${var.cluster_node_count}"
+  cluster_node_count = 3


Для применения изменений, как и в случае с первым примером, воспользуйтесь командой terraform apply:

$ env \
TF_VAR_sel_account=SEL_ACCOUNT \
TF_VAR_sel_token=SEL_TOKEN \
TF_VAR_user_password=USER_PASSWORD \
terraform apply


При изменении количества нод кластер будет оставаться доступным. После добавления ноды через Terraform, можно использовать ее без дополнительной конфигурации:

$ kubectl get nodes
NAME                               STATUS                     ROLES     AGE   VERSION
tf-cluster-rz6nggvs4va7-master-0   Ready,SchedulingDisabled   master    8m    v1.12.4
tf-cluster-rz6nggvs4va7-minion-0   Ready                          8m    v1.12.4
tf-cluster-rz6nggvs4va7-minion-1   Ready                          8m    v1.12.4
tf-cluster-rz6nggvs4va7-minion-2   Ready                          3m    v1.12.4

Заключение


В этой статье мы ознакомились с основными способами работы с «Виртуальным приватным облаком» через Terraform. Будем рады, если вы воспользуетесь официальным Terraform-провайдером Selectel и предоставите обратную связь.

Обо всех найденных багах Terraform-провайдера Selectel можно сообщить посредством Github Issues.

© Habrahabr.ru