Цель
Не жарить, а печь.
Задача
Подружить Packer с облачным провайдером SberCloud
Вступление
Привет! Я начинающий DevOps инженер, на неделе была поставлена цель перейти от создания облачной инфраструктуры ручками к IaaC посредством внедрения Packer + Terraform + Ansible. Если у сбера есть провайдер для Terraform, но для Packer провайдер не завезли.
Облазил весь интернет, и не нашёл готового решения или хотя бы намёка на то куда копать.
Нашёл единственную статью на habr.com от компании КРОК и их облаке которое построено по принципу AWS. Исходя из это статьи начал копать, а именно узнал по какому принципу сделано облако сбера, немного почитав документацию понял - облако сделано по принципу Huawei Cloud. И о везение, существует провайдер Huawei Cloud - ссылочка на доку.
Жарка с провайдером Huawei Cloud
Казалось бы всё, победа! Но не тут то было, посмотрим на базовый пример для создания образа в облаке Huawei
Пример для провайдера Huawei cloud
variable "access_key" { type = string } variable "secret_key" { type = string } variable "source_image_id" { type = string } variable "vpc_id" { type = string } variable "subent_id" { type = string } source "huaweicloud-ecs" "basic-example" { region = "cn-north-1" access_key = var.access_key secret_key = var.secret_key flavor = "s6.large.2" image_name = "packer-image" source_image = var.source_image_id vpc_id = var.vpc_id subnets = [var.subent_id] security_groups = ["default"] eip_bandwidth_size = 2 eip_type = "5_bgp" ssh_ip_version = "4" ssh_username = "root" } build { sources = ["source.huaweicloud-ecs.basic-example"] provisioner "shell" { inline = [ "echo \"start install nginx, sleep 20s first\"", "sleep 20", "echo \"run install\"", "apt install -y nginx", "echo \"enable nginx\"", "systemctl enable nginx.service", "echo \"install nginx done\"" ] } }
Данный пример на языке HCL2. И тут есть пара очень важных моментов, которые чуток ломают мозг. Если мы обратимся к провайдеру сбера для Terraform, то увидим что для создания ECS, мы используем следующий код.
resource "sbercloud_compute_instance" "ECS_TestBack" { ... }
Обратим внимание на "sbercloud_compute_instance" - создание ECS происходит при вызове этого ресурса, но если мы тоже самое напишем в Packer, то получим ошибку - что логично, ведь провайдер то не знает ни о каком "sbercloud_compute_instance". По этому оставляем как есть.
Далее подставим свои токены и попробуем запустить.
Непосредственно как дружить
Тут я чуток переписал код под себя, но смысл остался тот же.
Сначала указываем провайдера.
Провайдер
packer { required_plugins { huaweicloud = { version ">= 0.4.0" source = "github.com/huaweicloud/huaweicloud" } } }
Потом несколько переменных.
Переменные
# Объявление переменных variable "sber_access_key" { type = string description = "Access_key для сбера" } variable "sber_secret_key" { type = string description = "Secret_key для сбера" } variable "ECS_enterprise_project" { type = string description = "Тип проекта" } variable "vpc_id" { type = string description = "Id vpc" } variable "source_image_name" { type = string description = "Первоначальный образ" } variable "security_groups_test_back" { description = "Группы безопасности для тестового бэка" } variable "security_groups_test_front" { description = "Группы безопасности для тестового фронта" }
Самое интересное и важное, на какой виртуалке создавать образ.
Ну и блок build, в котором описываем что билдим и какой provisioner используем(код ansible не буду показывать, так как смысл статьи в другом)
Настройка виртуальной машины и блок build
# Настройки на какой машине образ будет билдиться source "huaweicloud-ecs" "test-back" { region = "cn-north-1" access_key = var.sber_access_key secret_key = var.sber_secret_key flavor = "c6.large.2" image_name = "test-back" source_image_name = var.source_image_name vpc_id = var.vpc_id subnets = ["5abf333d-9592-44a8-9833-7fada04c5b24"] security_groups = var.security_groups_test_back ssh_ip_version = "4" ssh_username = "root" } build { sources = ["source.huaweicloud-ecs.test-back"] provisioner "ansible" { playbook_file = "../Ansible/playbook.yml" } }
Весь код в листинге ниже, вдруг кому то захочется скопипастить не рабочий код)
Не рабочий, но полезный для понимания код
packer { required_plugins { huaweicloud = { version ">= 0.4.0" source = "github.com/huaweicloud/huaweicloud" } } } # Объявление переменных variable "sber_access_key" { type = string description = "Access_key для сбера" } variable "sber_secret_key" { type = string description = "Secret_key для сбера" } variable "ECS_enterprise_project" { type = string description = "Тип проекта" } variable "vpc_id" { type = string description = "Id vpc" } variable "source_image_name" { type = string description = "Первоначальный образ" } variable "security_groups_test_back" { description = "Группы безопасности для тестового бэка" } variable "security_groups_test_front" { description = "Группы безопасности для тестового фронта" } # Настройки на какой машине образ будет билдиться source "sbercloud_compute_instance" "test-back" { region = "cn-north-1" access_key = var.sber_access_key secret_key = var.sber_secret_key flavor = "c6.large.2" image_name = "test-back" source_image_name = var.source_image_name vpc_id = var.vpc_id subnets = ["5abf333d-9592-44a8-9833-7fada04c5b24"] security_groups = var.security_groups_test_back ssh_ip_version = "4" ssh_username = "root" } build { sources = ["source.huaweicloud-ecs.test-back"] provisioner "ansible" { playbook_file = "../Ansible/playbook.yml" } }
Запускаем и получаем ошибку авторизации, мол таких ключей нет, и тут снова логичней некуда, он пытается стукнуться в Huawei cloud, а мы же со SberCloud.
На самом деле почти победа, нужно внести маленькие правочки, до них можно догадаться если обратиться к Terraform провайдеру (да да они похожи).
Редактировать будем 1 блок, а именно source.
Правка блока с настройками виртуальной машины
# Настройки на какой машине образ будет билдиться source "huaweicloud-ecs" "test-back" { auth_url = "https://iam.ru-moscow-1.hc.sbercloud.ru/v3" region = "ru-moscow-1" access_key = var.sber_access_key secret_key = var.sber_secret_key flavor = "c6.large.2" image_name = "test-back" source_image_name = var.source_image_name vpc_id = var.vpc_id subnets = ["5abf333d-9592-44a8-9833-7fada04c5b24"] security_groups = var.security_groups_test_back ssh_ip_version = "4" ssh_username = "root" }
Самые важные изменения находятся в строках 3 и 4. Мы говорим явно какая ссылка для авторизации, ну и регион меняем на правильный.
Запуск...
Барабанная дробь
Бинго, всё работает.
Теперь приложу рабочий код, его можно смело копипастить и оно заработает)
Рабочий код конфигурации
packer { required_plugins { huaweicloud = { version ">= 0.4.0" source = "github.com/huaweicloud/huaweicloud" } } } # Объявление переменных variable "sber_access_key" { type = string description = "Access_key для сбера" } variable "sber_secret_key" { type = string description = "Secret_key для сбера" } variable "ECS_enterprise_project" { type = string description = "Тип проекта" } variable "vpc_id" { type = string description = "Id vpc" } variable "source_image_name" { type = string description = "Первоначальный образ" } variable "security_groups_test_back" { description = "Группы безопасности для тестового бэка" } variable "security_groups_test_front" { description = "Группы безопасности для тестового фронта" } # Настройки на какой машине образ будет билдиться source "huaweicloud-ecs" "test-back" { auth_url = "https://iam.ru-moscow-1.hc.sbercloud.ru/v3" region = "ru-moscow-1" access_key = var.sber_access_key secret_key = var.sber_secret_key flavor = "c6.large.2" image_name = "test-back" source_image_name = var.source_image_name vpc_id = var.vpc_id subnets = ["5a33d-9592-44a8-9833-7fada04c5b24"] security_groups = var.security_groups_test_back ssh_ip_version = "4" ssh_username = "root" } # Настройки билда образов build { sources = ["source.huaweicloud-ecs.test-back"] provisioner "ansible" { playbook_file = "../Ansible/playbook.yml" } }
Вывод
С этой задачкой я жарился два дня, скорее всего из-за неопытности, но путь пройден и теперь это не проблема)
Надеюсь статья будет полезна для таких же новичков, как и я. И сэкономит очень много времени и нервных клеток.
