VMmanager, управление инфраструктурой через VMmanager API и Ansible
Привет, Хабр! Статья будет посвящена любимому мной IaC. Чтобы ввести в курс дела, кратко расскажу про VMmanager и текущую реализацию продукта. Затронем варианты, как можно работать с VMmanager с подходом Infrastructure as Code, а основная часть — про развертывание платформы VMmanager и управление виртуальными машинами в ней с помощью Ansible.
О платформе VMmanager
Наверняка вы уже знаете, что такое VMmanager. Это платформа управления виртуализацией. Она имеет версии VMmanager Hosting и VMmanager Infrastructure — под разные цели использования.
Версия | Hosting | Infrastructure |
Назначение | — ориентирована на потребности хостинг-провайдеров | — ориентирована на потребности владельцев IT-инфраструктур |
Состав | — базовая функциональность платформы | — базовая функциональность платформы |
Дополнительно | — | — регистрация в Едином реестре российских программ для электронных вычислительных машин и баз данных |
VMmanager — один из продуктов ISPsystem, он имеет интеграцию с другими продуктами, на схеме кратко и просто представлена их взаимосвязь.

Я буду работать с VMmanager Infrastructure.
IaC-решения
Для реализации подхода Infrastructure as Code в работе с VMmanager у нас есть сценарий развертывания платформы с помощью Ansible, примеры управления инфраструктурой через провайдер Terraform и работа с платформой с использованием VMmanager API. Все это представлено в документации.
По работе с Terraform уже была подробная статья. Поэтому сосредоточимся на Ansible. С помощью готового сценария мы развернем платформу, посмотрим, что из себя представляет сценарий (спойлер: набор плейбуков с задачами, использующими модуль ansible.builtin.uri). А для управления виртуальными машинами на платформе я погружусь в VMmanager API и напишу собственный модуль на Python.
Управление инфраструктурой через VMmanager API и Ansible
Развертывание платформы с помощью Ansible
Начнем с подготовки серверов для платформы VMmanager, понадобится Astra Linux версии 1.8.1 уровня защиты «Орел». У меня есть такой образ, его я и буду разворачивать в Yandex Cloud. Узел кластера для тестирования можно не разворачивать: в VMmanager для таких целей можно настроить кластер-заглушку, это нужно сделать уже после создания кластера.
Настройку серверов для платформы и узла кластера я не буду приводить в статье по двум причинам: во-первых, в документации очень подробно и точно описаны шаги — можно смело по ним идти, все получится; во-вторых, тема статьи о другом и будет неуместно сюда из документации репостить объемный материал. Но приведу несколько замечаний, которые при аналогичном развертывании на виртуальной машине Yandex Cloud могут быть полезны.
Из всех пунктов мне понадобилось только отредактировать /etc/apt/sources.list. Остальное я оставил по умолчанию.
Раздел «Настройка подключения к узлам кластера» можно пропустить, если настраиваем кластер-заглушку.
Переходим к развертыванию VMmanager. В документации есть step-by-step по установке VMmanager с помощью Ansible. Но, поскольку шагов не так много и это уже про IaC, я перепишу в статью все шаги, немного добавив пояснений.
Для начала стоит сказать, что для активации платформы понадобится лицензия. У меня есть триал, получил за красивые глаза, но это не обязательный навык для работы с VMmanager.
Все продукты ISPsystem доступны для бесплатного тестирования. По запросу на сайте получите бесплатный триал или доступ к демостенду. Также можно заказать демонстрацию интересующих платформ на сайте: DCImanager, VMmanager, BILLmanager, DNSmanager.
Нас все еще интересует триал для VMmanager.
Переходим к установке платформы.
Установим Ansible на ПК, с которого будет запускаться установка платформы. Порядок установки в официальной документации Ansible.
На ПК с Ansible:
Если на ПК не установлена утилита curl, установите ее:
dnf install curl || apt install curlСкачайте сценарии установки:
curlhttps://download.ispsystem.com/extras/ansible/vmmanager6_common.tar.gzСоздайте SSH-ключ и скопируйте его на сервер платформы. Подробнее — в статье про SSH-протокол.
Создадим директорию для сценариев установки:
mkdir vm6_ansibleРаспакуем в директорию архив со сценариями:
tar xzf vmmanager6_common.tar.gz -C vm6_ansible/Перейдем в созданную директорию:
cd vm6_ansibleУкажем параметры установки в секции vars файла vmmanager6.yml:
vars:
vmi_first_username: "admin@example.com"
vmi_first_password: "q1w2e3r4"
vmmanager6_license_token: "..........:..................."
vmi_domain: "{{ ansible_ssh_host }}"
# Поскольку я разворачивал виртуальную машину в Yandex Cloud,
# параметры сети берем по факту, в которой разворачиваем.
vmi_network: "10.177.91.0/24"
vmi_network_gateway: "10.177.91.1"
vmi_network_note: "some network notes"
vmi_pool_name: "some_pool"
vmi_pool_note: "testing pool"
vmi_cluster_name: "new_cluster"
vmi_time_zone: "UTC"
vmi_cluster_note: "some cluster note"
vmi_domain_template: ".example.com"
# Я указал для check ip из настроек dns, но он нам не понадобится в рамках теста.
vmi_node_check_ip: "10.177.181.142"
# Мы далее закомментируем все, что касается ssl и бэкапа, поэтому следующие
# настройки можно не трогать.
vmi_certificate: "-----BEGIN CERTIFICATE-----\nMIIDkT……7s=\n-----END CERTIFICATE-----\n"
vmi_certificate_key: "-----BEGIN PRIVATE KEY-----\nMI….BlXDeTd\n-----END PRIVATE KEY-----\n"
vmi_certificate_ca: ""
vmi_backup_ip: "10.177.91.71"
vmi_backup_user: "root"
vmi_backup_password: "q1w2e3p4"
vmi_backup_path: "/backup"Мы не планируем подключать SSL-сертификат, закомментируем в файле vmmanager6.yml строку:
# - include_tasks: cert.ymlРезервное копирование платформы мы также не планируем, закомментируем в файле vmmanager6.yml строку:
# - include_tasks: backup.ymlЗапустим установку:
ansible-playbook -i, -u root vmmanager6.yml Вместо
укажите ip своей виртуальной машины.
Посмотрим немного глубже в Ansible-сценарий установки VMmanager. В распакованном архиве мы видим набор плейбуков.

Основной плейбук vmmanager6.yml, в который подключаются по порядку остальные плейбуки для установки.
---
- name: Install VMmanager 6 playbook
hosts: all
debugger: on_failed
vars:
vmi_first_username: "admin@example.com"
vmi_first_password: "q1w2e3r4"
vmmanager6_license_token: ".............:................"
vmi_domain: "{{ ansible_ssh_host }}"
vmi_network: "10.177.91.0/24"
vmi_network_gateway: "10.177.91.1"
vmi_network_note: "some network notes"
vmi_pool_name: "some_pool"
vmi_pool_note: "testing pool"
vmi_cluster_name: "new_cluster"
vmi_time_zone: "UTC"
vmi_cluster_note: "some cluster note"
vmi_domain_template: ".example.com"
vmi_node_check_ip: "10.177.181.142"
vmi_certificate: "-----BEGIN CERTIFICATE-----\nMIIDkT……7s=\n-----END CERTIFICATE-----\n"
vmi_certificate_key: "-----BEGIN PRIVATE KEY-----\nMI….BlXDeTd\n-----END PRIVATE KEY-----\n" vmi_certificate_ca: ""
vmi_backup_ip: "10.177.91.71"
vmi_backup_user: "root"
vmi_backup_password: "q1w2e3p4"
vmi_backup_path: "/backup"
tasks:
- include_tasks: remove_and_install.yml
- name: First time token
uri:
url: "https://{{ vmi_domain }}/auth/v4/public/token"
method: POST
body_format: json
status_code: [200,201,503]
return_content: yes
body:
email: "{{ vmi_first_username }}"
password: "{{ vmi_first_password }}"
validate_certs: no
register: first_token
retries: 3
delay: 30
until: first_token.status == 201
- name: make ses6 a fact
set_fact:
ses6: "{{ (first_token.content|from_json).token }}"
- include_tasks: first_run.yml
# - include_tasks: cert.yml
- include_tasks: setup_ip.yml
- include_tasks: cluster.yml
- include_tasks: storage.yml
# - include_tasks: backup.ymlПосмотрим на один из плейбуков cluster.yml, чтобы разобраться, что происходит при установке. Мы видим, что сценарий построен на использовании модуля ansible.builtin.uri.
---
- name: Set up cluster
uri:
# В документации API можем посмотреть url для создания кластера, и другие url,
# а также параметры, которые мы можем передать.
url: "https://{{ vmi_domain }}/vm/v3/cluster"
method: POST
body_format: json
status_code: [200, 401, 409, 500, 503]
headers:
Cookie: "ses6={{ ses6 }}"
x-xsrf-token: "{{ ses6 }}"
body:
name: "{{ vmi_cluster_name }}"
virtualization_type: "kvm"
time_zone: "{{ vmi_time_zone }}"
dns_servers:
- "1.1.1.1"
comment: "{{ vmi_cluster_note }}"
os:
- 1
iso_enabled: false
manage_disk_enabled: false
domain_template: "{{ vmi_domain_template }}"
domain_change_allowed: false
overselling: 1
host_per_node_limit: -1
host_distribution_policy: "spread"
host_filter: []
backup_locations: []
image_storage_path: "/image"
os_storage_path: "/share"
datacenter_type: "common"
interfaces:
- interface: 0
ippool: [ 1 ]
node_network:
gateway: "{{ vmi_node_check_ip }}"
timeout: 300
vxlan_mode: "disabled"
validate_certs: no
register: cluster
retries: 3
delay: 10
until: cluster.status == 200С помощью переменных мы ранее задали все нужные значения, которые подтягиваются при выполнении задач. ansible.builtin.uri отправляет запросы для скачивания установочных файлов VMmanager API и инициализации установки. А далее происходит магия… Обращение к VMmanager API для создания кластера и его настройки.
Посмотрев на все задачи из сценария, можно увидеть, что работа с VMmanager API несложная, документации соответствует, такой сценарий вполне можно составить самостоятельно.
Далее нужно создать кластер в VMmanager — в документации пошагово представлено, как это сделать через веб-интерфейс, а затем настроить заглушку для кластера. Эти шаги я тоже оставляю за пределами статьи — по тем же причинам, что и настройка серверов.
Команда должна быть:
update vm_cluster set virtualization_type = 'dummy' where id =
Где «dummy» в одинарных кавычках.
Управление ВМ с помощью модуля ansible.builtin.uri
У меня готова платформа VMmanager, кластер настроен и подключен, самое время попробовать в IaC — будем создавать виртуальные машины. Научимся с простого варианта — с использованием модуля ansible.builtin.uri. Поскольку VMmanager API позволяет довольно гибко работать с платформой, будет полезно отработать быстрый вариант работы с API, если захочется использовать разные возможности управления.
Отмечу, что данный способ имеет определенный нюанс: мы не получаем контроль идемпотентности нашего Infrastructure as Code. VMmanager API обеспечивает идемпотентность только по id, что может быть удобно, когда мы не хотим иметь ограничение в именах виртуальных машин, но модуль ansible.builtin.uri это не обеспечит. В POST-запросе нельзя указать id, то есть создать виртуальную машину с конкретным id.
С точки зрения подхода идеально, когда за идемпотентность отвечает выбранный нами инструмент, а это Ansible. В нашем случае можно выбрать между скоростью разработки инфраструктурного кода и каноничностью принципов.
Для управления виртуальными машинами нам будет достаточно переиспользовать файл с переменными и создать сценарий. Сеть и пул IP-адресов уже созданы при развертывании платформы, учетную запись рекомендую создать отличную от админской, пользователя создадим из веб-интерфейса. А далее обратимся к документации API.
Заполним основной файл сценария — с переменными, авторизацией и вызовом сценария создания виртуальной машины.
---
- name: Install VMmanager 6 playbook
hosts: all
debugger: on_failed
vars:
vmi_first_username: "vm@example.com"
vmi_first_password: "uA2sW2nT9czV"
vmi_domain: "{{ ansible_ssh_host }}"
tasks:
- name: First time token
uri:
url: "https://{{ vmi_domain }}/auth/v4/public/token"
method: POST
body_format: json
status_code: [200,201,503]
return_content: yes
body:
email: "{{ vmi_first_username }}"
password: "{{ vmi_first_password }}"
validate_certs: no
register: first_token
retries: 3
delay: 30
until: first_token.status == 201
- name: make ses6 a fact
set_fact:
ses6: "{{ (first_token.content|from_json).token }}"
- include_tasks: vm.ymlИ напишем сам сценарий работы с виртуальными машинами.
–
# Для начала посмотрим, какие же виртуальные машины уже развернуты,
# указанный url выдаст все, без фильтрации.
- name: Get up vm
uri:
url: "https://{{ vmi_domain }}/vm/v3/host"
method: GET
body_format: json
status_code: [200, 401, 409, 500, 503]
headers:
Cookie: "ses6={{ ses6 }}"
x-xsrf-token: "{{ ses6 }}"
validate_certs: no
# Для тестирования мы передаем минимальный набор параметров.
- name: Set up vm
uri:
url: "https://{{ vmi_domain }}/vm/v3/host"
method: POST
body_format: json
status_code: [200, 401, 409, 500, 503]
headers:
Cookie: "ses6={{ ses6 }}"
x-xsrf-token: "{{ ses6 }}"
body:
name: My_vm
password: vmsecret
# Для cluster, ipv4_pool, os передаем id, в веб-интерфейсе все они указаны,
# можно посмотреть.
cluster: 1
os: 1
ram_mib: 512
hdd_mib: 5000
cpu_number: 1
ipv4_pool: [1]
validate_certs: noУправление ВМ с помощью своего модуля Ansible
Настало время перейти к технически интересному варианту, полностью соответствующему подходу Infrastructure as Code. Я напишу собственный модуль на Python для создания виртуальных машин в VMmanager. Грамотно написанный модуль обеспечит на стороне Ansible идемпотентность нашего инфраструктурного кода.
Если быть точными, то мы напишем два модуля vm_info, vm и два вспомогательных модуля auth_utils и info_utils. Это будет полностью соответствовать рекомендациям Ansible, а именно выносить сбор информации, не вносящий изменения в инфраструктуру, в модуль info, общий код модулей — во вспомогательные модули.
Начнем с модуля auth_utils. Он нужен для авторизации, при вызове других модулей мы получаем токен и возвращаем его в вызвавший авторизацию модуль.
# -*- coding: utf-8 -*-
import json
import time
import urllib3
from ansible.module_utils.urls import open_url, SSLValidationError
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def get_auth_token(base_url, email, password, retries=3, delay=30, validate_certs_param=None, module=None):
"""
Получение токена авторизации через API VMI.
:param base_url: Базовый URL (например, https://vmi.example.com)
:param email: Логин пользователя
:param password: Пароль
:param retries: Количество попыток
:param delay: Задержка между попытками
:param validate_certs_param: строка 'no' или None (если не передан параметр)
:param module: ссылка на AnsibleModule для вывода ошибок
:return: токен сессии
"""
url = f"{base_url}/auth/v4/public/token"
headers = {
'Content-Type': 'application/json'
}
body = json.dumps({
"email": email,
"password": password
})
last_exception = None
for attempt in range(1, retries + 1):
try:
kwargs = {
"url": url,
"method": "POST",
"headers": headers,
"data": body,
}
if validate_certs_param == "no":
kwargs["validate_certs"] = False
response = open_url(**kwargs)
if response.getcode() in (200, 201):
result = json.loads(response.read())
return result.get("token")
except (SSLValidationError) as e:
last_exception = e
if module:
module.warn(f"Попытка {attempt} не удалась: {e}")
time.sleep(delay)
if module:
module.fail_json(msg="Не удалось получить токен после нескольких попыток", exception=str(last_exception))
else:
raise Exception(f"Ошибка получения токена: {last_exception}")Далее vm_info. Мы могли бы ограничиться только вспомогательным модулем, но будет более показательно реализовать модуль info полностью, тем более что он будет содержать минимальное количество базового кода.
#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.auth_utils import get_auth_token
from ansible.module_utils.info_utils import get_vmi_info
DOCUMENTATION = r'''
---
module: vmi_info
short_description: Получение информации о хосте по имени из VMI API
description:
- Получает токен через auth_utils.get_auth_token, затем делает GET запрос через info_utils.get_vmi_info
options:
vmi_domain:
description: Домен VMI без https://
required: true
type: str
vmi_first_username:
description: Email пользователя
required: true
type: str
vmi_first_password:
description: Пароль пользователя
required: true
type: str
name:
description: Имя хоста для фильтрации
required: true
type: str
validate_certs:
description:
- Отключает проверку SSL-сертификатов ('no' для отключения).
required: false
type: str
'''
EXAMPLES = r'''
- name: Получить информацию о хосте
vm_info:
vmi_domain: vmi.example.com
vmi_first_username: admin@example.com
vmi_first_password: secret
name: my-host
validate_certs: no
register: result
'''
def main():
module = AnsibleModule(
argument_spec=dict(
vmi_domain=dict(required=True, type='str'),
vmi_first_username=dict(required=True, type='str'),
vmi_first_password=dict(required=True, type='str'),
name=dict(required=True, type='str'),
validate_certs=dict(required=False, type='str'),
)
)
base_url = f"https://{module.params['vmi_domain']}"
email = module.params['vmi_first_username']
password = module.params['vmi_first_password']
name = module.params['name']
validate_certs = module.params.get('validate_certs')
# Получаем токен
token = get_auth_token(
base_url=base_url,
email=email,
password=password,
validate_certs_param=validate_certs,
module=module
)
# Формируем endpoint
endpoint = f"/vm/v3/host?where=(name+EQ+'{name}')"
# Получаем информацию
data = get_vmi_info(base_url, token, endpoint, validate_certs, module)
module.exit_json(changed=False, finder=data.get('size', []))
if __name__ == '__main__':
main()Теперь перейдем к вспомогательному модулю info_utils. Он нужен для реализации идемпотентности на стороне Ansible-модуля создания виртуальных машин. Через этот модуль мы будем получать информацию о текущей инфраструктуре.
# -*- coding: utf-8 -*-
from ansible.module_utils.urls import open_url
import json
def get_vmi_info(base_url, token, endpoint, validate_certs, module):
"""
Делает GET-запрос к API по endpoint с использованием токена.
:param base_url: базовый URL с https
:param token: токен авторизации ses6
:param endpoint: путь API начиная с /, например /vm/v3/host?where=(name+...
:param validate_certs: 'no' или None
:param module: объект AnsibleModule для fail_json
:return: распарсенный JSON из ответа
"""
url = f"{base_url}{endpoint}"
headers = {
'Accept': 'application/json',
'Cookie': f'ses6={token}',
'x-xsrf-token': token,
}
kwargs = {
'url': url,
'method': 'GET',
'headers': headers,
}
if validate_certs == 'no':
kwargs['validate_certs'] = False
try:
response = open_url(**kwargs)
return json.loads(response.read())
except Exception as e:
module.fail_json(msg=f"Ошибка при GET-запросе к {url}", error=str(e))Последним модулем будет vm. Запрашивая информацию о текущей инфраструктуре, мы будем сравнивать ее параметры со входными параметрами при вызове модуля и в случае совпадения текущего состояния и желаемого — не производить изменения, отдавая changed False.
#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.auth_utils import get_auth_token
from ansible.module_utils.info_utils import get_vmi_info
from ansible.module_utils.urls import open_url
import ssl
import http.client
import json
from urllib.parse import urlparse
DOCUMENTATION = r'''
---
module: vm
short_description: Управление виртуальной машиной в VM
description:
- Получает токен через get_auth_token.
- Проверяет наличие VM по имени через get_vmi_info.
- Создает VM если state=present и VM не существует.
options:
vmi_domain:
description: Домен VMI без https://
required: true
type: str
vmi_first_username:
description: Email пользователя
required: true
type: str
vmi_first_password:
description: Пароль пользователя
required: true
type: str
state:
description: Состояние VM
required: false
default: present
choices: [present, absent]
type: str
name:
description: Имя виртуальной машины
required: true
type: str
password:
description: Пароль для VM
required: true
type: str
cluster:
description: ID кластера
required: true
type: int
os:
description: ID операционной системы
required: true
type: int
ram_mib:
description: RAM в Мибибайтах
required: true
type: int
hdd_mib:
description: HDD в Мибибайтах
required: true
type: int
cpu_number:
description: Количество CPU
required: true
type: int
ipv4_pool:
description: Список ID пулов IPv4
required: true
type: list
elements: int
validate_certs:
description:
- Отключает проверку SSL-сертификатов ('no' для отключения).
required: false
type: str
'''
EXAMPLES = r'''
- name: Создать VM если отсутствует
vm:
vmi_domain: vmi.example.com
vmi_first_username: admin@example.com
vmi_first_password: secret
name: My_vm
password: vmsecret
cluster: 1
os: 1
ram_mib: 512
hdd_mib: 5000
cpu_number: 1
ipv4_pool: [1]
validate_certs: no
state: present
'''
def create_vm(base_url, token, vm_spec, validate_certs, module):
url = f"{base_url}/vm/v3/host"
body = json.dumps(vm_spec)
headers = {
'Content-Type': 'application/json',
'Cookie': f'ses6={token}',
'x-xsrf-token': token,
}
body = json.dumps(vm_spec)
kwargs = {
'url': url,
'method': 'POST',
'headers': headers,
'data': body,
}
if validate_certs == 'no':
kwargs['validate_certs'] = False
try:
response = open_url(**kwargs)
response_body = response.read().decode('utf-8')
if response.getcode() in (200, 201):
return json.loads(response_body)
else:
module.fail_json(msg=f"Ошибка создания VM. HTTP {response.getcode()}", response_body=response_body)
except Exception as e:
module.fail_json(msg="Ошибка при создании VM, проверьте статус узла кластера", kwargs=kwargs, error=str(e))
def run(base_url, token, state, validate_certs, module):
vm_name = module.params['name']
vm_password = module.params['password']
cluster = module.params['cluster']
os_id = module.params['os']
ram_mib = module.params['ram_mib']
hdd_mib = module.params['hdd_mib']
cpu_number = module.params['cpu_number']
ipv4_pool = module.params['ipv4_pool']
endpoint = f"/vm/v3/host?where=(name+EQ+'{vm_name}')"
vmi_info = get_vmi_info(base_url, token, endpoint, validate_certs, module).get('size', 0)
if state == 'present':
if vmi_info != 0:
# VM существует, ничего не меняем
module.exit_json(changed=False, finder=vmi_info)
else:
# Создаем VM
vm_spec = {
"name": vm_name,
"password": vm_password,
"cluster": cluster,
"os": os_id,
"ram_mib": ram_mib,
"hdd_mib": hdd_mib,
"cpu_number": cpu_number,
"ipv4_pool": ipv4_pool,
}
created_vm = create_vm(base_url, token, vm_spec, validate_certs, module)
module.exit_json(changed=True, vm=created_vm)
else:
# Поддержка state=absent можно сделать позже
module.exit_json(changed=False, msg="state=absent пока не реализован")
def main():
module = AnsibleModule(
argument_spec=dict(
vmi_domain=dict(required=True, type='str'),
vmi_first_username=dict(required=True, type='str'),
vmi_first_password=dict(required=True, type='str'),
state=dict(required=False, default='present', choices=['present', 'absent']),
name=dict(required=True, type='str'),
password=dict(required=True, type='str'),
cluster=dict(required=True, type='int'),
os=dict(required=True, type='int'),
ram_mib=dict(required=True, type='int'),
hdd_mib=dict(required=True, type='int'),
cpu_number=dict(required=True, type='int'),
ipv4_pool=dict(required=True, type='list', elements='int'),
validate_certs=dict(required=False, type='str'),
),
supports_check_mode=False,
)
base_url = f"https://{module.params['vmi_domain']}"
email = module.params['vmi_first_username']
password_user = module.params['vmi_first_password']
state = module.params['state']
validate_certs = module.params.get('validate_certs')
# Получаем токен
token = get_auth_token(
base_url=base_url,
email=email,
password=password_user,
validate_certs_param=validate_certs,
module=module
)
# Вызов основной функции
run(base_url, token, state, validate_certs, module)
if __name__ == '__main__':
main()Завершаем работу переработкой созданного ранее сценария управления виртуальными машинами vm.yml, заменим ansible.builtin.uri на свой модуль. Прошу не ругать за FQCN: все-таки модули мы не упаковывали в коллекцию и подгрузим их через указанные пути в переменных.
---
- name: Install VMmanager 6 playbook
hosts: all
debugger: on_failed
tasks:
- name: Get up vm
vm_info:
vmi_domain: "{{ ansible_ssh_host }}"
vmi_first_username: vm@example.com
vmi_first_password: uA2sW2nT9czV
name: My_vm
validate_certs: no
- name: Создать VM если отсутствует
vm:
vmi_domain: "{{ ansible_ssh_host }}"
vmi_first_username: vm@example.com
vmi_first_password: uA2sW2nT9czV
name: My_vm
password: vmsecret
cluster: 1
os: 1
ram_mib: 512
hdd_mib: 5000
cpu_number: 1
ipv4_pool: [1]
validate_certs: no
state: presentДля использования локальных модулей добавим пути через переменные:
export ANSIBLE_LIBRARY=/home/my_user/vm6_ansible/plugins/modules
export ANSIBLE_MODULE_UTILS=/home/my_user/vm6_ansible/plugins/module_utilsИ протестируем — запустим сценарий дважды, чтобы убедиться, что модуль действительно идемпотентен. Запускаем с помощью команды:
ansible-playbook --private-key /root/.ssh/private_key -i IP, -u root vm.ymlСмотрим результат:

В веб-интерфейсе платформы проверяем — действительно, модуль идемпотентен, создана одна виртуальная машина.

На этом наша работа с Infrastructure as Code, знакомство с платформой VMmanager и VMmanager API завершены. Желаю успехов в экспериментах, а также освоении новых инструментов и технологий.
Habrahabr.ru прочитано 2585 раз
