Во-первых, прошу прощения за ужасное название. Я не совсем уверен, как лаконично описать проблему.
Итак, вот моя проблема. Я работаю над подготовкой пользователей базы данных и хотел бы иметь гибкий метод определения пользователей. У меня возникла проблема с использованием Jinja для условных выражений и доступных циклов, потому что я делаю то, для чего, как мне кажется, ansible не обязательно предназначен. Начнем с переменной:
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
Я бы хотел взять group
введите первый элемент и разверните его в список IP-адресов (как во втором элементе). group
относится к группе доступных хостов. Для этого у меня есть следующее:
- 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 }}"
Это трансформирует mysql_users
в 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"
А потом добавляем пользователей:
- 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)
У меня все идет, но ansible
кричит на меня, говоря, что не может найти "12.34.56.78", потому что пытается использовать этот IP-адрес в качестве ключа для поиска хоста в hostvars
. У меня возникли проблемы с поиском лучшего способа обработки поиска IP-адреса и восстановления неудачных поисков.
Во-первых, есть ли более простой способ сделать это? Я слишком усложняю это? Во-вторых, мне интересно, есть ли способ лучше сопоставить IP-адреса хоста с фактом.
я нашел эта полезная ветка и закончил тем, что создал шаблон файла var локально, а затем загрузил его в playbook. Это позволило мне использовать больше логики при создании файла var.
Вероятно, эту проблему можно решить с помощью фильтров карты и списка, как описано во втором примере здесь:
http://docs.ansible.com/ansible/set_fact_module.html
# 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 }}"
Я углублюсь здесь немного глубже: http://smileytechadventures.blogspot.com/2015/07/ansible-filter-results.html