我计划使用Ansible管理相当多的Linux服务器集,其中有很多变化。

主机将按照角色之间的层次结构进行分组,其中有一个common角色,每个其他角色都依赖于该角色,子角色取决于common,并且可能有孙角色取决于它们,对依赖深度没有限制。

common
   |___ role1
   |___ role2
   |___ role3
          |___ role3.1


每个角色都有其自己的系统配置文件模板子集。

roles/
   common/
       templates/
           etc/
               hosts
               resolv.conf
       tasks/
           main.yml
           system-settings.yml # imported in main.yml
   role1/
       templates/
           etc/
               hosts # role-specific version, overrides 'common'
               httpd/
                   conf/
                       httpd.conf
       tasks/
           main.yml
           system-settings.yml # imported in main.yml
   role2/
   role3/
   role3.1/


棘手的是,我想分层地应用这些模板,类似于Ansible解析变量范围的方式。
因此,对于给定的子角色,将应用模板文件的最特定版本,如果该角色中不存在模板,则应用父级的版本,搜索到根级别。

我已经(通过某种方式)将以下各项放入每个角色的system-settings.yml中来实现此目的:

- name: Create directories
  file:
    path: /{{ item.path }}
    state: directory
    mode: '{{ item.mode }}'
  with_filetree: templates/
  when: item.state == 'directory'

- name: Template files
  template:
    src: '{{ item.src }}'
    dest: /{{ item.path }}
    mode: '{{ item.mode }}'
  with_filetree: templates/
  when: item.state == 'file'

- name: Recreate symlinks
  file:
    src: '{{ item.src }}'
    dest: /{{ item.path }}
    state: link
    force: yes
    mode: '{{ item.mode }}'
  with_filetree: templates/
  when: item.state == 'link'


它可以工作,但不幸的是,它会应用所有父角色的模板,然后应用所有子角色的模板。
万一剧本执行由于某种原因中止,这会浪费工作,并且很危险,因为主机可能会留下通用版本的系统文件。

因此,对于上面的示例树,将role1应用于一组主机Ansible时:


/etc/hosts角色应用/etc/resolv.confcommon
/etc/hosts角色应用/etc/httpd/conf/httpd.confrole1


但我想这样做:


/etc/resolv.conf角色应用common
/etc/hosts角色中应用role1(最特定的版本)
/etc/httpd/conf/httpd.conf角色应用role1


由于添加新文件或特定于角色的版本以覆盖通用文件的管理开销,模板文件不应在任务/剧本中明确列出,因为我们不想更改任何剧本或其他配置。

Ansible可以实现吗?

我可以看到使用外部脚本的可能解决方案(如https://docs.ansible.com/ansible/2.4/playbooks_loops.html#iterating-over-the-results-of-a-program-execution中所述),但是我不确定如何将角色层次结构传递到脚本中。

最佳答案

我的想法:

第一选择:
将“公共”文件任务更改为“公共”处理程序。我选择处理程序的原因是我们可以有条件地包括处理程序。另外,我们还有角色前/后处理程序。通知角色中尚未完成的所有任务以及必须完成的任务可以在角色前处理程序中进行。

第二选择:
有条件地包含任务,我认为需要付出很多努力才能将标签附加到包含的文件中。
例如:

---
-name: task inclusion
Hosts: localhost
Gether_facts: false
Tasks:
Include: common.yaml
When: item | bool
A_list:
  -true
  -false


希望这可以帮助。

问候
Sudhakar

关于ansible - Ansible:分层应用角色模板,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51215654/

10-16 17:36