Шаблон балансировщика нагрузки Ansible для нескольких центров обработки данных

Шаблон балансировщика нагрузки Ansible для нескольких центров обработки данных

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

У меня есть три центра обработки данных D1, D2 и D3. В каждом из них повторяется одна и та же конфигурация:

  • Анбалансировщик нагрузки nginx(lb.D[n]) привязан к публичному IP
  • Двасерверы приложений(as[1-2].D[n]), которые получают трафик исключительно от локального балансировщика нагрузки
  • Раб (только чтение)сервер БД(db.D[n]), из которого считывают данные оба сервера приложений.

Файл hosts, который я создал на данный момент, выглядит примерно так:

# DC1 -----------
[dc_1_webservers]
10.43.0.10

[dc_1_appservers]
10.43.0.20
10.43.0.21

[dc_1_dbservers]
10.43.0.30

[dc_1:children]
dc_1_webservers
dc_1_appservers
dc_1_dbservers

# DC2 -----------
[dc_2_webservers]
10.43.10.10

[dc_2_appservers]
10.43.10.20
10.43.10.21

[dc_2_dbservers]
10.43.10.30

[dc_2:children]
dc_2_webservers
dc_2_appservers
dc_2_dbservers

# DC3 -----------
[dc_3_webservers]
10.43.20.10

[dc_3_appservers]
10.43.20.20
10.43.20.21

[dc_3_dbservers]
10.43.20.30

[dc_3:children]
dc_3_webservers
dc_3_appservers
dc_3_dbservers

[webservers:children]
dc_1_webservers
dc_2_webservers
dc_3_webservers

[appservers:children]
dc_1_appservers
dc_2_appservers
dc_3_appservers

Я намеренно оставил здесь только IP-адреса, поскольку хотел бы понять, как будет работать чистое решение Ansible, вместо того чтобы прибегать к DNS.

Проблема заключается в правильном заполнении обратного прокси-сервера nginx вверх по течению, так чтодобавляются только локальные серверы приложений для каждого DCкогда роль nginx запущена и шаблон файла конфигурации скопирован на машину балансировщика нагрузки. В частности, возможно ли сделать что-то подобное?

# file /etc/nginx/sites-enabled/loadbalancer.conf in lb.D[n] (i.e. lb.D2)
 upstream backend  {
 # Iterate over the app servers in the current data center (i.e. D2)
 {% for host in [datacenters][current_datacenter][appservers] %}
     # Add each local app server IP to the load balancing pool 
     # (i.e. 10.43.10.20 and 10.43.10.21 for DC2)
     server {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }};
 {% endfor %}
 }

Во-первых, я не уверен, что файл hosts имеет полный смысл (может быть, мне следует вместо этого добавлять переменные в отдельные записи? В текущей конфигурации я не могу сделать что-то вроде [dc][3][appservers], хотя я и не уверен, что именно в этом и заключается решение).

Большое спасибо!

ПРАВКА 1:

Структура пособия выглядит следующим образом:

main.yml
hosts
vars.yml
servers/
    webservers.yml
    appservers.yml
roles/
   base/
     files/
       ssh/
       newrelic/
     tasks/
       main.yml
     handlers/
       main.yml
   webserver/
     files/
       ssl_certs/
     templates/
       nginx/
          loadbalancer.j2
     tasks/
       main.yml
     handlers/
       main.yml
   appserver/
     files/
       pip/
         requirements.txt
     templates/
       supervisor/
          gunicorn.j2
     tasks/
        main.yml
     handlers/
        main.yml

Точка входа main.yml состоит всего из двух строк:

---
- include: servers/webservers.yml
- include: servers/appservers.yml

webservers.yml собирает информацию о серверах приложений (я решил, что это необходимо для достижения моей цели, хотя пока не совсем уверен, как это сделать), а затем сначала вызывает базовую роль, которая просто устанавливает некоторые общие ключи SSH, привязки NewRelic и другие вещи, общие для каждой машины в нашем облаке, а затем вызывает фактическую роль веб-сервера.

---
- name: Gather data about appservers
  hosts:  appservers
  gather_facts: yes
  tasks:
    - debug: Gather Facts

- name: Configure all frontend web servers
  hosts: webservers
  sudo: yes
  roles:
    - { role: base }
    - { role: webserver }

Указанная роль «веб-сервера» устанавливает nginx, копирует SSL-сертификаты, а затем, наконец, копирует шаблон конфигурации jinja2 nginx.

 - name: Install nginx configuration file.
    template: src=files/loadbalancer.j2 dest=/etc/nginx/sites-available/{{ project_name }} backup=yes

решение1

Вы можете использоватьмагические переменные group_namesи groupsдля поиска групп, определенных в вашем инвентаре:

---
- hosts: webservers
  vars:
    dcs: [dc_1, dc_2, dc_3]
  tasks:
  - debug:
      msg: |
        upstream backend {
        {%- for dc in dcs %}
        {%-   if dc in group_names %}
        {%-     for host in groups[dc+'_appservers'] %}
        server {{host}};
        {%-     endfor %}
        {%-   endif %}
        {%- endfor %}
        }

Эта инструкция даст вам следующий результат.

TASK: [debug ]     **************************************************************** 
ok: [10.43.0.10] => {
    "msg": "upstream backend { server 10.43.0.20; server 10.43.0.21;}"
}
ok: [10.43.10.10] => {
    "msg": "upstream backend { server 10.43.10.20; server 10.43.10.21;}"
}
ok: [10.43.20.10] => {
    "msg": "upstream backend { server 10.43.20.20; server 10.43.20.21;}"
}

Меняйте server {{host}};по мере необходимости.

Связанный контент