You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible从列表生成字典时遇条目被覆盖问题求助

我的Ansible密码生成问题:循环添加条目总是覆盖旧内容

最近在折腾Ansible给一批用户批量生成随机密码,结果卡壳了——每次循环新增密码条目,都会把之前的内容给覆盖掉,完全达不到我要的字典键值对效果!

具体情况:

  • 我的输入是存在accounts_list变量里的用户列表,格式如下:
account:
  - PR_user1
  - PR_user2
  • 需求很简单:给每个用户生成随机密码,后续用来配置服务,最后导出到文本文件。现在卡在第一步:遍历这个列表生成密码,并存成{用户名: 密码}的字典格式。
  • 我参照了相关思路,尝试了两种向变量添加条目的方法(combine和列表拼接+),写的Playbook代码是这样的:
- set_fact:
    # 第一种尝试:用combine合并字典
    # domain_accounts: "{{ domain_accounts|default({}) | combine({item|trim: lookup('password', '/dev/null length=8 chars=ascii_letters,digits,punctuation')}) }}"
    # 第二种尝试:用+拼接列表
    domain_accounts: "{{ domain_accounts|default([]) + [{item|trim: lookup('password', '/dev/null length=8 chars=ascii_letters,digits,punctuation')}] }}"
  with_items: "{{account_list.accounts}}"
  • 但执行后每次循环都把之前的结果覆盖了,输出日志是这样的:
TASK [set account passwords] ******************************************************************
ok: [localhost] => (item=PR_user1) => {"ansible_facts": {"domain_accounts": [{"PR_user1": "u]oT,cU{"}]}, "changed": false, "item": "PR_user1"}
ok: [localhost] => (item=PR_user2) => {"ansible_facts": {"domain_accounts": [{"PR_user2": "b>npKZdi"}]}, "changed": false, "item": "PR_user2"}
解决办法

问题根源其实很明确:Ansible循环中每次执行set_fact时,domain_accounts的default值会被重新触发,相当于每次都从零开始创建变量,而不是基于上一次循环的结果累加。

给你两种靠谱的解决方式:

方法1:用combine生成完整字典(推荐)

如果你的目标是生成标准的键值对字典,直接修改set_fact,确保每次循环都把新的键值对合并到已存在的字典里:

- set_fact:
    domain_accounts: "{{ domain_accounts | default({}) | combine({ item|trim: lookup('password', '/dev/null length=8 chars=ascii_letters,digits,punctuation') }, recursive=True) }}"
  with_items: "{{ account_list.accounts }}"

执行后就能得到一个包含所有用户和对应密码的字典,不会再出现覆盖问题。

方法2:用列表拼接时合并循环结果

如果坚持要列表套字典的格式,可以先把每次循环的结果存起来,再统一合并:

- set_fact:
    domain_accounts: "{{ domain_accounts | default([]) + [{ item|trim: lookup('password', '/dev/null length=8 chars=ascii_letters,digits,punctuation') }] }}"
  with_items: "{{ account_list.accounts }}"
  register: password_results

- set_fact:
    domain_accounts: "{{ password_results.results | map(attribute='ansible_facts.domain_accounts') | flatten }}"

第一步把每次循环的结果注册到password_results里,第二步用map和flatten把所有零散的列表合并成一个完整的列表。

验证效果

不管用哪种方法,最终你都能得到包含所有用户密码的集合,比如字典形式的结果会是:

"domain_accounts": {
    "PR_user1": "u]oT,cU{",
    "PR_user2": "b>npKZdi"
}

内容的提问来源于stack exchange,提问作者Ali Khawaja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:22:36