Хабрахабр

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

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

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

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

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 = "$"
}

Также в этом файле указано значение по умолчанию для 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, в котором образы считаются неизменяемыми сущностями.

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

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

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

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

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

Перед запуском манифестов следует учесть, что в нашем примере запускаются два разных провайдера, причем провайдер 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:

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

Пример создания кластера 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.

В файле vars.tf можно увидеть значения по умолчанию, такие как количество нод, их характеристики, версия Kubernetes и прочее. Этот пример создает проект, пользователя с ролью в проекте и поднимает один кластер 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, в списке проектов вашего аккаунта:

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

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

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

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

На этой же вкладке находится инструкция по установке 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 <none> 8m v1.12.4
tf-cluster-rz6nggvs4va7-minion-1 Ready <none> 8m v1.12.4
tf-cluster-rz6nggvs4va7-minion-2 Ready <none> 3m v1.12.4

Заключение

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

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

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»