我想做一些与提到的非常相似的事情如何才能拥有一个具有 fileglob 模式的嵌套循环?除了文件列表是一个引用来自外循环的项目的 glob 模式之外。
我迄今为止的(失败的)代码:
- name: Deploy authorized_keys files for users
authorized_key:
user: "{{ item }}"
key: "{{ query('fileglob', 'ssh-pub-keys/{{ item }}/*.pub') }}"
with_list:
- user1
- user2
该目录ssh-pub-keys
如下所示:
ssh-pub-keys
├── user1
│ ├── hostA_id_ecdsa.pub
│ ├── hostA_id_ed25519.pub
│ ├── hostB_id_ecdsa.pub
│ ├── hostB_id_ed25519.pub
│ └── hostB_id_rsa.pub
└── user2
├── hostC_id_ecdsa.pub
├── hostC_id_rsa.pub
├── hostD_id_ecdsa.pub
└── hostD_id_ed25519.pub
错误信息如下:
failed: [somehost] (item=user1) => {"changed": false, "item": "user1", "msg": "invalid key specified: ['…/ssh-pub-keys/user1/hostA_id_ecdsa.pub', '…/ssh-pub-keys/user1/hostA_id_ed25519.pub', …]"}
failed: [somehost] (item=user2) => {"changed": false, "item": "user2", "msg": "invalid key specified: ['…/ssh-pub-keys/user2/hostC_id_ecdsa.pub', '…/ssh-pub-keys/user2/hostC_id_rsa.pub', …]"}
我似乎无法使用,with_nested
因为我无法从一个列表引用到另一个列表。
还尝试了类似的 Ansible/Jinja2 过滤器loop: {{ ['user1','user2'] | product(query(('fileglob', 'ssh-pub-keys/{{ ??? }}/*.pub'')) | list }}
,但没有弄清楚如何引用里面第一个列表中的项目product(…)
……
另一个尝试是使用两个任务,其中第二个任务引用第一个任务的注册输出,但是我没有弄清楚如何将 shell 输出变成适当的数据结构(输出按空格分割,但保留使用了哪个输入项的信息):
- name: Enumerate all authorized_keys files for all users
shell: "echo ssh-pub-keys/{{ item }}/*.pub"
with_list:
- user1
- user2
register: keyfiles
有人知道如何正确执行这类任务吗?
PS:使用 Debian 10 Buster(当前 Debian 稳定版本)中可用的 Ansible 2.7.7。
答案1
可以将键连接起来。引用自授权密钥:
可以在单个键字符串值中指定多个键,通过使用换行符分隔它们。
例如
- name: Deploy authorized_keys files for users
authorized_key:
user: "{{ item }}"
key: |
{% for fn in lookup('fileglob', 'ssh-pub-keys/' ~ item ~ '/*.pub', wantlist=True) %}
{{ lookup('file', fn) }}
{% endfor %}
loop:
- user1
- user2