基于事实的参数化ansible命令,如何做?

基于事实的参数化ansible命令,如何做?

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

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

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

- name: Install zsh
  sudo: yes
  yum|dnf: name=zsh state=latest

...而不是两次复制粘贴相同的命令,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

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

答案1

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 }}"

ansible_pkg_mgr现在您所需要的只是一些设置为apt或等的逻辑yum,然后所有when逻辑都会消失。

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

答案2

据我所知,这是 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

这有点不方便。但是,它确实有其优点。如果你仔细检查,你会发现 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'

但要扩展它,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'

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

相关内容