基于事实的参数化ansible命令,怎么做?

mac*_*mac 4 yum ansible dnf

我正在更新我的一些 ansible playbook 以在最新版本的 Fedora 上运行,该版本现在dnf默认使用。

由于我的大部分剧本也应该在 CentOS 上运行,我希望我的脚本yum在对 CentOS 机器运行dnf时运行 ansible 命令,在对 Fedora 运行时运行该命令(Ansible 1.9 中的新功能),但使用其余的角色原样。

换句话说,我想编写一个可以智能地选择正确命令的单个操作(类似于):

- name: Install zsh
  sudo: yes
  yum|dnf: name=zsh state=latest
Run Code Online (Sandbox Code Playgroud)

...而不是复制粘贴相同的命令两次,更换yumdnf两个中的一个,然后执行一些逻辑,说两个不同的角色来运行的一个至极:

- name: Install zsh (yum version)
  sudo: yes
  yum: name=zsh state=latest

- name: Install zsh (dnf version)
  sudo: yes
  dnf: name=zsh state=latest
Run Code Online (Sandbox Code Playgroud)

在有人冲过去之前:我知道yumdnf最新的 Fedora 上有一个别名,并且我可以将剧本保持原样......我的问题不是关于编写 CentOS/Fedora 兼容的剧本,我的问题是关于选择一个根据目标环境,相同参数的不同命令

xdd*_*dsg 7

Ansible 2 现在有一个通用的包管理器:

http://docs.ansible.com/ansible/package_module.html

对于旧版本,您可以通过事实关联包管理器

- name: Install packages
  with_items: package_list
  action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"
Run Code Online (Sandbox Code Playgroud)

现在你所需要的只是一些设置ansible_pkg_mgraptyum等的when逻辑,所有的逻辑都消失了。

看起来 Ansible也在努力在未来的模块中做你想做的事

  • 嗯,反正大部分。在 F22 上,`ansible_pkg_mgr` 仍然返回 `yum` 而不是 `dnf`。我怀疑这是一个错误。 (2认同)

Mic*_*ton 5

据我所知,这是 Ansible 中比较混乱的部分之一。我一直认为它应该有一种方法可以自行找出正在使用的包管理器,而无需我指定它。

与此同时,我有很多角色,任务如下:

- name: Update OpenSSH on CentOS
  yum: name=openssh state=latest enablerepo=cr
  when: ansible_distribution == 'CentOS' and ansible_distribution_major_version|int == 7
  notify: restart sshd

- name: Update OpenSSH on RHEL
  yum: name=openssh state=latest
  when: ansible_distribution == 'RedHat' and ansible_distribution_major_version|int == 7
  notify: restart sshd

- name: Update OpenSSH on Fedora
  yum: name=openssh state=latest
  when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int <= 21
  notify: restart sshd

- name: Update OpenSSH on Fedora
  dnf: name=openssh state=latest
  when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int >= 22
  notify: restart sshd

- name: Update OpenSSH on Debian/Ubuntu
  apt: name=openssh-server state=latest
  when: ansible_os_family == 'Debian'
  notify: restart ssh
Run Code Online (Sandbox Code Playgroud)

这变得有点笨拙。然而,它确实有它的优点。如果您仔细检查,您会注意到 CentOS 版本不同;它在安装包时启用存储库。

当然,这样做是有原因的。在不同的系统上,你甚至可能有不同的包,所以你最终可能不得不为它们分配不同的任务。但是,您可以将其放入特定于操作系统的变量中,然后执行以下操作:

- include_vars: common_os_{{ansible_distribution}}_{{ansible_distribution_major_version}}.yml

- name: Install minimum system administration packages
  yum: name={{item}} state=present
  with_items: common_packages_admin
  when: ansible_os_family == 'RedHat'

- name: Install minimum system administration packages
  apt: name={{item}} state=present
  with_items: common_packages_admin
  when: ansible_os_family == 'Debian'
Run Code Online (Sandbox Code Playgroud)

但是要扩展它dnf需要一堆额外的when:逻辑,这是绝对零增益的大量工作,因为 dnf 的 yum 兼容性会处理它。这是一个假设的“自动找出要使用的包管理器”模块有用的地方。

但即使你有一个,你有时仍然需要使用单独的包管理器,因为其中一些有......特性。

- name: Install salt-minion
  yum: name=salt-minion state=latest
  when: ansible_os_family == 'RedHat'

- name: Install salt-minion
  apt: name=salt-minion state=latest update_cache=yes
  when: ansible_os_family == 'Debian'
Run Code Online (Sandbox Code Playgroud)

所以,我能给你的最好建议是:等到 Ansible 有更好的方法来处理包管理器。或者写一个...