Цель
Не жарить, а печь.
Задача
Подружить 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"
}
}
Вывод
С этой задачкой я жарился два дня, скорее всего из-за не опытности, но путь пройден и теперь это не проблема)
Надеюсь статья будет полезна для новичков как и я. И сэкономит очень много времени и нервных клеток.