Создание новых экземпляров Nextcloud  с помощью скриптов Ansible

от автора

Всем привет! Хочу поделиться с вами вариантом скрипта для создания экземпляров Nextcloud через Ansible в vCloudDirector. Заодно опишу процесс создания экземпляров Nextcloud. Возможно, у вас тоже бывают подобные задачи, — можете не изобретать ещё один велосипед, вот один из вариантов решения.

Для начала приведу схему инфраструктуры, в которой будут разворачиваться новые экземпляры Nextcloud.

Добавлю немного подробностей, чтобы картинка стала понятнее.

Все серверы в инфраструктуре — виртуальные, развёрнуты в Vmware Cloud Director (далее VCD). Они работают под управлением ОС Ubuntu 20.04. В качестве reverse proxy используется веб-сервер Nginx. 

Новые разворачиваемые экземпляры Nextcloud представлены на схеме как Nextcloud Instances. В качестве сервера выполнения скрипта создания новых экземпляров Nextcloud используется Scripts. Этот сервер имеет ssh доступы по ключу на Nginx и все создаваемые экземпляры. Также Scripts может посылать API запросы к Vmware Cloud Director. 

Для доступов к интернету используется NSX EDGE Gateway, а для разрешения доменных имён — публичный DNS сервер (он так и обозначен на схеме). Все экземпляры Nextcloud находятся в одном домене domainname.com. Вместо этого имени должен быть ваш домен. Также предполагается, что SSL сертификаты на домен domainname.com получены и добавлены на Nginx.

Скрипт создания новых экземпляров Nextcloud

Скрипт выполняется на виртуальном сервере Scripts. На нём установлен Ansible с модулем ansible-module-vcloud-director для работы с API VCD. Он состоит из главного скрипта на bash и отдельных скриптов для определённых действий на Ansible и Python. Вот их список:

  1. create_instances_nextcloud.sh

  2. create_vapp.yml

  3. create_vm_in_vapp.yml

  4. list_nics.yml

  5. insert_txt.py

  6. config_next.yml

  7. config_nginx.yml

  8. nextcloud_template_tls

Скрипт create_instances_nextcloud.sh выглядит так:

#!/bin/bash ansible-playbook create_vapp.yml --extra-vars "orgname=$1" ansible-playbook create_vm.yml --extra-vars "orgname=$1" ip=$(ansible-playbook list_nics.yml --extra-vars "orgname=$1" 2>&1 | grep '"ip_address":' | grep -E -o '[0-9]{1,3}(\.[0-9]{1,3}){3}') last_name_conf_next="nextcloud_tls" name_config_next="$1$last_name_conf_next" echo "[$1]" >> ansible_hosts echo "$ip" >> ansible_hosts cp nextcloud_template_tls "$name_config_next" ./insert_txt.py $1 $ip $name_config_next last_domain_name_nextcloud="next.domainname.com" domain_name_nextcloud="$1$last_domain_name_nextcloud" scp $name_config_next root@192.168.4.3:/etc/nginx/sites-available ansible-playbook config_nginx.yml --extra-vars "name_config_next=$name_config_next" sleep 60 ansible-playbook config_next.yml --extra-vars "orgname=$1 ip=$ip domain_name_nextcloud=$domain_name_nextcloud password=$2"

Скрипт принимает два параметра:

  1. Имя экземпляра Nextcloud. Является суффиксом к доменному имени next.domainname.com

  2. Пароль пользователя admin в Nextcloud

Во второй строке скрипта используется ansible playbook create_vapp.yml. Он нужен для создания нового vApp в VCD. Приведу его содержание:

- name: vCloudDirectorAnsible   hosts: localhost   environment:        env_user: admin        env_password: password        env_host: vcd.domainname.ru            ## VCD Instance URL        env_org: name_org             ## VCD ORG to login ##      env_api_version: PYVCLOUD_API_VERSION        env_verify_ssl_certs: false   tasks:   - name: create vapp     vcd_vapp:       vapp_name: "{{ orgname }}Nextcloud"       vdc: "name_VDC"       description: "name_VDC"       network: "name_network"       deploy: true       power_on: true       accept_all_eulas: false       state: "present"

Playbook принимает параметр “orgname”, что является суффиксом к названию нового экземпляра Nextcloud

В переменной “environment” задаются “credentials”, такие как:

  1. env_user – имя пользователя с правами администратора организации

  2. env_password – пароль пользователя

  3. env_host – доменное имя VCD

  4. env_org – название организации в VCD

Далее выполняется задача создания vapp. В переменной vcd_vapp вводятся данные, необходимые для нового vApp:

  1. vapp_name – Название vApp с суффиксом названия экземпляра Nextcloud передаваемый в переменной orgname

  2. vdc – название VDC где будет создаваться экземпляр Nextcloud

  3. description – опиcание vApp (может быть любым)

  4. network – имя сети которую необходимо подключить к vApp

  5. power_on – включить vApp после создания

  6. statepresent означает что нужно создать vApp

Далее в скрипте create_instances_nextcloud.sh (3 строка) выполняется playbook create_vm.yml создания виртуальной машины в ранее созданном vApp. Создание виртуальной машины происходит из заранее подготовленного шаблона ВМ с Nextcloud. Вот содержание playbook:

- name: vCloudDirectorAnsible   hosts: localhost   environment:        env_user: name_admin        env_password: password        env_host: vcd.domainname.ru            ## VCD Instance URL        env_org: name_VDC             ## VCD ORG to login ##      env_api_version: PYVCLOUD_API_VERSION        env_verify_ssl_certs: false   tasks:   - name: create vapp vm from catalog     vcd_vapp_vm:       target_vm_name: "{{ orgname }}Nextcloud"       target_vapp: "{{ orgname }}Nextcloud"       target_vdc: name_VDC       source_vdc: "name_source_VDC"       source_catalog_name: name_Catalog       source_template_name: template_name       source_vm_name: source_vm_name       hostname: "{{ orgname }}Nextcloud"       ip_allocation_mode: "POOL"       power_on: "true"       all_eulas_accepted: "true"       network: network_name       deploy: false       state: "present"

Playbook как и в предыдущем случае принимает один параметр: “orgname”.

Как и в предыдущем playbook в переменной “environment” указываются “credentials”. Далее создаётся задача создания виртуальной машины в vApp, где в переменной “vcd_vapp_vm” указываются следующие данные:

  1. target_vm_name – имя создаваемой машины с суффиксом названия экземпляра Nextcloud, передаваемым через переменную orgname

  2. target_vapp — название vApp, в котором будет создаваться ВМ, с суффиксом названия экземпляра Nextcloud передаваемым в переменной “orgname”

  3. target_vdc – название VDC, в котором будет создаваться ВМ

  4. source_catalog_name – имя каталога, в котором находится шаблон

  5. source_template_name – имя шаблона с Nextcloud, который будет разворачиваться

  6. source_vm_name – имя ВМ, которая находится в шаблоне

  7. hostname – сетевое имя ВМ с суффиксом названия экземпляра Nextcloud, передаваемым через переменную “orgname”

  8.  ip_allocation_mode – способ назначения ip-адреса ВМ. Выбран способ static_ip_pool

  9. power_on – включить или нет машину после создания. Выбрано “Да”.

  10. network – имя сети, к которой необходимо подключить создаваемую ВМ. Имя сети совпадает с именем сети, которая подключается к vApp при его создании в прошлом playbook. 

  11.  State – поставлена present. Это означает, что будет создаваться новая ВМ

На этом этапе выполнения вывод скрипта будет примерно таким:

После создания vApp и VM в нём, нам необходимо узнать ip-адрес, который получила новая ВМ и записать его в переменную “ip” командой в строке 4 скрипта create_instances_nextcloud.sh. Делается это при помощи playbook “list_nics.yml”. Вот его содержание:

- name: vCloudDirectorAnsible   hosts: localhost   environment:        env_user: name_admin        env_password: password        env_host: vcd.domainname.ru            ## VCD Instance URL        env_org: name_org             ## VCD ORG to login ##      env_api_version: PYVCLOUD_API_VERSION        env_verify_ssl_certs: false   tasks:     - name: list vapp vm nics       vcd_vapp_vm:         target_vm_name: "{{ orgname }}Nextcloud"         target_vapp: "{{ orgname }}Nextcloud"         target_vdc: name_VDC         operation: "list_nics"       register: command_output     - debug:              var: command_output

Playbook принимает параметр “orgname”.

Как и в предыдущих playbook в переменной “environment” указываются “credentials” . Затем создаётся задача просмотра информации о интерфейсах. В переменной vcd_vapp_vm указываются:

  1. target_vm_name – имя ВМ, информацию по которой хотим получить. Совпадает с именем ВМ, которые были указаны в предыдущих playbook.

  2. target_vapp – имя vApp,в котором находится ВМ

  3. target_vdc – имя VDC, в котором находится ВМ

  4. operation – тип операции. Используется операция получения информации по интерфейсам «list_nics»

Далее выполняется подготовка конфигурационных файлов Nginx. Делается это путём редактирования единого шаблона конфигурации под именем nextcloud_template_tls. Этот шаблон был создан из конфигурации путём удаления строки “server_name <your-nc-domain>;” и “proxy_pass http://127.0.0.1:11000$request_uri; ”. 

В строке 5 и 6 скрипта create_instances_nextcloud.sh задаётся имя конфигурационного файла Nginx для экземпляра Nextcloud. Затем добавляются строки в инвентарный файл Ansible для нового экземпляра Nextcloud в командах под строками 7 и 8 скрипта create_instances_nextcloud.sh. 

В строке 9 копируется шаблон конфигурации Nginx nextcloud_template_tls под новым именем, которое хранится в переменной name_config_next. Затем при помощи скрипта на Python insert_txt.py вставляются нужные строки для нашего экземпляра Nextcloud. Вот содержание этого скрипта:

#!/usr/bin/python3.8 import sys def insert(file, line, column, text):     ln, cn = line - 1, column - 1         # offset from human index to Python index     count = 0                             # initial count of characters     with open(file, 'r+') as f:           # open file for reading an writing         for idx, line in enumerate(f):    # for all line in the file             if idx < ln:                  # before the given line                 count += len(line)        # read and count characters              elif idx == ln:               # once at the line                                                  f.seek(count + cn)        # place cursor at the correct character location                 remainder = f.read()      # store all character afterwards                                        f.seek(count + cn)        # move cursor back to the correct character location                 f.write(text + remainder) # insert text and rewrite the remainder                 return                    # You're finished! if __name__ == "__main__":   nextcloud_domain_name='server_name ' + sys.argv[1] + 'next.domainname.com;'   directve_proxy_pass_next='proxy_pass https://' + sys.argv[2] + '$request_uri;'   template_nextcloud=sys.argv[3]   insert(template_nextcloud, 27, 5, nextcloud_domain_name)   insert(template_nextcloud, 30, 9, directve_proxy_pass_next)

Этот скрипт принимает 3 параметра:

  1. Суффикс – суффикс имени нового экземпляра Nextcloud. Является суффиксом доменного имени next.domainname.com

  2. IP адрес – ip-адрес нового экземпляра Nextcloud

  3. Имя конфигурационного файла Nginx для Nextcloud

В итоге данный скрипт добавляет директивы “server_name” и “proxy_pass” в конфигурационный файл Nginx, где domainname.com — домен, в котором будет находиться ваш экземпляр Nextcloud.

Далее в строках 11, 12 скрипта create_instances_nextcloud.sh переменой domain_name_nextcloud присваивается доменное имя Nextcloud, где domainname.com — домен, в котором будет находиться ваш экземпляр Nextcloud. 

В строке 13 скрипта create_instances_nextcloud.sh подготовленный конфигурационный файл копируется на Nginx по ssh при помощи команды scp. 

В строке 14 задаётся конфигурация Nginx при помощи playbook config_nginx.yml. Вот его содержание:

- name: "Run a shell command on a remote host"   hosts: nginx*   tasks:   - name: create simvolic url      shell: |        ln -s /etc/nginx/sites-available/{{ name_config_next }} /etc/nginx/sites-enabled/{{ name_config_next }}        /etc/init.d/nginx reload 

Playbook принимает один параметр “name_config_next”, что является именем конфигурационного файла, который мы подготавливали ранее.

В этом playbook удалённо выполняются команды по ssh на Nginx proxy. Например, команды создания символической ссылки в каталоге “sites-enabled” на конфигурационный файл, который мы скопировали ранее в каталог “sites-available”. После этого Nginx перечитывает конфигурацию командой “/etc/init.d/nginx reload”. 

На этом этапе выполнения вывод скрипта будет примерно таким 

В строке 15 скрипта create_instances_nextcloud.sh при помощи команды sleep ждём 60 секунд, пока машина загрузится.

В строке 16 скрипта create_instances_nextcloud.sh идёт конфигурация созданного экземпляра Nextcloud при помощи playbook config_next.yml. Вот его содержание:

- name: "Run a shell command on a remote host"   hosts: "{{ orgname }}"   tasks:   - name: congigure Nextcloud     shell: |        sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 3 --value='{{ ip }}'        sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 4 --value='{{ domain_name_nextcloud }}'        echo "{{ password }}" | sudo -u www-data php /var/www/nextcloud/occ user:resetpassword admin               systemctl restart apache2

Playbook принимает три параметра:

  1. Суффикс имени экземпляра Nextcloud

  2. IP-адрес экземпляра Nextcloud

  3. Доменное имя экземпляра Nextcloud

  4. Пароль пользователя admin который необходимо задать в Nextcloud

В этом playbook удалённо по ssh выполняются команды на новом экземпляре Nextcloud: добавляются доверенные домены в виде ip-адреса экземпляра Nextcloud и его доменного имени. Сбрасывается пароль пользователя администратора Nextcloud под именем admin. Затем перезагружается веб-сервер apache2.

На этом этапе выполнения скрипта вывод будет примерно таким

После выполнения скрипта create_instances_nextcloud.sh необходимо создать DNS записи для нашего экземпляра Nextcloud на DNS сервере. И всё, можно пользоваться Nextcloud. 

Описанный алгоритм позволяет создать много экземпляров Nextcloud, используя скрипт create_instances_nextcloud.sh. Будет круто, если мой опыт вам поможет.


ссылка на оригинал статьи https://habr.com/ru/articles/796469/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *