Estou migrando o gerenciamento de uma configuração multi-datacenter existente para o Ansible, mas não tenho certeza qual é a melhor maneira de modelá-lo, já que sou novo nele.
Eu tenho três datacenters D1, D2 e D3. Em cada uma delas, a mesma configuração é repetida de forma idêntica:
- Um balanceador de carga nginx (lb.D [n]) vinculado a um IP público
- Dois servidores de aplicativos (como [1-2] .D [n]) que recebem tráfego somente do balanceador de carga local
- Um escravo (somente leitura) Servidor de BD (db.D [n]) a partir do qual os servidores de aplicativos lêem.
O arquivo de hosts que eu fiz até agora é parecido com isto:
# 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
Eu deixei intencionalmente apenas endereços IP aqui porque gostaria de entender como uma solução Ansible pura funcionaria, em vez de recorrer ao DNS.
O problema é preencher corretamente o upstream do proxy reverso do nginx, de forma que apenas os servidores de aplicativos locais de cada DC sejam adicionados quando a função nginx for executada e o modelo de arquivo de configuração for 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 o sentido (devo adicionar variáveis às entradas individuais? Na configuração atual, não posso fazer algo como [dc] [3] [appservers], embora eu Não tenho certeza de que é onde a solução está.)
Muito obrigado!
EDIT 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 é apenas duas linhas:
---
- include: servers/webservers.yml
- include: servers/appservers.yml
webservers.yml reúne fatos sobre os appservers (imaginei que seria necessário atingir meu objetivo, embora eu não esteja totalmente certo de como ainda), e então primeiro invoco uma função base que apenas instala algumas chaves SSH compartilhadas, NewRelic ligações e outras coisas que são comuns a todas as máquinas em nossa nuvem e, em seguida, invocam a função real do servidor da 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 }
Essa função "webserver" instala o nginx, copia os certificados SSL e finalmente copia o modelo de configuração nginx do jinja2.
- name: Install nginx configuration file.
template: src=files/loadbalancer.j2 dest=/etc/nginx/sites-available/{{ project_name }} backup=yes