Encontrei este tópico útil e acabei criando um modelo de arquivo var localmente e depois carregá-lo no playbook. Isso me permitiu utilizar mais lógica na construção do arquivo var.
Primeiramente, peço desculpas pelo título terrível. Não tenho certeza de como descrever sucintamente o problema.
Então aqui está o meu desafio. Estou trabalhando no provisionamento de usuários de banco de dados e gostaria de um método flexível de definição de usuários. Estou encontrando um problema em usar o Jinja para condicionais e loops ansible porque estou fazendo coisas que acho que o ansible não foi necessariamente projetado para fazer. Vamos começar com a variável:
mysql_users:
- user: biggles
password: boggles
group: app
database: some_db
- user: boogers
password: boogers
hosts:
- "12.34.56.78"
- "12.34.56.79"
- "12.34.56.80"
database: another_db
Gostaria de pegar a chave group
no primeiro item e expandi-la em uma lista de endereços IP (como no segundo item). group
refere-se a um grupo de hosts ansible. Para fazer isso, eu tenho isso:
- name: Expand Mysql users hosts from their group name
set_fact:
args:
mysql_users_dirty:
user: "{{ item }}"
hosts: "{{ groups[item.group | default('')] | default(item.hosts) }}"
with_items: mysql_users
register: mysql_users_results
# when: item.group is defined | default(false)
- name: Map fact result list to correct ansible fact
set_fact:
mysql_users_expanded: "{{ mysql_users_results.results | map(attribute='ansible_facts.mysql_users_dirty') | list }}"
Isso transforma mysql_users
em mysql_users_expanded
:
mysql_users_expanded:
- hosts:
- "23.34.56.78"
- "23.34.56.79"
- "23.34.56.80"
user:
user: biggles
password: boggles
group: app
database: some_db
- hosts:
- "12.34.56.78"
- "12.34.56.79"
- "12.34.56.80"
user:
user: boogers
password: boogers
database: another_db
hosts:
- "12.34.56.78"
- "12.34.56.79"
- "12.34.56.80"
E então adicionamos os usuários:
- name: Create/assign additional database users to db and grant permissions (group hosts)
mysql_user: name="{{ item.0.user.user }}"
password="{{ item.0.user.password }}"
host="{{ hostvars[ item.1 ]['ansible_' + private_iface ]['ipv4']['address'] | default(item.1) }}"
priv="{{ item.0.user.database }}.*:{{ item.0.user.priv | default('ALL')}}"
state=present
login_host="localhost"
login_user=root
login_password="{{ mysql_root_password }}"
with_subelements:
- mysql_users_expanded
- hosts
when: item.1 is defined | default(false)
Eu tenho isso acontecendo, mas ansible
grita comigo dizendo que não pode encontrar "12.34.56.78" porque está tentando usar esse endereço IP como chave para procurar o host em hostvars
. Estou tendo problemas para encontrar uma maneira melhor de lidar com a pesquisa de endereços IP e resgatar pesquisas com falha.
Primeiramente, há uma maneira mais simples de fazer isso? Estou fazendo isso muito complicado? Em segundo lugar, estou pensando se há uma maneira de mapear melhor os ips do host para o fato.
Encontrei este tópico útil e acabei criando um modelo de arquivo var localmente e depois carregá-lo no playbook. Isso me permitiu utilizar mais lógica na construção do arquivo var.
Isso provavelmente seria resolvido usando os filtros map e list, conforme descrito no segundo exemplo aqui:
# Example setting host facts using complex arguments
- set_fact:
one_fact: something
other_fact: "{{ local_var * 2 }}"
another_fact: "{{ some_registered_var.results | map(attribute='ansible_facts.some_fact') | list }}"
Eu entro em um pouco mais de profundidade aqui: link