나는 asible로 시작하여 여러 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"
두 패키지 관리자가 다르지만 여전히 공통적 인 기본 사용법이 있습니다. 다른 오케 스트레이터 ( 예 : 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_mgr
에 apt
또는 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
입니다. 다른 시스템 및 지원 라이브러리 목록도 비슷합니다.
공통 기본 매개 변수 세트가있을 수 있지만 패키지 관리자마다 다른 고급 매개 변수도 있습니다. 그리고 어떤 명령에는 하나의 구문을 사용하고 다른 명령에는 다른 구문을 사용하는 모호한 상황에 처하기를 원하지 않습니다.