
私はまずアンシブルそして、これを他のツールとともに、いくつかの 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"
2つのパッケージマネージャは異なることは理解していますが、それでも共通の基本的な使用法があります。他のオーケストレータ(例えば塩) には、単一のインストール コマンドがあります。
答え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
編集: マイケル・デハーン(Ansibleの作者)以来パッケージマネージャモジュールを抽象化しないことを選択したのようにシェフする、
Ansibleの古いバージョン(Ansible < 2.0)をまだ使用している場合残念ながら、これを処理する必要があります全てプレイブックとロールの詳細。 私見ではこれにより、プレイブックとロールの作成者に多くの不要な反復作業が押し付けられますが、これが現状です。パッケージマネージャーを抽象化して、その特定のオプションとコマンドをすべてサポートしようとするのではなく、パッケージマネージャーに依存しないパッケージを簡単にインストールする方法を用意する必要があると言っているわけではありません。スマートパッケージマネージャー流行に流されるのではなく、構成管理ツールに何らかのパッケージ インストール抽象化レイヤーがあると、クロスプラットフォームのプレイブックやクックブックを簡素化するのに非常に便利です。Smart プロジェクトは興味深いものですが、まだあまり採用されていないディストリビューションやプラットフォーム間でパッケージ管理を統一するという非常に野心的なプロジェクトです...成功するかどうかは興味深いところです。実際の問題は、パッケージ名がディストリビューション間で異なる傾向があるため、when:
違いを処理するために case ステートメントやステートメントを実行する必要があることです。
私が対処してきた方法は、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性が低下します。疑わしい場合は、翻訳元。
答え2
ファクトを介してパッケージマネージャを抽象化できます
- name: Install packages
with_items: package_list
action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"
必要なのは、 またはなどansible_pkg_mgr
を設定するロジックだけです。apt
yum
アンシブル将来のモジュールでやりたいことをやろうとしている。
答え3
Ansible 2.0 からは新しいPackage
-modul が追加されました。
これを提案のように使用できます。
- name: install the latest version of Apache
package: name=httpd state=latest
名前の違いも考慮する必要があります。
答え4
特定のパッケージ名はディストリビューション間で異なるため、これを実行することは望ましくありません。たとえば、RHEL 関連のディストリビューションでは、一般的な Web サーバー パッケージの名前は ですhttpd
が、Debian 関連のディストリビューションでは ですapache2
。他のシステム ライブラリやサポート ライブラリの膨大なリストについても同様です。
共通の基本パラメータのセットがあるかもしれませんが、パッケージ マネージャー間で異なる、より高度なパラメータも多数あります。また、一部のコマンドでは 1 つの構文を使用し、他のコマンドでは別の構文を使用するというあいまいな状況は避けたいものです。