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

Terraform — это инструмент автоматизации OpenStack, позволяющий описать параметры инфраструктуры (серверов, сети, дисков и т.д.) в конфигурационном файле, чтобы потом всё это дело разворачивать одной командой. В этой статье рассмотрим, как это работает.

Установка

1. Установите Terraform по инструкции.

2. Проверьте версию и корректность установки:

terraform -version

Структура проекта

У Terraform вся логика разбита на несколько файлов. Это не обязательно, но такая структура — стандарт де-факто: она позволяет не смешивать ресурсы, переменные и результаты в одном месте.

Создайте четыре файла в каталоге, где планируете развёртывать среды. Они должны называться так же, как и в примере. Шаблоны содержимого для каждого из файлов даем далее в статье.

my-project/
├── variables.tf # переменные (что можно настроить)
├── terraform.tfvars # значения переменных (конкретные значения)
├── main.tf # основные ресурсы (что именно создаём)
└── outputs.tf # вывод (что получим на выходе)

Аутентификация

Происходит с помощью файла clouds.yaml. О том, как его настроить, мы рассказывали в отдельной статье о работе с облаком OpenStack через API. Служба Terraform OpenStack также использует этот файл в своей работе.

Как управлять облаком OpenStack через API

Конфигурация

Как мы уже говорили, стандартная логика работы Terraform предполагает использование четырех файлов: variables.tf, terraform.tfvars, main.tf и outputs.tf. В этом разделе – что должно быть в каждом из них.

variables.tf

Это файл, где вы объявляете все переменные, которые вы будете использовать. Без него Terraform не поймет, откуда брать значение.

Вот пример содержимого файла, в котором:

  • description — просто подсказка для вас;
  • default — значение по умолчанию (можно не задавать).

Если нет default — значение обязательно нужно передать через файл terraform.tfvars.

variable "cloud_name" {
description = "Профиль з clouds.yaml"
default = "openstack-ua"
}

variable "server_name" {
description = "Имя сервера"
default = "my-server"
}

variable "image_id" {
description = "ID образа ОС"
}

variable "flavor_id" {
description = "ID конфигурации сервера"
}

variable "network_id" {
description = "ID сети (Public)"
}

variable "volume_size" {
description = "Размер загрузочного диска в ГБ"
default = 50
}

variable "key_name" {
description = "Имя SSH-ключа"
}

variable "security_group_id" {
description = "ID существующей security group (опционально — если не задано, будет создана новая)"
default = ""

terraform.tfvars

Здесь вы уже не описываете, а подставляете реальные данные. Это как файл .env в обычных проектах. Именно этот файл Terraform автоматом подхватывает при запуске. Подставьте у него реальные значения из панели (Project → API Access) или из результатов команд:

openstack --os-cloud=openstack-nl image list
openstack --os-cloud=openstack-nl flavor list
openstack --os-cloud=openstack-nl network list
openstack --os-cloud=openstack-nl security group list
openstack --os-cloud=openstack-nl keypair list 
cloud_name        = "openstack-nl"
server_name = "my-server"
image_id = "PASTE_IMAGE_ID"
flavor_id = "PASTE_FLAVOR_ID"
network_id = "PASTE_PUBLIC_NETWORK_ID"
volume_size = 50
key_name = "PASTE_KEY_NAME"
security_group_id = "PASTE_SG_ID" 

⚠️ Нюанс : Этот файл часто содержит чувствительные или привязанные к среде данные, поэтому его не комментируют в git. Разместите его в .gitignore.

main.tf

Это главный файл. В нём описаны ресурсы, которые Terraform должен быть создан. В нём ничего менять не нужно, просто скопируйте содержимое как есть.

terraform {
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.54"
}
}
}

# Провайдер — читає credentials з clouds.yaml
provider "openstack" {
cloud = var.cloud_name
}

# SSH-ключ — використовуємо наявний
data "openstack_compute_keypair_v2" "keypair" {
name = var.key_name
}

# Сервер — використовуємо існуючу security group з панелі
resource "openstack_compute_instance_v2" "server" {
name = var.server_name
flavor_id = var.flavor_id
key_pair = data.openstack_compute_keypair_v2.keypair.name

security_groups = [var.security_group_id]

# Boot from volume — обов'язково для нашої хмари
block_device {
uuid = var.image_id
source_type = "image"
destination_type = "volume"
volume_size = var.volume_size
boot_index = 0
delete_on_termination = true
}

network {
uuid = var.network_id
}
}

outputs.tf

После команды terraform apply вы обычно хотите получить не просто «успешно», а полезные данные — например IP сервера. Что конкретно нужно вывести – описывают в этом файле. В нашем примере файла будет отображаться ID сервера, его имя, публичный IP и команда для подключения по SSH.

output "server_id" {
value = openstack_compute_instance_v2.server.id
}

output "server_name" {
value = openstack_compute_instance_v2.server.name
}

output "public_ip" {
description = "Публичный IP-адрес сервера"
value = openstack_compute_instance_v2.server.access_ip_v4
}

output "ssh_command" {
description = "Команда для подключения по SSH"
value = "ssh clouduser@${openstack_compute_instance_v2.server.access_ip_v4}"
}

Базовый воркфлоу

Вот пример типичного взаимодействия с Terraform после настройки всех необходимых файлов.

Инициализация (один раз)

Заходим в каталог, где будет создаваться сервер и запускаем Terraform:

cd my-server
terraform init

Просмотреть, что будет создано

Смотрим список ресурсов, которые будут созданы — без реальных изменений.

terraform plan

Развернуть

terraform apply

Разворачиваем конфигурацию. Terraform снова покажет план и спросит подтверждения. После ввода yes создаст все ресурсы и выведет outputs:

Outputs:

public_ip = "185.91.72.xxx"
server_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
server_name = "my-server"
ssh_command = "ssh clouduser@185.91.72.xxx"

Как подключиться к облачному VPS

Удалить всё

Удалить все ресурсы, которые создал этот шаблон — сервер, диск, security group и т.д.

terraform destroy

Часто задаваемые вопросы

Вот несколько ситуаций, с которыми часто сталкиваются пользователи Terraform.

Предупреждение о loadbalancer/neutron-lbaas при plan/apply – что делать?

Игнорировать. Это предупреждение касается балансировщика нагрузки, который мы не используем у себя на хостинге.

Как узнать IP-сервер после развертывания?

Выполнить команду для вывода IP:

terraform output public_ip

Или команду для подключения:

terraform output ssh_command

Как изменить размер сервера после создания?

Сменить flavor_id в terraform.tfvars и запустить terraform apply. В результате Terraform удалит старый сервер и создаст другой уже с новыми параметрами.

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

Как изменить характеристики облачного VPS

Как посмотреть текущее состояние инфраструктуры?

terraform show

Как развернуть такой же сервер в Украине?

Изменить в terraform.tfvars:

cloud_name = "openstack-ua"

Изменить в terraform.tfvars:

И подставить соответствующие ID ресурсов для UA региона – image, flavor, network, security group, keypair в UA другие, чем у NL. Получи их командами:

openstack --os-cloud=openstack-ua image list
openstack --os-cloud=openstack-ua flavor list
openstack --os-cloud=openstack-ua network list
openstack --os-cloud=openstack-ua security group list
openstack --os-cloud=openstack-ua keypair list

При переключении между регионами (NL → UA или наоборот) Terraform выдает ошибку об endpoint?

Провайдер закэшировал состояние предыдущего региона. Следует очистить его и инициализировать повторно:

rm -rf .terraform .terraform.lock.hcl terraform.tfstate terraform.tfstate.backup
terraform init
terraform plan

Полезные ссылки

OpenStack Terraform провайдер

Документация Terraform

Compute ресурсы

Networking ресурсы