I have a complicated environment with stages and users for multiple systems.
The stages are: dev, int, etc.
Each stage has a user for an application, let's call the user john. That leads to a user johnd for dev and johni for int and so on.
To abstract the system management, since all systems in the stages are the same, I created this data structure:
users:
john:
dev:
name: "johnd"
int:
name: "johni"
Now I have a role "collect_user_information" which collects all kind of informations from LDAP and stores them in a variable with help of set_fact.
- name: Get the userhome out of LDAP
shell: 'getent passwd {{ users[ user ][ stage ].name }} | cut -d: -f6'
register: user_home
And set_fact:
- name: set facts for LDAP user
set_fact:
"{{user}}":
name: "{{ users[ user ][ stage ].name }}"
home: "{{ user_home.stdout }}"
To dump the variable, I use:
- name: debug output for myuser
debug: var="{{user}}"
The debug output looks promissing.
TASK [collect_user_information : debug output for user] *******
ok: [host1] => {
"john": {
"home": "/home/johni",-
"name": "johni"
}
}
Now I would like to execute a role to create the users home.
- { role: create_user_home, user: "john" }
First I dump the entries of my variable:
- name: debug role create_user_home output for variable user
debug: var=user
TASK [create_user_home : debug role create_user_home output for variable user] ***********
ok: [host1] => {
"user": "john"
}
- name: debug role create_user_home output for variable john
debug: var={{ user }}
TASK [create_user_home : debug role create_user_home output for variable john] **********
ok: [host1] => {
"john": {
"home": "/home/johni",-
"name": "johni"
}
}
Now I would like use this data structure. I would guess I can access the values by referencing "{{user.name}}" or "{{user['name']}}', but neither works.
TASK [create_user_home : Create home directories for john] ***********************
fatal: [host1]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'ansible.parsing.yaml.objects.AnsibleUnicode object' has no attribute 'home'\n\nThe error appears to have been in '/etc/ansible/roles/create_user_home/tasks/main.yml': line 37, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n#-------------------------------------------------------------------------------\n- name: Create home directories for john\n ^ here\n"}
Well, how does it work?
Okay I found the solution myself.
First I create an additional layer (myuser) in my data structure and use a different notation.
- name: set facts for LDAP user
set_fact:
myuser: '{ "{{user}}": { "name": "{{ users[ user ][ stage ].name }}", "home": "{{ user_home.stdout }}", "gid": "{{ user_gid.stdout}}", "group": "{{ user_primarygroup.stdout }}" } }'
This returns me a debug dump like this:
TASK [collect_user_information : debug output for myuser] ***********
ok: [host1] => {
"myuser": {
"john": {
"home": "/home/johni",
"name": "johni"
}
}
}
Now I'm able to use my data structure values. Remember "user" has been passed to the role by argument.
- name: Create home directories for user
user:
name: "{{ myuser[ user ].name }}"
home: "{{ myuser[ user ].home }}"
shell: "/bin/bash"
register: "create_user_home"
tags: [ 'user' ]
Hope that helps.