![Modelo de balanceador de carga Ansible para vários datacenters](https://rvso.com/image/658734/Modelo%20de%20balanceador%20de%20carga%20Ansible%20para%20v%C3%A1rios%20datacenters.png)
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_names
e groups
para 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.