First off, I apologize for the terrible title. I'm not entirely sure how to succinctly describe the problem.
So here's my challenge. I'm working on provisioning database users and would like a flexible method of defining users. I'm encountering a problem with using Jinja for conditionals and ansible loops because I'm doing things I think that ansible wasn't necessarily designed to do. Let's start with the variable:
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
I'd like to take the group
key in the first item and expand it into a list of ip addresses (like in the second item). group
refers to an ansible hosts group. To do that, I've got this:
- 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 }}"
This transforms mysql_users
into 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"
And then we add the users:
- 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)
I've got this going, but ansible
yells at me saying it can't find "12.34.56.78" because it's trying to use that ip address as the key to lookup the host in hostvars
. I'm having trouble finding a better way of handling ip address lookup and rescuing failed lookups.
First off, is there a simpler way of doing this? Am I making this too complicated? Second, I'm wondering if there's a way to better map the host ips to the fact.