Как мы уже писали, сервис 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
Все необходимые пакеты установлены, переменные добавлены, приступим к написанию плейбука.
Пример
- Создадим файл 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
- Создадим файл example.yaml, в котором мы будем описывать наши таски. Добавим необходимые параметры hosts и vars_files.
Переменная hosts определяет машину/машины, с которым мы будем осуществлять выполнение тасков, а vars_files указывает, откуда подгружать необходимые переменные (тут это файл example_vars.yaml):--- - hosts: localhost vars_files: - example_vars.yaml
- Приступим к написанию тасков. Первым делом добавим создание проекта с помощью 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
- Создадим и добавим пользователя в проект:
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 }}"
- Создадим сеть:
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
- После создания сети для создания виртуальных машин нам потребуются диски, которые можно создать с помощью готового 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
- Для доступа к нашим машинам нам будут нужны 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
- С помощью 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
- Опишем таск для их создания и дополнительно таск для добавления их в 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
- В конце добавим таск для проверки наших хостов на доступность:
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
Полный файл плейбука можно найти здесь.
- Запускаем наш плейбук:
$ 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] => { "msg": { "changed": false, "ping": "pong" } } ok: [95.213.234.211] => { "msg": { "changed": false, "ping": "pong" } } ok: [95.213.234.212] => { "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-модули покрывают весь набор функций, которые предоставляет наш сервис, и полезны в работе специалистов, взаимодействующих с нашим API.
Приглашаю всех заинтересованных попробовать модули и высказать замечания, пожелания и предложения.
Автор: rutskiy