web-dev-qa-db-ja.com

パッケージインストールタスクをansibleで統合する方法

私は ansible から始めて、とりわけ、いくつかの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"

2つのパッケージマネージャーが異なることを理解していますが、共通の基本的な使用法がまだあります。他のオーケストレーター( たとえば、塩 )には、単一のインストールコマンドがあります。

71
WoJ

更新:Ansible 2.0以降では、ジェネリック&アブストラクト package module が追加されました

使用例:

異なる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)をまだ使用している場合、残念ながらこれを行う必要がありますプレイブックと役割のall[〜#〜] imho [〜#〜]これにより、不要な反復作業の多くがプレイブックとロールの作成者に押し付けられます...しかし、それは現在の方法です。特定のオプションとコマンドをすべてサポートする一方で、パッケージマネージャーを抽象化しようとする必要はありませんが、パッケージマネージャーに依存しないパッケージをインストールする簡単な方法があることに注意してください。 Smart Package Manager bandwagonにジャンプする必要があるとも言っていませんが、構成管理ツールのある種のパッケージインストール抽象化レイヤーは、クロスプラットフォームのプレイブック/クックブックを単純化するのに非常に便利です。 。スマートプロジェクトは興味深いように見えますが、まだあまり採用されていないディストリビューションやプラットフォーム全体でパッケージ管理を統合することはかなり野心的です...成功するかどうかを確認することは興味深いでしょう。実際の問題は、パッケージ名がディストリビューション間で異なる場合があるため、caseステートメントまたは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'

次に、さまざまなパッケージマネージャーの場合:

Apt:

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

自作:

---
- name: Tap homebrew foobar/foo
  homebrew_tap: >
    name=foobar/foo
    state=present

- homebrew: >
    name=foo
    state=latest

これはひどく反復的であり、 DRY ではありません。いくつかのmightはプラットフォームによって異なり、処理する必要がありますが、一般にこれは冗長で扱いにくいと思いますシェフのものと比較すると:

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

そして、はい、-someパッケージ名はディストリビューション間で異なるという議論があります。そして、現在 簡単にアクセスできるデータの欠如 がありますが、most人気のあるパッケージ名が一般的であると思いますディストリビューション間で、抽象化されたパッケージマネージャーモジュールを介してインストールできます。いずれにせよ、特別なケースは処理する必要があり、D.R.Y。疑わしい場合は、 pkgs.org を確認してください。

69
TrinitronX

ファクトを介してパッケージマネージャーを抽象化できます

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

必要なのは、ansible_pkg_mgraptまたはyumなどに設定するロジックです。

Ansible 将来のモジュールでやりたいことにも取り組んでいます

13
xddsg

Ansible 2.0から、新しいPackage- modulがあります。

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

その後、提案のように使用できます。

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

名前の違いを考慮する必要があります。

6
Tvartom

条件付きインポート に関するAnsibleのドキュメントを確認してください。

各OSでサービス名が異なる場合でも、Apacheが実行されていることを確認する1つのタスク。

---
- 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
3
David Vasandani

ディストリビューション間で特定のパッケージ名が異なるため、これを行う必要はありません。たとえば、RHEL関連のディストリビューションでは、人気のあるWebサーバーパッケージの名前はhttpdですが、Debian関連のディストリビューションでは、Apache2。同様に、他のシステムとサポートライブラリの膨大なリストがあります。

共通の基本パラメーターのセットがあるかもしれませんが、パッケージマネージャー間で異なる多くの高度なパラメーターもあります。また、一部のコマンドでは1つの構文を使用し、他のコマンドでは別の構文を使用するというあいまいな状況になりたくありません。

2
Mxx