Для управления облачной инфраструктурой Beget помимо панели управления и API можно использовать Terraform.
Terraform-провайдер Beget представляет собой альтернативный метод управления облачными ресурсами, позволяя декларативно описать желаемое состояние, после чего Terraform самостоятельно создаст, изменит или удалит описанные ресурсы. Подобный подход позволяет легко управлять и версионировать состояние облачной инфраструктуры.
На данный момент Terraform-провайдер Beget позволяет управлять жизненным циклом:
- виртуальных серверов и их снапшотов;
- бакетов S3;
- собственных образов виртуальных серверов;
- приватных сетей;
- дополнительных IPv4-адресов;
- SSH-ключей.
Также вы можете получать информацию о:
- доступных конфигурациях серверов;
- реквизитах доступа к бакетам S3;
- собственных образах виртуальных серверов;
- лицензиях ISP Manager;
- приватных сетях;
- регионах;
- доступном для установки ПО из Marketplace.
Актуальный список возможностей, ресурсов и источников данных для Terraform, а также примеры использования вы можете найти в нашем репозитории на GitHub:
Примеры конфигураций
Предположим, мы хотим создать 2 сервера в одной приватной сети с конфигурациями:
- Регион Санкт-Петербург (ru1), 1 ядро CPU, линейка CPU – Standard 3+ GHz (
normal_cpu), 1 ГБ оперативной памяти, 20 ГБ дискового пространства. - Регион Санкт-Петербург (ru1), линейка CPU – High-Freq 5+ Ghz (
high_cpu), 2 ядра CPU, 4 ГБ оперативной памяти, 50 ГБ дискового пространства.
Файл плана инфраструктуры в таком случае может выглядеть следующим образом:
# Добавляем Terraform-провайдера Beget
terraform {
required_providers {
beget = {
source = "tf.beget.com/beget/beget"
}
}
}
# Задаем ключ API облака Beget, необходимый для работы провайдера
provider "beget" {
token = "JWT_token"
}
# Создаем ресурс публичного SSH-ключа
resource "beget_ssh_key" "devops" {
name = "Terraform machine key"
# Можно указать как путь до файла ключа с помощью file(), так и сам ключ в виде строки
public_key = file("/home/betutorial/.ssh/id_ed25519.pub")
}
# Создаем ресурс приватной сети в нужном регионе
resource "beget_private_network" "ru1" {
region = "ru1"
}
# Источники данных позволяют получить необходимую для установки ПО информацию – например, его ID
data "beget_software" "gitea" {
slug = "gitea"
}
# В некоторых случаях для установки ПО требуются дополнительные данные.
# Узнать доступные переменные и являются ли они обязательными можно следующим способом:
locals {
gitea_vars = {
for v in data.beget_software.gitea.variables :
v.variable => {
label = v.label
required = v.is_required
description = v.description
}
}
}
# Для вывода значений переменных используется конструкция output:
output "gitea_variables" {
value = local.gitea_vars
}
# Создаем ресурс виртуального сервера
resource "beget_compute_instance" "gitea" {
name = "Gitea"
description = "Gitea server, provisioned with Terraform"
hostname = "gitea-ru1"
region = "ru1"
# Список добавляемых на сервер ключей SSH, для создания сервера требуется как минимум один
access = {
ssh_keys = [beget_ssh_key.devops.id]
}
# Конфигурация VPS
configuration = {
cpu_class = "normal_cpu"
cpu = 1
ram_mb = 1 * 1024
disk_mb = 20 * 1024
}
image = {
software = {
# Для установки ПО обязательно указать его ID, чтобы его получить, можно использовать data source beget_software
id = data.beget_software.gitea.id
# Объект с дополнительными переменными устанавливаемого ПО
# Для некоторого ПО они могут быть обязательны – например, для установки Gitea требуется указать домен, а также email и пароль администратора
vars = {
beget_fqdn = "gitea.betutorial.ru"
beget_email = "example@betutorial.ru"
beget_gitea_password = "5gnA41#1f"
}
}
}
# Добавляем сервер в приватную сеть
private_networks = {
(beget_private_network.ru1.id) = {
# При необходимости можно явно указать приватный IP сервера
address = "10.0.0.10"
}
}
}
data "beget_software" "docker" {
slug = "docker"
}
resource "beget_compute_instance" "gitea_runner" {
name = "Gitea Runner 00"
description = "Terraform-provisioned Gitea runner"
hostname = "gitea-runner-ru1-00"
region = "ru1"
access = {
ssh_keys = [beget_ssh_key.devops.id]
}
configuration = {
# Здесь указываем другую линейку процессора
cpu_class = "high_cpu"
cpu = 2
ram_mb = 4 * 1024
disk_mb = 50 * 1024
}
image = {
# Для установки некоторого ПО дополнительные данные не требуются.
# В таком случае указывать поле vars необязательно.
software = {
id = data.beget_software.docker.id
}
}
private_networks = {
(beget_private_network.ru1.id) = {
# Если поле address не указано, IP в приватной сети будет выдан автоматически
}
}
}
# Помимо получения информации, необходимой для создания сервера, с помощью output можно получить статус созданных ресурсов.
output "compute_instances" {
value = [for i in [beget_compute_instance.gitea, beget_compute_instance.gitea_runner] : {
id = i.id
name = i.name
ip_address = i.ip_address
software_domain = i.software_domain
private_networks = i.private_networks
status = i.status
configuration = i.configuration
}]
}
Пример конфигурации с загрузкой собственного образа операционной системы и созданием виртуального сервера на его основе:
- Регион Москва (ru2), 2 ядра CPU, линейка CPU – Standard 3+ GHz (normal_cpu), 2 ГБ оперативной памяти, 30 ГБ дискового пространства.
# Добавляем Terraform-провайдера Beget
terraform {
required_providers {
beget = {
source = "tf.beget.com/beget/beget"
}
}
}
# Задаем ключ API облака Beget, необходимый для работы провайдера
provider "beget" {
token = "JWT_token"
}
# Создаем ресурс публичного SSH-ключа
resource "beget_ssh_key" "devops" {
name = "Terraform machine key"
# Можно указать как путь до файла ключа с помощью file(), так и сам ключ в виде строки
public_key = file("/home/betutorial/.ssh/id_ed25519.pub")
}
# Загружаем собственный образ в ту же локацию, где будет развернут сервер
resource "beget_compute_image" "alpine_cloud_image" {
name = "alpine-cloud-image"
region = "ru2"
source = {
# Указываем URL, по которому доступен файл образа
url = "https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/cloud/nocloud_alpine-3.23.2-x86_64-bios-cloudinit-r0.qcow2"
}
}
# Создаем ресурс виртуального сервера
resource "beget_compute_instance" "alpine" {
name = "Alpine"
description = "Alpine Linux server, provisioned with Terraform"
hostname = "alpine-ru2"
region = "ru2"
# Список добавляемых на сервер ключей SSH, для создания сервера требуется как минимум один
access = {
ssh_keys = [beget_ssh_key.devops.id]
}
# Конфигурация VPS
configuration = {
cpu_class = "normal_cpu"
cpu = 2
ram_mb = 2 * 1024
disk_mb = 30 * 1024
}
image = {
# Указываем ID образа
image_id = beget_compute_image.alpine_cloud_image.id
}
}
# Помимо получения информации, необходимой для создания сервера, с помощью output можно получить статус созданных ресурсов
output "compute_instances" {
value = {
id = beget_compute_instance.alpine.id
name = beget_compute_instance.alpine.name
ip_address = beget_compute_instance.alpine.ip_address
software_domain = beget_compute_instance.alpine.software_domain
private_networks = beget_compute_instance.alpine.private_networks
status = beget_compute_instance.alpine.status
configuration = beget_compute_instance.alpine.configuration
}
}
output "compute_image" {
value = {
id = beget_compute_image.alpine_cloud_image.id
disk_size_bytes = beget_compute_image.alpine_cloud_image.disk_size_bytes
price = beget_compute_image.alpine_cloud_image.price
size_bytes = beget_compute_image.alpine_cloud_image.size_bytes
status = beget_compute_image.alpine_cloud_image.status
}
}
Пример конфигурации для создания бакета S3 с подключенным поддоменом и настройками CORS.
# Добавляем Terraform-провайдера Beget
terraform {
required_providers {
beget = {
source = "tf.beget.com/beget/beget"
}
}
}
# Задаем ключ API облака Beget, необходимый для работы провайдера
provider "beget" {
token = "JWT_token"
}
# Создаем бакет S3
resource "beget_s3_bucket" "main" {
name = "S3 storage bucket"
description = "S3 storage bucket, provisioned with Terraform"
# На данный момент для создания бакетов S3 доступен только регион ru1
region = "ru1"
# Вы можете указать поддомен, по которому будут доступны ресурсы бакета. Это необязательное поле, его можно оставить пустым.
domain = "static.betutorial.ru"
# При необходимости вы можете указать настройки CORS для бакета.
cors = [{
allowed_methods = ["GET", "HEAD"]
allowed_origin = "https://example.com"
allowed_headers = ["*"]
expose_headers = ["ETag", "Content-Length"]
max_age_seconds = 3600
}, {
allowed_methods = ["GET", "PUT", "POST", "DELETE"]
allowed_origin = "*"
allowed_headers = ["Authorization", "Content-Type"]
expose_headers = ["ETag"]
max_age_seconds = 1800
}]
}
# Помимо получения информации, необходимой для создания сервера, с помощью output можно получить статус созданных ресурсов и другую информацию - например, реквизиты доступов к бакетам
output "bucket" {
value = {
id = beget_s3_bucket.main.id
name = beget_s3_bucket.main.name
domain = beget_s3_bucket.main.domain
}
}
output "s3_credentials" {
value = {
url = beget_s3_bucket.main.s3_access.url
bucket_name = beget_s3_bucket.main.s3_access.bucket_name
access_key = nonsensitive(beget_s3_bucket.main.s3_access.access_key)
secret_key = nonsensitive(beget_s3_bucket.main.s3_access.secret_key)
}
}
output "ftp_credentials" {
value = {
host = beget_s3_bucket.main.ftp.host
port = beget_s3_bucket.main.ftp.port
login = nonsensitive(beget_s3_bucket.main.ftp.login)
password = nonsensitive(beget_s3_bucket.main.ftp.password)
status = beget_s3_bucket.main.ftp.status
}
}
output "sftp_credentials" {
value = {
host = beget_s3_bucket.main.sftp.host
port = beget_s3_bucket.main.sftp.port
login = nonsensitive(beget_s3_bucket.main.sftp.login)
password = nonsensitive(beget_s3_bucket.main.sftp.password)
status = beget_s3_bucket.main.sftp.status
}
}Подробная документация и описание структуры различных ресурсов доступны в репозитории:
Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить Terraform или другие наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.