我有一个复杂的环境,有多个系统的阶段和用户。
阶段是:dev,int等。
每个阶段都有一个应用程序用户,让我们调用用户john。这导致了 对于dev和johni的用户johnd为int等等。
要抽象系统管理,因为阶段中的所有系统都是相同的, 我创建了这个数据结构:
users:
john:
dev:
name: "johnd"
int:
name: "johni"
现在我有一个角色" collect_user_information"它从LDAP收集所有类型的信息,并借助set_fact将它们存储在变量中。
- name: Get the userhome out of LDAP
shell: 'getent passwd {{ users[ user ][ stage ].name }} | cut -d: -f6'
register: user_home
和set_fact:
- name: set facts for LDAP user
set_fact:
"{{user}}":
name: "{{ users[ user ][ stage ].name }}"
home: "{{ user_home.stdout }}"
要转储变量,我使用:
- name: debug output for myuser
debug: var="{{user}}"
调试输出看起来很容易。
TASK [collect_user_information : debug output for user] *******
ok: [host1] => {
"john": {
"home": "/home/johni",-
"name": "johni"
}
}
现在我想执行一个角色来创建用户回家。
- { role: create_user_home, user: "john" }
首先我转储变量的条目:
- 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"
}
}
现在我想使用这个数据结构。我猜我可以通过引用" {{user.name}}"来访问这些值。或" {{用户['名称']}}',但都不起作用。
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"}
嗯,它是如何运作的?
答案 0 :(得分:1)
好的,我自己找到了解决方案。
首先,我在数据结构中创建了一个附加层(myuser),并使用不同的表示法。
- 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 }}" } }'
这会返回一个像这样的调试转储:
TASK [collect_user_information : debug output for myuser] ***********
ok: [host1] => {
"myuser": {
"john": {
"home": "/home/johni",
"name": "johni"
}
}
}
现在我可以使用我的数据结构的值。记住"用户"有bin通过参数传递给角色。
- name: Create home directories for user
user:
name: "{{ myuser[ user ].name }}"
home: "{{ myuser[ user ].home }}"
shell: "/bin/bash"
register: "create_user_home"
tags: [ 'user' ]
希望有所帮助。
答案 1 :(得分:0)
这里的整个过程太棘手了 - 你想要定义一个动态var,其中var名称是用户名,例如。 john
,而john
是一个包含.name
和.home
两个键的字典。
您的第一次尝试失败是因为您尝试引用user.name
引用了词典name
的键user
,而不是john
的词典。
由于您在某处定义了一个金色词典users
,因此您并不需要让事情变得复杂。对于主目录,您始终可以使用users[user][stage].name
和user_home.stdout
来引用该名称。
如果您认为语法太麻烦了。我们可以通过创建另一个dict来存储名称和主目录来回到原来的方法。在以下情况中,user
始终引用您正在配置的当前用户:
- name: set facts for LDAP user
set_fact:
user:
name: "{{ users[username][stage].name }}"
home: "{{ user_home.stdout }}"
这样您就可以在任何后续任务中使用user.name
和user.home
。注意第4行,我将传递给角色的var重命名为username
以避免碰撞。
<强>更新强>
支持多个用户:
- name: Get the user home out of LDAP
shell: 'getent passwd {{ users[item][stage].name }} | cut -d: -f6'
register: homes
with_items: "{{ users }}"
# item.item is the username, item.stdout is the home dir
- debug: msg="{{ users[item.item][stage].name }}'s home is {{ item.stdout }}"
with_items: "{{ homes.results }}"