Modelo de balanceador de carga Ansible para vários datacenters

Modelo de balanceador de carga Ansible para vários datacenters

Estou migrando o gerenciamento de uma configuração existente de vários datacenters para o Ansible, mas não tenho certeza de qual é a melhor maneira de modelá-lo, pois sou novo nisso.

Tenho três data centers D1, D2 e ​​D3. Em cada um, a mesma configuração é repetida de forma idêntica:

  • Umbalanceador de carga nginx(lb.D[n]) vinculado a um IP público
  • Doisservidores de aplicativos(as[1-2].D[n]) que recebem tráfego somente do balanceador de carga local
  • Um escravo (somente leitura)Servidor de banco de dados(db.D[n]) do qual ambos os servidores de aplicativos leem.

O arquivo hosts que criei até agora é mais ou menos assim:

# 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

Deixei propositalmente apenas endereços IP aqui porque gostaria de entender como funcionaria uma solução Ansible pura, em vez de recorrer ao DNS.

O problema é preencher corretamente o upstream do proxy reverso do nginx, para queapenas os servidores de aplicativos locais para cada controlador de domínio são adicionadosquando a função nginx é executada e o modelo do arquivo de configuração é copiado na máquina do balanceador de carga. Em particular, é possível fazer algo assim?

# 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 %}
 }

Por um lado, não tenho certeza se o arquivo hosts faz todo sentido (devo adicionar variáveis ​​às entradas individuais? Na configuração atual, não posso fazer algo como [dc][3][appservers], mesmo que não tenha certeza é aí que está a solução.)

Muito obrigado!

EDITAR 1:

A estrutura do manual é a seguinte:

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

O ponto de entrada main.yml tem apenas duas linhas:

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

webservers.yml reúne fatos sobre servidores de aplicativos (pensei que isso seria necessário para atingir meu objetivo, embora ainda não tenha certeza de como) e, em seguida, primeiro invoca uma função base que apenas instala algumas chaves SSH compartilhadas, ligações NewRelic e outros coisas que são comuns a todas as máquinas em nossa nuvem e, em seguida, invoca a função real do servidor web.

---
- 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 }

A referida função "webserver" instala o nginx, copia os certificados SSL e, finalmente, copia o modelo de configuração jinja2 nginx.

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

Responder1

Você pode utilizarvariáveis ​​​​mágicas group_namese groupspara procurar grupos definidos em seu inventário:

---
- 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 %}
        }

Este manual fornecerá o seguinte resultado.

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;}"
}

Mude server {{host}};conforme necessário.

informação relacionada