Как я дружил Packer со SberCloud

от автора

Цель

Не жарить, а печь.

Задача

Подружить Packer с облачным провайдером SberCloud

Вступление

Привет! Я начинающий DevOps инженер, на неделе была поставлена цель перейти от создания облачной инфраструктуры ручками к IaaC посредством внедрения Packer + Terraform + Ansible. Если у сбера есть провайдер для Terraform, но для Packer провайдер не завезли.

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

Нашёл единственную статью на habr.com от компании КРОК и их облаке которое построено по принципу AWS. Исходя из это статьи начал копать, а именно узнал по какому принципу сделано облако сбера, немного почитав документацию понял — облако сделано по принципу Huawei Cloud. И о везение, существует провайдер Huawei Cloud — ссылочка на доку.

Жарка с провайдером Huawei Cloud

Казалось бы всё, победа! Но не тут то было, посмотрим на базовый пример для создания образа в облаке Huawei

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_TestBack22" {   ... }

Обратим внимание на «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 не буду показывать, так как смысл статьи в другом)

# Настройки на какой машине образ будет билдиться 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         = ["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"     } } 

Вывод

С этой задачкой я жарился два дня, скорее всего из-за не опытности, но путь пройден и теперь это не проблема)

Надеюсь статья будет полезна для новичков как и я. И сэкономит очень много времени и нервных клеток.


ссылка на оригинал статьи https://habr.com/ru/post/676008/