我已通过以下变量加载include_vars
:
access:
username-foo:
- path: /
permissions: rwX
recursive: true
username-bar:
- path: /
permissions: rX
- path: /css
permissions: rwX
recursive: true
- path: /data
permissions: rX
- path: /data/reviews.yml
permissions: rw
- path: /js
permissions: rX
- path: /js/*.js
permissions: rw
我想将这些信息提供给shell
命令以便设置适当的权限。
我从这里尝试了一些技巧: http://docs.ansible.com/playbooks_loops.html 但未能提出可行的解决方案。
是否可以迭代此结构?如果不行,我该如何重新构造它以使其工作?是否可以在不违反 DRY 规则的情况下做到这一点(例如将用户名包含在每条记录中)?
答案1
首先,您可能需要考虑使用file
模块,而不是shell
。它不太容易出错,而且表面上是幂等的。但是,这可能会给你带来一些混合目录、文件和文件全局的问题。YMMV。
至于问题的核心,我会像这样设置变量:
users:
- username: bar
directories:
- path: /data
permissions: rX
- path: /js
permissions: rX
- username: foo
directories:
- path: /
permissions: rwX
那么剧情将会是这样的:
- name: Change mod/own
shell: chown {{ item.0.username }} {{ item.1.path }};chmod u+{{ item.1.permissions }} {{ item.1.path }
with_subelements:
- users
- directories
答案2
这是一个很好的输出示例,你可以自己尝试一下。创建一个名为的新剧本iteration_loop.yml
:
---
- name: Change mod/own
hosts: all
tasks:
- name: show me the iterations
debug: msg={{ item.0.username }} {{ item.1.path }} then {{ item.1.permissions }} {{ item.1.path }}
with_subelements:
- users
- directories
vars:
users:
- username: bar
directories:
- path: /data
permissions: rX
- path: /js
permissions: rX
- username: foo
directories:
- path: /
permissions: rwX
然后像这样运行剧本:
ansible-playbook -i '172.16.222.131,' iteration_loop.yml
输出应该告诉你如何访问这些项目:
PLAY [Change mod/own] *********************************************************
GATHERING FACTS ***************************************************************
ok: [172.16.222.131]
TASK: [show me the iterations] ************************************************
ok: [172.16.222.131] => (item=({'username': 'bar'}, {'path': '/data', 'permissions': 'rX'})) => {
"item": [
{
"username": "bar"
},
{
"path": "/data",
"permissions": "rX"
}
],
"msg": "bar"
}
ok: [172.16.222.131] => (item=({'username': 'bar'}, {'path': '/js', 'permissions': 'rX'})) => {
"item": [
{
"username": "bar"
},
{
"path": "/js",
"permissions": "rX"
}
],
"msg": "bar"
}
ok: [172.16.222.131] => (item=({'username': 'foo'}, {'path': '/', 'permissions': 'rwX'})) => {
"item": [
{
"username": "foo"
},
{
"path": "/",
"permissions": "rwX"
}
],
"msg": "foo"
}
PLAY RECAP ********************************************************************
172.16.222.131 : ok=2 changed=0 unreachable=0 failed=0
答案3
假设等等dict={a:[1,2,3],b:[1,2]}
:
- name: Flattened list
set_fact:
flattened: "{{ dict.values() | sum(start=[]) }}"
现在flattened == [1,2,3,1,2]
答案4
我会将您的变量重新格式化为以下格式:
access:
- username: foo
directories:
- path: /
permissions: rwX
recursive: true
- username: bar
directories:
- path: /
permissions: rX
recursive: false
- path: /css
permissions: rwX
recursive: true
- path: /data
permissions: rX
recursive: false
- path: /data/reviews.yml
permissions: rw
recursive: false
- path: /js
permissions: rX
recursive: false
- path: /js/*.js
permissions: rw
recursive: false
然后我的剧本如下:
tasks:
- name: Iterate the vars inside var4 when recursive
debug: msg="username is {{ item.0.username }} and path is {{ item.1.path }} permission is {{ item.1.permissions }} and recursive"
when: item.1.recursive
ignore_errors: true
with_subelements:
- "{{ access }}"
- directories
- name: Iterate the vars inside var4 when no recursive
debug: msg="username is {{ item.0.username }} and path is {{ item.1.path }} permission is {{ item.1.permissions }}"
when: not item.1.recursive
ignore_errors: true
with_subelements:
- "{{ access }}"
- directories