私は ansible から始めて、とりわけ、いくつかの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つのパッケージマネージャーが異なることを理解していますが、共通の基本的な使用法がまだあります。他のオーケストレーター( たとえば、塩 )には、単一のインストールコマンドがあります。
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 を確認してください。
ファクトを介してパッケージマネージャーを抽象化できます
- 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
- modulがあります。
http://docs.ansible.com/ansible/package_module.html
その後、提案のように使用できます。
- name: install the latest version of Apache
package: name=httpd state=latest
名前の違いを考慮する必要があります。
条件付きインポート に関する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
ディストリビューション間で特定のパッケージ名が異なるため、これを行う必要はありません。たとえば、RHEL関連のディストリビューションでは、人気のあるWebサーバーパッケージの名前はhttpd
ですが、Debian関連のディストリビューションでは、Apache2
。同様に、他のシステムとサポートライブラリの膨大なリストがあります。
共通の基本パラメーターのセットがあるかもしれませんが、パッケージマネージャー間で異なる多くの高度なパラメーターもあります。また、一部のコマンドでは1つの構文を使用し、他のコマンドでは別の構文を使用するというあいまいな状況になりたくありません。