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

Ansible循环生成sudoers文件异常,求正确实现方案

问题原因分析

你的Playbook问题出在content字段的Jinja2循环逻辑:你遍历了整个sudoers_include字典的所有键值对,导致不管循环到哪个文件(比如sudofile1),都会把所有sudofile的规则全部写入目标文件,这就是为什么生成的文件包含所有规则的原因。

正确实现方式

方法1:修正copy模块的循环逻辑

不需要遍历整个字典,直接利用循环项item.value获取当前文件对应的规则列表即可:

---
- name: main
  hosts: all
  become: true
  vars:
    sudoers_include:
      sudofile1:
          - "%kombit ALL=NOPASSWD: /usr/local/bin/create_sftp_dirs.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/add_public_key.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/remove_sftp_dirs.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/lock_file.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/unlock_file.sh"
      sudofile2:
          - "%admin1 ALL=NOPASSWD: /usr/local/bin/create_sftp_dirs.sh"
          - "%admin2 ALL=NOPASSWD: /usr/local/bin/add_public_key.sh"
  tasks:
  - copy:
      dest: "/tmp/{{ item.key }}"
      content: |
        {%- for rule in item.value -%}
          {{ rule }}
        {%- endfor -%}
    loop: "{{ sudoers_include | dict2items }}"

这样每个文件只会写入自身对应的规则列表,不会混入其他文件的内容。

方法2:使用template模块(推荐复杂场景)

如果后续需要给sudoers文件添加头部注释、权限校验逻辑,或者规则格式需要更复杂的渲染,template模块会更灵活:

  1. 创建模板文件(例如sudoers.j2):
# 自动生成的sudoers规则文件,请勿手动修改
{%- for rule in rules -%}
{{ rule }}
{%- endfor -%}
  1. 修改Playbook调用模板:
---
- name: main
  hosts: all
  become: true
  vars:
    sudoers_include:
      sudofile1:
          - "%kombit ALL=NOPASSWD: /usr/local/bin/create_sftp_dirs.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/add_public_key.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/remove_sftp_dirs.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/lock_file.sh"
          - "%kombit ALL=NOPASSWD: /usr/local/bin/unlock_file.sh"
      sudofile2:
          - "%admin1 ALL=NOPASSWD: /usr/local/bin/create_sftp_dirs.sh"
          - "%admin2 ALL=NOPASSWD: /usr/local/bin/add_public_key.sh"
  tasks:
  - template:
      src: sudoers.j2
      dest: "/tmp/{{ item.key }}"
    loop: "{{ sudoers_include | dict2items }}"
    vars:
      rules: "{{ item.value }}"
模块选择建议
  • 若只是简单将列表内容逐行写入文件,用copy模块加循环足够简洁;
  • 若需要复杂的格式渲染、注释添加或逻辑判断,优先用template模块,扩展性更强。

内容的提问来源于stack exchange,提问作者johnny bravo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:52:48