# Ansible Credentials and Variable Overrides

Let’s say we need to create mysql users. We’ll be overloading at the group_vars level, with group_vars/all/mysql_users.vault.yml being overridden by the more specific group_vars/production/mysql_users.vault.yml. Although we can set some basic stuff for all the hosts in a role, we want it to be available to both the database and the app roles without introducing dependencies. Hence, group_vars/all.

In ansible, to get a merging rather than replace behaviour for hashes, we set hash_behaviour = merge in ansible.cfg. The default behaviour is to replace the value and ONLY hashes can have the merge behaviour. The variables can be overriden in the group_vars directory and the variables set and loaded in all are overriden in the specific environment group. The only time there may be confusion is if a host is part of two groups, let’s say production and app, and the variable is set in both places.

Sample group_vars/all/mysql_users.vault.yml:

mysql_users:
root:
host: localhost
priv: '*.*:ALL,GRANT'
repl:
priv: '"*.*":"REPLICATION SLAVE,REPLICATION CLIENT"'


and we can override it in group_vars/production/mysql_users.vault.yml

mysql_users:
root:


This gets called with the iterator with_dict in a playbook:

- name: Create all the mysql users
tags: mysql_user
mysql_user: name={{ item.key }} password={{ item.value.password }} host={{ item.value.host | default("%") }} priv={{ item.value.priv | default("*.*:USAGE")}} state=present
with_dict: mysql_users


So that’s fairly straightforward. There are more complicated situations, for instance, creating a set of users with authorized_keys. I’m modifying the example given here which is using a list. But lists can’t be merged, so the data structure needs to be modified to a dict that works while using with_subelement. What I’ve found works is below:

users:
alice:
name: alice
authorized:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
bob:
name: bob
authorized:
- /tmp/bob/id_rsa.pub

- user: name={{ item.name }} state=present generate_ssh_key=yes
with_items: users

- authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'"
with_subelements:
- users
- authorized


Modelling the data this way allows overrides and usage with ansible’s iterators.