Работа с VPC при помощи пакета ansible-selvpc-modules

Как мы уже писали, сервис Virtual Private Cloud компании Selectel построен на базе платформы OpenStack, об этом подробнее можно прочитать в нашей предыдущей статье.

Многие наши клиенты привыкли использовать в своих проектах систему управления конфигурациями Ansible, которая позволяет автоматизировать рутинные задачи и облегчить жизнь системного администратора. Также к преимуществам Ansible относится множество готовых модулей, в том числе и для автоматизации работы с компонентами OpenStack-платформы (список готовых модулей).

Работа с виртуальным приватным облаком начинается с создания проекта и резервирования для него ресурсов. Эти операции можно выполнить через панель управления или с помощью нашего API.

Часто при работе с VPC-сервисом может возникнуть необходимость создать несколько одинаковых виртуальных машин, добавить, выделить определенное количество ресурсов, создать новых пользователей и так далее.

Чтобы привести начальную конфигурацию проекта и работу с OpenStack API к общему знаменателю, мы разработали пакет ansible-selvpc-modules, который включает в себя несколько ansible-модулей, предназначенных специально для нашего сервиса. Он будет полезен в работе для любого рода специалистов, которые взаимодействуют с нашим API.

Модули покрывают весь набор функций, который предоставляет наш сервис. Теперь нет необходимости вручную, либо через сторонние утилиты устанавливать ресурсы для проекта: все это можно сделать сразу в одном плейбуке с помощью ansible-selvpc-modules.

Пакет ansible-selvpc-modules включает в себя:

  • selvpc_projects — для управления VPC проектами;
  • selvpc_quotas — для управления ресурсами проекта;
  • selvpc_limits — для получения информации о доступных ресурсах;
  • selvpc_users — для работы с пользователями;
  • selvpc_floatingips — для работы с плавающими ip адресами;
  • selvpc_subnets — для работы с подсетями;
  • selvpc_roles — для работы с ролями в проекте;
  • selvpc_tokens — для создания ключей;
  • selvpc_licenses — для работы с лицензиями.

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

Установка

Создадим изолированное виртуальное окружение, активируем и установим ansible-selvpc-modules:

$ virtualenv --no-site-packages env
$ source env/bin/activate
$ pip install ansible-selvpc-modules

Также нам понадобятся дополнительные пакеты для работы: shade как зависимость для os_* ansible-модулей и jmespath для удобного парсинга json-а (подробнее). Ставим из PyPi:

$ pip install shade jmespath

Для работы с Resell API нужны ключи. Зарегистрированные пользователи Selectel могут получить их здесь.

Теперь добавим переменные окружения SEL_URL и SEL_TOKEN:

$ export SEL_URL=https://api.selectel.ru/vpc/resell/
// На момент написания статьи актуальной версией API является 2
$ export SEL_TOKEN=<ваш API-ключ полученный выше в панели>

Так как в примере я буду использовать OpenStack модули для Ansible, дополнительно мне понадобятся следующие переменные:

$ export OS_PROJECT_DOMAIN_NAME=<ваш логин на my.selectel.ru>
$ export OS_USER_DOMAIN_NAME=<аналогично предыдущему>

Для облегчения жизни и хождений на хосты через Ansible выставим переменную окружения ANSIBLE_HOST_KEY_CHECKING в значение False:

$ export ANSIBLE_HOST_KEY_CHECKING=False

Все необходимые пакеты установлены, переменные добавлены, приступим к написанию плейбука.

Пример

    1. Создадим файл example_vars.yaml, где определим переменные image, username, password и project_name, а также два списка с именами наших дисков и виртуальных машин. (image — образ OS, под управлением которой будет работать наши виртуальные машины, flavor — конфигурация машины, в нашем случае это 512 RAM и 1 VCPU, подробнее):
---
username: TestUser
password: 123456
project_name: TestProject
image: Ubuntu 16.04 LTS 32-bit
volumes:
  - display_name: volume1
  - display_name: volume2
  - display_name: volume3
servers:
  - name: vm1
  - name: vm2
  - name: vm3
    1. Создадим файл example.yaml, в котором мы будем описывать наши таски. Добавим необходимые параметры hosts и vars_files.
      Переменная hosts определяет машину/машины, с которым мы будем осуществлять выполнение тасков, а vars_files указывает, откуда подгружать необходимые переменные (тут это файл example_vars.yaml):
---
- hosts: localhost
  vars_files:
    - example_vars.yaml
    1. Приступим к написанию тасков. Первым делом добавим создание проекта с помощью selvpc_projects и выделение квот для проекта, используя selvpc_quotas-модуль. Для 3 машин нам будет достаточно 3 процессорных ядер, 1536 RAM и 15 GB SSD-диска:
   ...
  tasks:
     - name: Create project
       selvpc_projects:
           project_name: "{{ project_name }}"
       register: project_out
 
     - name: Set quotas on created project
       selvpc_quotas:
           project_id: "{{ project_out.project.id }}"
           quotas:
               compute_cores:
               - region: ru-1
                 zone: ru-1a
                 value: 3
               compute_ram:
               - region: ru-1
                 zone: ru-1a
                 value: 1536
               volume_gigabytes_fast:
               - region: ru-1
                 zone: ru-1a
                 value: 15
       register: quotas_out
    1. Создадим и добавим пользователя в проект:
tasks:
   ...
     - name: Create user
       selvpc_users:
           username: "{{ username }}"
           password: "{{ password }}"
       register: user_out
 
     - name: Add created user to project
       selvpc_roles:
           project_id: "{{ project_out.project.id }}"
           user_id: "{{ user_out.user.id }}"
    1. Создадим сеть:
tasks:
    ...
     - name: Create public net
       selvpc_subnets:
            project_id: "{{ project_out.project.id }}"
            subnets:
              - region: ru-1
                type: ipv4
                quantity: 1
                prefix_length: 29
       register: public_net
 
     - name: Get info about network
       selvpc_subnets:
            subnet_id: "{{ public_net|json_query(subnets[0].id') }}"
       register: network_out
    1. После создания сети для создания виртуальных машин нам потребуются диски, которые можно создать с помощью готового Ansible модуля os_volume:
tasks:
   ...
     - name: Create volumes
       os_volume:
          state: present
          auth:
 auth_url: https://api.selvpc.ru/identity/v3
            username: "{{ username }}"
            password: "{{ password }}"
            project_name: "{{ project_name }}"
          display_name: "{{ item.display_name }}"
          image: "{{ image }}"
          size: 5
	     region_name: ru-1
       with_items: "{{ volumes }}"
       register: volume
    1. Для доступа к нашим машинам нам будут нужны SSH-ключи. Мы создадим один ключ для всех машин. В этом нам поможет os_keypair:
tasks:
   ...
     - name: Create key
       os_keypair:
          state: present
          auth:
		 auth_url: https://api.selvpc.ru/identity/v3
            username: "{{ username }}"
            password: "{{ password }}"
            project_name: "{{ project_name }}"
          name: ansible_key
	     region_name: ru-1
          public_key_file: "{{ '~' | expanduser }}/.ssh/id_rsa.pub"
       register: key
    1. С помощью os_nova_flavor создадим конфигурацию(flavor) для наших машин, в нашем случае это 512 RAM и 1 VCPU и назовем ее “selectel_test_flavor”(можно дать любое другое):
tasks:
   ...
     - name: Create flavor
       os_nova_flavor:
          state: present
          auth:
            auth_url: https://api.selvpc.ru/identity/v3
            username: "{{ username }}"
            password: "{{ password }}"
            project_name: "{{ project_name }}"
          name: selectel_test_flavor
          ram: 512
          vcpus: 1
          disk: 0
          region_name: ru-1
          is_public: False
       register: flavor
    1. Опишем таск для их создания и дополнительно таск для добавления их в in-memory inventory для последующей работы с уже созданными хостами, в конце небольшую паузу для того, чтобы виртуальные машины успели включиться перед использованием:
tasks:
   ...
     - name: Create servers
       os_server:
          state: present
          auth:
		 auth_url: https://api.selvpc.ru/identity/v3
            username: "{{ username }}"
            password: "{{ password }}"
            project_name: "{{ project_name }}"
          name: "{{ item.1.name }}"
          flavor: "{{ flavor }}"
          boot_volume: "{{ item.0 }}"
          nics: "net-id={{ network_out.subnet.network_id }}"
          key_name: ansible_key
	     region_name: ru-1
       with_together:
          - "{{ volume|json_query('results[*].id') }}"
          - "{{ servers }}"
       register: created_servers
 
 
     - name: Add hosts to inventory
       add_host:
          name: "{{ item }}"
          ansible_host: "{{ item }}"
          ansible_ssh_user: root
          groups: just_created
       with_items: "{{ created_servers|json_query('results[*].openstack.accessIPv4') }}"
 
- pause:
     seconds: 60
    1. В конце добавим таск для проверки наших хостов на доступность:
tasks:
   ...
- hosts: just_created
  tasks:
    - name: Ping all instances
      ping:
      register: results
 debug: msg={{ results }}

Я также добавил debug и ignore_errors в данном таске для наглядности, это не является обязательным (debug позволит нам выводить более подробный результат выполнения тасков, а ignore_errors не прекратит выполнение плейбука, в случае возникновения каких-либо ошибок).

Дополнительно в конце плейбука я добавил удаление конфигурации(flavor), пользователя и проекта, чтобы почистить все, что было создано ранее:

- hosts: localhost
  gather_facts: False
  vars_files:
    - example_vars.yaml
  tasks:
    - name: Delete flavor
      os_nova_flavor:
          state: absent
          auth:
            auth_url: https://api.selvpc.ru/identity/v3
            username: "{{ username }}"
            password: "{{ password }}"
            project_name: "{{ project_name }}"
          name: "{{ flavor.flavor.name }}"
          region_name: ru-1
      register: out
 
     - name: Delete user
       selvpc_users:
           user_id: "{{ user_out.user.id }}"
           state: absent
       register: out
 
     - name: Delete project
       selvpc_projects:
           project_id: "{{ project_out.project.id }}"
           state: absent
       register: out

Полный файл плейбука можно найти здесь.

    1. Запускаем наш плейбук:
$ ansible-playbook example.yaml

Во время паузы, которую мы добавили ранее в конце пункта 9, можно сходить в панель управления проекта и посмотреть на созданные серверы:

Результаты выполнения плейбука в консоли:

TASK [Ping all instances] 
*************************************************************************
ok: [95.213.234.211]
ok: [95.213.234.212]
ok: [95.213.234.210]
 
TASK [debug] 
*************************************************************************
ok: [95.213.234.210] =&gt; {
    "msg": {
        "changed": false, 
        "ping": "pong"
    }
}
ok: [95.213.234.211] =&gt; {
    "msg": {
        "changed": false, 
        "ping": "pong"
    }
}
ok: [95.213.234.212] =&gt; {
    "msg": {
        "changed": false, 
        "ping": "pong"
    }
}
 
PLAY [localhost] 
*************************************************************************
TASK [Delete flavor]
*************************************************************************
changed: [localhost]
 
TASK [Delete user] 
*************************************************************************
changed: [localhost]
 
TASK [Delete project] 
*************************************************************************
changed: [localhost]
 
PLAY RECAP 
*************************************************************************
95.213.234.210          : ok=3    changed=0    unreachable=0    failed=0   
95.213.234.211          : ok=3    changed=0    unreachable=0    failed=0   
95.213.234.212          : ok=3    changed=0    unreachable=0    failed=0   
localhost                     : ok=25   changed=13   unreachable=0    failed=0 

В выводе мы видим, что все таски выполнились успешно и наши хосты доступны. Также мы видим, что созданный пользователь и проект, а с ним и виртуальные машины были успешно удалены.

Заключение

Мы рассмотрели использование пакета ansible-selvpc-modules для управления проектами VPС.

Ansible-модули покрывают весь набор функций, которые предоставляет наш сервис, и полезны в работе специалистов, взаимодействующих с нашим API.

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

Документация и исходники