Ansibleを支えるfact: プラットフォームの情報を取得¶
なんかそこはかとなくAnsibleが流行ってきているのがかなり意外な感じのr_rudiです。
さて、 Chefを支えるohai。プラットフォームの情報を取得するためのライブラリ に触発されて、Ansibleの機能であるfactについてご紹介したいと思います。
factって?¶
AnsibleにもChefと同じようにターゲットホストの情報を取得する機能があります。これを使って「Ubuntuならこれ」とか「FreeBSDならこれ」というように処理を分けたり、などができます。
具体的な使い方の例としてはこんな感じです。ここでは when を使って、Ubuntuの場合だけ実行しています。
- name: Ubuntuの場合だけ実行する
apt: pkg=apache2 state=present
when: ansible_distribution == "Ubuntu"
あるいは、変数に使ったりと、いろいろなところで使えます。例えば下のtaskはawesome-i686.tar.gz を取得します。
- name: アーキテクチャを指定して取得
get_url: url=http://example.com/awesome-{{ ansible_machine }}.tar.gz dest=/tmp/hoge.tar.gz
ちなみに、factの実行はそれなりに時間がかかるので、必要ない場合は以下のように gather_facts: no とすると早くなります。
- hosts: localhost
gather_facts: no
どんな情報が取れるの?¶
factで取得できる情報を調べるにはsetupモジュールを使います。JSON形式でずらずらと出てくることが分かります。 (モジュール単体実行なのでansible-playbookではありません)
% ansible <ホストパターン> -m setup
local | success >> {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"127.0.0.1"
],
"ansible_all_ipv6_addresses": [],
"ansible_architecture": "amd64",
さて、本題。
ohaiを使って情報を取得する¶
Ansibleのfactだけでも多くの情報が取れますが、Ohaiを使ってさらに情報を追加できます。
やり方は単にohaiを入れるだけです。ansibleは使えるのであればohaiも使って情報を追加します。
% gem install ohai
ohaiが使える状態で setup モジュールを実行すると、以下のような情報が追加されていることが分かります。 ohaiで取得した情報は ohai_ というprefixがついています。
"ohai_hostname": "ubuntu",
"ohai_idletime": "3 days 00 hours 20 minutes 36 seconds",
"ohai_ip6address": "fe80::a00:9999:998d:395e",
"ohai_ipaddress": "127.0.0.1",
"ohai_macaddress": "08:99:99:8D:39:5E",
"ohai_os": "linux",
"ohai_os_version": "3.5.0-25-generic",
残念ながらAnsibleから利用できる情報はTop Levelの限られた情報だけです。
ohai モジュールを使うとohaiで取得した情報がすべて取れますので、registerを使ってみようとしたのですが、だめでした。(あとでコード読みます)
% ansible all -c local -m ohai
facterを使って情報を取得する¶
もうひとつ、 Facter という同じような情報取得ライブラリがあります。ちなみにpuppetlabsが作っています。
これも同じようにsetupモジュールから使えますし、facter モジュールを別に使えます。
% gem install facter # facterインストール
% ansible all -c local -m facter
facterで取得した情報は facter_ というprefixがついています。
自分でfactを設定する¶
これまでは既存のライブラリを使った情報取得でした。これらに加えてAnsibleでは自分でfactを設定できます。
ただし、1.3からですので、1.2.3ユーザーは現状ではgithubからインストールする必要があります。
自分でfactを設定するには、fact_pathにファイルを設置します。fact_pathは初期設定は /etc/ansible/facts.d となっています。fact_pathは ターゲットホスト ということに気をつけてください。ですから、事前にtemplateモジュールなどを使って置く必要があります。
fact_pathはsetupモジュールの引数として設定できます。先頭で実行すれば以降のtaskで使えます。
---
- hosts: local
tasks:
- setup: fact_path=/tmp/fact.d/
- debug: msg={{ ansible_local.hige.number }}
静的なファイル¶
fact_path以下に ".fact" という拡張子がついたファイルを読み込みます。
iniファイル形式か、
% cat ./hoge.fact
[location]
city=Tokyo
phone=0399999999
JSON形式です。JSON形式では配列も使えます。
% cat ./hige.fact
{
"name" : "Me",
"number" : 42,
"phones" : [ "0399999999", "0311111111" ]
}
"ansible_local.factのファイル名" 以下にこの内容が追加されます。
% %ansible all -c local -m setup
localhost | success >> {
(..)
"ansible_local": {
"hoge": {
"location": {
"city": "Tokyo",
"phone": "0399999999"
}
}
},
(..)
}
playbookからはこんな感じで使います。
---
- hosts: local
tasks:
- name: せっかくだからおれはこのfactファイルを読み込むぜ!
debug: msg={{ ansible_local.hoge.location.city }}
動的に生成¶
同じ場所に実行属性があるファイルがあると実行してJSONを受け取ってくれます。
#!/bin/sh
COUNT=`who | wc -l`
cat <<EOF
{
"ansible_facts" : {
"users_logged_in" : $COUNT
}
}
EOF
まとめ¶
Ansibleを支える技術であるfactを紹介しました。これによって、templateで埋め込んだり、場合分けを行ったりできます。また、1.3からは、自作のfactを使えるので、例えばターゲットホストの負荷状況によって動作を変える、ということも可能です。
現在ではohaiの情報全てが使えるわけではないのが悲しいですが、 Pull Request を送っている ので、問題なければマージされるかと思います。
- 2013-10-15 追記
ついに マージ されました。
Comments
comments powered by Disqus