Cập nhật: Kể từ Ansible 2.0, giờ đây đã có một mô-đun chung & trừu tượngpackage
Ví dụ sử dụng:
Bây giờ khi tên gói giống nhau trên các họ hệ điều hành khác nhau, nó đơn giản như:
---
- name: Install foo
package: name=foo state=latest
Khi tên gói khác nhau giữa các họ hệ điều hành, bạn có thể xử lý nó với các tệp vars dành riêng cho họ phân phối hoặc hệ điều hành:
---
# roles/apache/apache.yml: Tasks entry point for 'apache' role. Called by main.yml
# Load a variable file based on the OS type, or a default if not found.
- include_vars: "{{ item }}"
with_first_found:
- "../vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int}}.yml"
- "../vars/{{ ansible_distribution }}.yml"
- "../vars/{{ ansible_os_family }}.yml"
- "../vars/default.yml"
when: apache_package_name is not defined or apache_service_name is not defined
- name: Install Apache
package: >
name={{ apache_package_name }}
state=latest
- name: Enable apache service
service: >
name={{ apache_service_name }}
state=started
enabled=yes
tags: packages
Sau đó, đối với mỗi HĐH mà bạn phải xử lý khác nhau ... hãy tạo tệp vars:
---
# roles/apache/vars/default.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/RedHat.yml
apache_package_name: httpd
apache_service_name: httpd
---
# roles/apache/vars/SLES.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/Debian.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/Archlinux.yml
apache_package_name: apache
apache_service_name: httpd
EDIT: Vì Michael DeHaan (người tạo ra Ansible) đã chọn không trừu tượng hóa các mô-đun quản lý gói như Chef hiện,
Nếu bạn vẫn đang sử dụng phiên bản cũ hơn của Ansible (Ansible <2.0) , thật không may, bạn sẽ cần phải xử lý việc này trong tất cả các sách và vai trò của mình. IMHO điều này thúc đẩy rất nhiều công việc lặp đi lặp lại không cần thiết đối với các tác giả của playbook & vai trò ... nhưng đó là cách nó hiện tại. Lưu ý rằng tôi không nói rằng chúng ta nên cố gắng trừu tượng hóa các trình quản lý gói trong khi vẫn cố gắng hỗ trợ tất cả các tùy chọn và lệnh cụ thể của chúng, nhưng chỉ có một cách dễ dàng để cài đặt một gói là bất khả tri của trình quản lý gói. Tôi cũng không nói rằng tất cả chúng ta nên nhảy vào Trình quản lý gói thông minhbandwagon, nhưng một số loại trừu tượng cài đặt gói trong công cụ quản lý cấu hình của bạn rất hữu ích để đơn giản hóa các sách / sách nấu ăn đa nền tảng. Dự án thông minh có vẻ thú vị, nhưng khá tham vọng khi thống nhất quản lý gói trên các bản phân phối và nền tảng mà không cần áp dụng nhiều ... sẽ rất thú vị để xem liệu nó có thành công hay không. Vấn đề thực sự chỉ là các tên gói đôi khi có xu hướng khác nhau giữa các distro, vì vậy chúng ta vẫn phải thực hiện các báo cáo trường hợp hoặc các when:
câu lệnh để xử lý các khác biệt.
Cách tôi đã xử lý là theo tasks
cấu trúc thư mục này trong một vở kịch hoặc vai trò:
roles/foo
└── tasks
├── apt_package.yml
├── foo.yml
├── homebrew_package.yml
├── main.yml
└── yum_package.yml
Và sau đó có cái này trong tôi main.yml
:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
Điều này trong foo.yml
(đối với gói 'foo'):
---
# foo: Tasks entry point. Called by main.yml
- include: apt_package.yml
when: ansible_pkg_mgr == 'apt'
- include: yum_package.yml
when: ansible_pkg_mgr == 'yum'
- include: homebrew_package.yml
when: ansible_os_family == 'Darwin'
- name: Enable foo service
service: >
name=foo
state=started
enabled=yes
tags: packages
when: ansible_os_family != 'Darwin'
Sau đó, cho các trình quản lý gói khác nhau:
Đúng cách:
---
# tasks file for installing foo on apt based distros
- name: Install foo package via apt
apt: >
name=foo{% if foo_version is defined %}={{ foo_version }}{% endif %}
state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
tags: packages
Yum:
---
# tasks file for installing foo on yum based distros
- name: Install EPEL 6.8 repos (...because it's RedHat and foo is in EPEL for example purposes...)
yum: >
name={{ docker_yum_repo_url }}
state=present
tags: packages
when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 6
- name: Install foo package via yum
yum: >
name=foo{% if foo_version is defined %}-{{ foo_version }}{% endif %}
state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
tags: packages
- name: Install RedHat/yum-based distro specific stuff...
yum: >
name=some-other-custom-dependency-on-redhat
state=latest
when: ansible_os_family == "RedHat"
tags: packages
Homebrew:
---
- name: Tap homebrew foobar/foo
homebrew_tap: >
name=foobar/foo
state=present
- homebrew: >
name=foo
state=latest
Lưu ý rằng điều này rất lặp đi lặp lại và không DRY , và mặc dù một số thứ có thể khác nhau trên các nền tảng khác nhau và sẽ phải xử lý, nói chung tôi nghĩ rằng điều này dài dòng và khó sử dụng khi so sánh với Chef:
package 'foo' do
version node['foo']['version']
end
case node["platform"]
when "debian", "ubuntu"
# do debian/ubuntu things
when "redhat", "centos", "fedora"
# do redhat/centos/fedora things
end
Và vâng, có lập luận rằng một số tên gói khác nhau trên các bản phát hành. Và mặc dù hiện tại thiếu dữ liệu có thể truy cập dễ dàng , tôi mạo hiểm đoán rằng hầu hết các tên gói phổ biến đều phổ biến trên các bản phát hành và có thể được cài đặt thông qua mô-đun trình quản lý gói trừu tượng. Các trường hợp đặc biệt sẽ cần phải được xử lý bằng mọi cách và sẽ yêu cầu thêm công việc khiến mọi thứ trở nên ít KHÔ hơn nếu nghi ngờ, hãy kiểm tra pkgs.org .