Ansible
使用 Jinja2 模板遍歷嵌套列表/字典
我正在嘗試通過使用 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 %}
我認為我離正確的模板結構還差得很遠。到底是如何遍歷這個列表的?
創建庫存
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 %}