基於事實的參數化ansible命令,怎麼做?
我正在更新我的一些 ansible playbook 以在最新版本的 Fedora 上執行,現在
dnf
預設使用該版本。由於我的大部分劇本也應該在 CentOS 上執行,我希望我的腳本在
yum
針對 CentOS 機器執行時執行 ansible 命令,並dnf
在針對 Fedora 執行時執行命令(Ansible 1.9 中的新功能),但使用其餘的角色原樣。換句話說,我想編寫一個可以智能地選擇正確命令的單個操作(類似於):
- name: Install zsh sudo: yes yum|dnf: name=zsh state=latest
…而不是將相同的命令複製粘貼兩次,替換
yum
為dnf
兩者之一,然後實現一些邏輯,說明要執行的兩個不同角色之一:- 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 兼容的劇本,我的問題是關於選擇一個相同參數的不同命令取決於目標環境
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也在努力在未來的模組中做你想做的事情。
據我所知,這是 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 有更好的方法來處理包管理器。或者寫一個…