[server] ansible에서 패키지 설치 작업을 통합하는 방법은 무엇입니까?

나는 asible로 시작하여 여러 Linux 배포판에 패키지를 설치하는 데 사용할 것입니다.

문서에서 yumapt명령이 분리되어 있음을 알 수 있습니다. 통합하고 다음과 같은 것을 사용하는 가장 쉬운 방법은 무엇입니까?

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

두 패키지 관리자가 다르지만 여전히 공통적 인 기본 사용법이 있습니다. 다른 오케 스트레이터 ( : salt )에는 단일 설치 명령이 있습니다.



답변

업데이트 : 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의 제작자) Chef 와 같은 패키지 관리자 모듈을 추상화하지 않기로 선택 했기 때문에 ,

여전히 이전 버전의 Ansible (Ansible <2.0)을 사용하는 경우 불행히도 모든 플레이 북 및 역할에서이 작업을 처리해야합니다. IMHO는 이것으로 많은 불필요한 반복 작업을 플레이 북 및 역할 저자에게 밀어 붙이고 있습니다. 그러나 그것은 현재의 방식입니다. 특정 옵션과 명령을 모두 지원하면서 패키지 관리자를 추상화하려고 시도하지는 않지만 패키지 관리자와 무관 한 패키지를 쉽게 설치할 수 있습니다. 또한 우리는 모두 Smart Package Manager 에 뛰어 들어야한다고 말하지 않습니다.구성 관리 도구의 일종의 패키지 설치 추상화 계층은 플랫폼 간 플레이 북 / 요리 책을 단순화하는 데 매우 유용합니다. 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

m :

---
# 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

이 몹시 반복적이고 않음을 유의 DRY , 그리고 몇 가지가 있지만 수있는 다른 플랫폼에서 다를 수 및 처리되어야 할 것이다, 일반적으로 내가 요리사의 비교했을 때이 장황하고 다루기 생각 :

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를 확인 하십시오 .


답변

사실을 통해 패키지 관리자를 추출 할 수 있습니다

- name: Install packages
  with_items: package_list
  action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"

당신이 필요로하는 설정 일부 로직 ansible_pkg_mgrapt또는 yum

Ansible 은 또한 향후 모듈에서 원하는 작업을 수행하고 있습니다 .


답변

Ansible 2.0부터는 새로운 Package모듈이 있습니다.

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

그런 다음 제안처럼 사용할 수 있습니다.

- name: install the latest version of Apache
  package: name=httpd state=latest

여전히 이름 차이를 고려해야합니다.


답변

조건부 가져 오기 에 대한 Ansible의 문서를 확인하십시오 .

서비스 이름이 OS마다 다르더라도 아파치가 실행되고 있는지 확인하는 한 가지 작업입니다.

---
- hosts: all
  remote_user: root
  vars_files:
    - "vars/common.yml"
    - [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
  tasks:
  - name: make sure apache is running
    service: name={{ apache }} state=running


답변

배포판마다 특정 패키지 이름이 다르기 때문에 그렇게하고 싶지 않습니다. 예를 들어 RHEL 관련 배포판에서 널리 사용되는 웹 서버 패키지의 이름은이며 httpd, 데비안 관련 배포판에서는 이름이 apache2입니다. 다른 시스템 및 지원 라이브러리 목록도 비슷합니다.

공통 기본 매개 변수 세트가있을 수 있지만 패키지 관리자마다 다른 고급 매개 변수도 있습니다. 그리고 어떤 명령에는 하나의 구문을 사용하고 다른 명령에는 다른 구문을 사용하는 모호한 상황에 처하기를 원하지 않습니다.


답변