AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1091892
Accepted
dutsnekcirf
dutsnekcirf
Asked: 2022-02-01 15:57:41 +0800 CST2022-02-01 15:57:41 +0800 CST 2022-02-01 15:57:41 +0800 CST

使用 Jinja2 模板遍历嵌套列表/字典

  • 772

我正在尝试通过使用 Ansible 生成 /etc/exports 文件来动态配置系统中的多个 NFS 服务器。我希望能够使用 jinja2 模板来做到这一点。这是我根据导出列表无法确定的 jinja2 模板。

我在我的 nfs 角色中定义了以下变量:

site_nfs_servers: ['ansibletarget1', 'ansibletarget2']

exports:
  - server: "ansibletarget1"
    shares:
      - path: "/my/first/share/path"
        client: "*"
        options: "rw,sync"
      - path: "/my/second/share/path"
        client: "*"
        options: "rw,sync,root_squash"
  - server: "ansibletarget2"
    shares:
      - path: "/another/shared/path/different/server"
        client: "*"
        options: "ro,sync"

然后我有以下 ansible play 来生成模板:

- name: Generate the exports file.
  template:
    src: exports.j2
    dest: /etc/exports
    owner: root
    group: root
    mode: '0750'

我的模板目前看起来像这样:

{% for export in exports %}
{% if ansible_hostname in export.server %}
{% for share in shares %}
{{ share.path }} {{ share.client }} {{ share.options }}
{% endfor %}
{% endif %}
{% endfor %}

我认为我离正确的模板结构还差得很远。到底是如何遍历这个列表的?

ansible ansible-playbook jinja2
  • 2 2 个回答
  • 3575 Views

2 个回答

  • Voted
  1. Gerald Schneider
    2022-02-01T22:15:24+08:002022-02-01T22:15:24+08:00

    export您在第二个循环中缺少对 the 的引用。

    {% for export in exports %}
    {% if ansible_hostname in export.server %}
    {% for share in export.shares %}
    {{ share.path }} {{ share.client }} {{ share.options }}
    {% endfor %}
    {% endif %}
    {% endfor %}
    

    但是,最好在主机变量中定义共享,如 Vladimir 的回答所示。

    • 3
  2. Best Answer
    Vladimir Botka
    2022-02-01T21:09:02+08:002022-02-01T21:09:02+08:00

    创建库存

    shell> cat hosts
    [site_nfs_servers]
    ansibletarget1
    ansibletarget2
    

    并将股份放入host_vars

    shell> cat host_vars/ansibletarget1.yml 
    shares:
      - path: "/my/first/share/path"
        client: "*"
        options: "rw,sync"
      - path: "/my/second/share/path"
        client: "*"
        options: "rw,sync,root_squash"
    
    shell> cat host_vars/ansibletarget2.yml 
    shares:
      - path: "/another/shared/path/different/server"
        client: "*"
        options: "ro,sync"
    

    为测试创建一个简化的角色

    shell> tree roles/my_nfs_role/
    roles/my_nfs_role/
    ├── tasks
    │   └── main.yml
    └── templates
        └── exports.j2
    
    2 directories, 2 files
    
    shell> cat roles/my_nfs_role/tasks/main.yml 
    - template:
        src: exports.j2
        dest: /etc/exports.test
    
    shell> cat roles/my_nfs_role/templates/exports.j2 
    {% for share in shares %}
    {{ share.path }} {{ share.client }} {{ share.options }}
    {% endfor %}
    

    然后,使用清单组和剧本中的角色

    shell> cat playbook.yml
    - hosts: site_nfs_servers
      roles:
        - my_nfs_role
    

    运行剧本并创建文件

    shell> ansible-playbook -i hosts playbook.yml
    
    PLAY [site_nfs_servers] ************************************************
    
    TASK [my_nfs_role : template] ******************************************
    changed: [ansibletarget1]
    changed: [ansibletarget2]
     ...
    
    shell> ssh admin@ansibletarget1 cat /etc/exports.test
    /my/first/share/path * rw,sync
    /my/second/share/path * rw,sync,root_squash
    
    shell> ssh admin@ansibletarget2 cat /etc/exports.test
    /another/shared/path/different/server * ro,sync
    

    请参阅示例 Ansible 设置。


    如果您想将共享保留在一个对象中,请将列表放入groups_vars中。为了简化代码,将列表转换为字典。例如,您可以使用community.general.groupby_as_dict

    shell> cat group_vars/all.yml
    exports:
      - server: "ansibletarget1"
        shares:
          - path: "/my/first/share/path"
            client: "*"
            options: "rw,sync"
          - path: "/my/second/share/path"
            client: "*"
            options: "rw,sync,root_squash"
      - server: "ansibletarget2"
        shares:
          - path: "/another/shared/path/different/server"
            client: "*"
            options: "ro,sync"
    
    exports_dict: "{{ exports|community.general.groupby_as_dict('server') }}"
    

    给

      exports_dict:
        ansibletarget1:
          server: ansibletarget1
          shares:
          - client: '*'
            options: rw,sync
            path: /my/first/share/path
          - client: '*'
            options: rw,sync,root_squash
            path: /my/second/share/path
        ansibletarget2:
          server: ansibletarget2
          shares:
          - client: '*'
            options: ro,sync
            path: /another/shared/path/different/server
    

    然后修改模板。这应该创建与以前相同的文件。

    shell> cat roles/my_nfs_role/templates/exports.j2 
    {% for share in exports_dict[inventory_hostname]['shares'] %}
    {{ share.path }} {{ share.client }} {{ share.options }}
    {% endfor %}
    
    • 2

相关问题

  • Ansible:将字符串转换为字典

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve