
나는 시작하고있다앤서블그리고 이를 사용하여 여러 Linux 배포판에 패키지를 설치합니다.
문서에서 yum
및 apt
명령이 분리되어 있음을 확인했습니다. 이를 통합하고 다음과 같이 사용하는 가장 쉬운 방법은 무엇입니까?
- name: install the latest version of Apache
unified_install: name=httpd state=latest
대신에
- name: install the latest version of Apache on CentOS
yum: name=httpd state=latest
when: ansible_os_family == "RedHat"
- name: install the latest version of Apache on Debian
apt: pkg=httpd state=latest
when: ansible_os_family == "Debian"
두 패키지 관리자는 서로 다르지만 여전히 공통된 기본 사용법이 있다는 것을 알고 있습니다. 기타 오케스트레이터(예를 들어 소금) 단일 설치 명령이 있습니다.
답변1
업데이트: Ansible 2.0부터는 이제 일반 및 추상화 버전이 있습니다.package
기준 치수
사용 예:
이제 패키지 이름이 여러 OS 제품군에서 동일하면 다음과 같이 간단합니다.
---
- name: Install foo
package: name=foo state=latest
패키지 이름이 OS 제품군마다 다른 경우 배포판 또는 OS 제품군별 vars 파일을 사용하여 이를 처리할 수 있습니다.
---
# 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
그런 다음 다르게 처리해야 하는 각 OS에 대해 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
편집하다: Michael DeHaan(Ansible 창시자) 이후패키지 관리자 모듈을 추상화하지 않기로 선택했습니다.좋다요리사하다,
아직도 이전 버전의 Ansible(Ansible < 2.0)을 사용하고 있는 경우, 안타깝게도 이 작업은 다음에서 처리해야 합니다.모두당신의 플레이북과 역할. IMHO이로 인해 플레이북 및 역할 작성자에게 불필요하고 반복적인 작업이 많이 발생하게 됩니다. 하지만 현재는 그렇습니다. 특정 옵션과 명령을 모두 지원하면서 패키지 관리자를 추상화해야 한다는 뜻은 아니지만, 패키지 관리자에 구애받지 않는 패키지를 쉽게 설치할 수 있는 방법만 있다는 점에 유의하세요. 나는 또한 우리 모두가 뛰어들어야 한다고 말하는 것이 아닙니다.스마트 패키지 관리자하지만 구성 관리 도구의 일종의 패키지 설치 추상화 계층은 크로스 플랫폼 플레이북/요리책을 단순화하는 데 매우 유용합니다. Smart 프로젝트는 흥미로워 보이지만 아직 많은 채택 없이 배포판과 플랫폼 전반에 걸쳐 패키지 관리를 통합하는 것은 매우 야심찬 일입니다... 성공할지 여부는 흥미로울 것입니다. 실제 문제는 패키지 이름이 때때로 배포판마다 다른 경향이 있다는 것입니다. 따라서 when:
차이를 처리하기 위해 여전히 사례 문이나 문을 수행해야 합니다.
제가 처리한 방식은 tasks
플레이북이나 역할에서 다음 디렉터리 구조를 따르는 것입니다.
roles/foo
└── tasks
├── apt_package.yml
├── foo.yml
├── homebrew_package.yml
├── main.yml
└── yum_package.yml
그리고 이것을 내 안에 넣으십시오 main.yml
:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
이것은 foo.yml
(패키지 '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'
그런 다음 다른 패키지 관리자의 경우:
적절한:
---
# 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
냠:
---
# 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
홈브류:
---
- name: Tap homebrew foobar/foo
homebrew_tap: >
name=foobar/foo
state=present
- homebrew: >
name=foo
state=latest
이것은 끔찍하게 반복적이며 그렇지 않습니다.마른, 그리고 어떤 것들은~할 것 같다플랫폼마다 다르기 때문에 처리해야 합니다. 일반적으로 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
그리고 그렇습니다. 다음과 같은 주장이 있습니다.일부패키지 이름은 배포판마다 다릅니다. 그리고 현재는쉽게 접근할 수 있는 데이터 부족, 나는 그것을 추측하고 싶습니다최대인기 있는 패키지 이름은 배포판 전반에 걸쳐 공통적이며 추상화된 패키지 관리자 모듈을 통해 설치할 수 있습니다. 특수한 경우는 어쨌든 처리해야 하며 이미 덜 DRY하게 만드는 추가 작업이 필요합니다. 의심스러운 경우 확인하세요.pkgs.org.
답변2
사실을 통해 패키지 관리자를 추상화할 수 있습니다.
- name: Install packages
with_items: package_list
action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"
필요한 것은 or 등 ansible_pkg_mgr
으로 설정하는 논리뿐입니다 .apt
yum
답변3
Ansible 2.0에는 새로운 -modul이 있습니다 Package
.
http://docs.ansible.com/ansible/package_module.html
그런 다음 제안한 대로 사용할 수 있습니다.
- name: install the latest version of Apache
package: name=httpd state=latest
여전히 이름 차이를 고려해야 합니다.
답변4
배포판마다 특정 패키지 이름이 다르기 때문에 그렇게 하고 싶지 않습니다. 예를 들어 RHEL 관련 배포판에서 널리 사용되는 웹 서버 패키지의 이름은 httpd
이고 Debian 관련 배포판에서는 이름이 입니다 apache2
. 다른 시스템 및 지원 라이브러리의 거대한 목록도 마찬가지입니다.
공통 기본 매개변수 세트가 있을 수 있지만 패키지 관리자마다 다른 고급 매개변수도 많이 있습니다. 그리고 일부 명령에 대해 하나의 구문을 사용하고 다른 명령에 대해 다른 구문을 사용하는 모호한 상황에 처하고 싶지는 않습니다.