第4回「システムからの情報取得」


前回のコラムでは自動化ツール上で動かす「プログラム」について説明しました。今回はシステムを構築する「プログラム」が使う情報の取得と管理について説明します。

プログラムには情報が必要です。情報が無いと、プログラムは決められた単純な動きしかできないでしょう。それは前回説明した自動化ツールの「プログラム」でも同様です。状況に応じた柔軟性のある動作を実現するには、システムの情報を「プログラム」が取得できなければなりません。それに加えてアプリケーション設定など、システムから取得するのではない、事前に決定している情報を何らかの方法で「プログラム」に渡さなければなりません。

自動化ツールではこれらの情報を取得し管理する手段を用意しています。今回はPuppet、Chef、Ansibleを利用した時の、システムからの情報取得について紹介します。

最初にPuppetの場合です。

Puppetには“Facter”と呼ばれる、システムを調査する機能があります。このFacterによって取得された情報を“facts”と呼んでいます。factsは“[facts名] => [値]”というハッシュのような形態になっており、マニフェストから変数名が“facts名”となったグローバルスコープの変数として参照できます。

ではfactsにはどのようなものがあるのでしょうか。確認するのは簡単です。Puppetがインストール済みの環境で「facter」というコマンドを実行します。なお、似たようなコマンドで「factor」というのがありますが、こちらは素因数分解のコマンドですので間違えないようにしましょう。

実行すると以下のようになります。

# facter

architecture => x86_64
augeasversion => 1.0.0
blockdevice_fd0_size => 4096
blockdevice_sda_model => VMware Virtual S
blockdevice_sda_size => 68719476736
blockdevice_sda_vendor => VMware,
blockdevice_sr0_model => VMware IDE CDR10
blockdevice_sr0_size => 1073741312
blockdevice_sr0_vendor => NECVMWar
blockdevices => fd0,sda,sr0

  :(中略)

timezone => JST
uniqueid => 11ac0500
uptime => 4:43 hours
uptime_days => 0
uptime_hours => 1
uptime_seconds => 6956
virtual => vmware

試しにマニフェストから読み出してみます。コンソールへの出力は“notify”というリソースを使います。factsのひとつである“architecture”を出力するのには以下のようにします。

# puppet apply -e 'notify { $::architecture: }'

Notice: Compiled catalog for 1b7c40925456 in environment production in 0.03 seconds
Notice: x86_64
Notice: /Stage[main]/Main/Notify[x86_64]/message: defined 'message' as 'x86_64'
Notice: Finished catalog run in 0.01 seconds

先ほどfacterで出力されたものと同じものが出力されています。このようにPuppetではシステムの情報をグローバルスコープの変数として参照できます。またfacterはビルトインで用意されている情報以外に、ユーザー側で情報取得用のコマンドやテキストを用意してfactsを拡張することもできます。今回は説明しませんので、詳細についてはFacterのドキュメント(https://puppet.com/docs/puppet/7/external_facts.html )で“External Facts”を参照してください。

次にChefの場合です。

Chefにも“Ohai”と呼ばれる、PuppetのFacterに相当する機能が備わっています。ohaiコマンドを実行すると、Puppetのfacts同様の情報が標準出力にJSON形式で出力されます。Cookbookからは“Automatic Attributes”として読み込まれていますので、ハッシュ変数として読み込むことができます。

それではOahiがどのような情報を取得できるのかohaiコマンドで確認してみます。実行すると以下のようになります。

# ohai
{
  "network": {
    "interfaces": {
      "lo": {
        "mtu": "65536",
        "flags": [
          "LOOPBACK",
          "UP",
          "LOWER_UP"
        ],

  :(中略)

      "version": "12.0.1",
      "chef_root": "/usr/local/share/gems/gems/chef-12.0.1/lib"
    }
  },
  "init_package": "bash",
  "hostname": "62df4fe76f89",
  "machinename": "62df4fe76f89",
  "fqdn": "62df4fe76f89",
  "domain": null

JSON形式でfactsよりも細かいところまで出力されているので、かなり大量のテキストが出力されました。ohaiコマンドの引数で出力したいアトリビュートを指定できますので、確認の際には指定してみると良いでしょう。

では試しにCookbookから読み出してみます。コンソールへの出力は“log”というリソースを使います。アトリビュートのひとつである“network”を出力するのには以下のようにします。

# chef-apply -e "log node['chef_packages']"

Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * log[{"ohai"=>{"version"=>"8.0.1", "ohai_root"=>"/usr/local/share/gems/gems/ohai-8.0.1/lib/ohai"}, "chef"=>{"version"=>"12.0.1", "chef_root"=>"/usr/local/share/gems/gems/chef-12.0.1/lib"}}] action write

正しく出力されましたが、多次元のハッシュになっています。例えばこの出力結果のうち“chef['version']”だけを取得したい場合は以下のように記述します。

# chef-apply -e "log node['chef_packages']['chef']['version']"

Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * log[12.0.1] action write

CookbookがRubyなので当然と言えばそれまでですが、Rubyでの一般的なハッシュ変数と同じ使い方ですね。Ohaiも用意されているアトリビュート以外に、“Custom Plugins”によってユーザー側でアトリビュートを拡張することができます。こちらについても今回は説明しませんので、詳細はOhaiのドキュメント(https://docs.chef.io/ohai.html)で“Custom Plugins”を参照してください。

最後にAnsibleをみてみましょう。

Ansibleでは、ホスト情報のことをPuppetに習いfactsと呼んでいます。例えばlocalhostのホスト情報は下記のコマンドによる取得することができます。

# ansible localhost -m setup

localhost | success >> {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.2.15"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::a00:27ff:fe92:19ef"
        ],
        "ansible_architecture": "x86_64",
	
    ...

        "ansible_virtualization_role": "guest",
        "ansible_virtualization_type": "virtualbox",
        "facter_architecture": "amd64",
        "facter_blockdevice_sda_model": "VBOX HARDDISK",

         ...

        "facter_uptime_seconds": 1903,
        "facter_virtual": "virtualbox",

  	 ...

        "ohai_block_device": {
            "loop0": {
                "removable": "0",
                "size": "0"
            },
            "loop1": {
                "removable": "0",
                "size": "0"
            },

JSON形式でホスト情報が出力されるので、Chefに近いですね。

Ansibleの特徴としては、前述したfacterやohaiがインストールされていれば、それらの情報も取得することができます。上記の例では、facter_、ohai_で始まる情報がそれぞれfacterとohaiから取得した情報になります。

facts変数を利用するには、{{変数名}}という形式で記述します。例えば、ansible_architectureを参照するサンプル(プレイブック)は次のようになります。

  - hosts: localhost
    tasks:
     - debug: msg="Architecture {{ ansible_architecture }}"

次回はアプリケーション設定などのシステムから取得する以外の情報管理について、詳細をお話します。



第4回「システムからの情報取得」