Pull to refresh
154.88
Cloud4Y
#1 Корпоративный облачный провайдер

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

Level of difficultyEasy
Reading time8 min
Views3.6K

Всем привет! Хочу поделиться с вами вариантом скрипта для создания экземпляров 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. Будет круто, если мой опыт вам поможет.

Tags:
Hubs:
Total votes 7: ↑5 and ↓2+4
Comments7

Articles

Information

Website
www.cloud4y.ru
Registered
Founded
2009
Employees
51–100 employees
Location
Россия