FabricからAnsibleのインベントリを美味しく参照する

#はじめに
構成管理ツールとしてAnsibleを使っていて、Fabricも、ということは多い。そこでFabricからAnsible側のインベントリ情報を参照する方法を紹介したい。この方法を使うとFabricのロールとしてAnsibleのグループを扱うことが可能になる。またAnsibleインベントリの強力な変数割り当て機能も手に入れることができる。

##Fabricとは
オーケストレーションツール、もしくはデプロイメントツール。公式サイトにはFabric is a Python library and command-line tool for streamlining the use of SSH for **application deployment or systems administration tasks**と書いてある。

##Ansibleとは
PuppetやChefと同じ構成管理ツールとしても使われるがオーケストレーションツールでもある。

##メリットは？
Fabricには外部設定ファイルを使って対象ホスト情報を管理する仕組みがない。一方AnsibleのCommandモジュールやShellモジュールにはFabric程の柔軟性がない。そのため実行時のパラメータ指定などFabricの方がより有効な状況も多く考えられる。また実行に長い時間がかかるもの処理の場合、途中経過が見れるというメリットもある。

#Hands-on


##Ansibleのグループをロールとして使えるようにする。

```shell:/etc/ansible/hosts
[web_servers]
127.0.0.1
127.0.0.2

[db_servers]
127.0.0.3
```

このインベントリファイルを参照するfabfileを作る。

```python:fabfile.py
from fabric.api import *
import ansible.inventory

inventory = ansible.inventory.Inventory('/etc/ansible/hosts')
env.roledefs = inventory.groups_list()

def hostname():
  run("echo %s" % env.host) 
```
ではweb_serversをロールとして指定して実行。

> $ fab -R servers hostname
> [127.0.0.1] Executing task 'hostname'
> [127.0.0.1] run: echo 127.0.0.1
> [127.0.0.1] out: 127.0.0.1
> [127.0.0.1] out: 
> 
> [127.0.0.2] Executing task 'hostname'
> [127.0.0.2] run: echo 127.0.0.2
> [127.0.0.2] out: 127.0.0.2
> [127.0.0.2] out: 
> 
> 
> Done.
> Disconnecting from 127.0.0.2... done.
> Disconnecting from 127.0.0.1... done.

Ansibleの通常動作と同じく、全てのホストが入っているallグループが自動で作られる。

> $ fab -R all hostname
> [127.0.0.1] Executing task 'hostname'
> [127.0.0.1] run: echo 127.0.0.1
> [127.0.0.1] out: 127.0.0.1
> [127.0.0.1] out: 
> 
> [127.0.0.2] Executing task 'hostname'
> [127.0.0.2] run: echo 127.0.0.2
> [127.0.0.2] out: 127.0.0.2
> [127.0.0.2] out: 
> 
> [127.0.0.3] Executing task 'hostname'
> [127.0.0.3] run: echo 127.0.0.3
> [127.0.0.3] out: 127.0.0.3
> [127.0.0.3] out: 
> 
> 
> Done.
> Disconnecting from 127.0.0.3... done.
> Disconnecting from 127.0.0.2... done.
> Disconnecting from 127.0.0.1... done.

##ホストごとに変数を設定するhost_varsを使ってみる。

```host_vars/127.0.0.1
hoge: a

```

```host_vars/127.0.0.2
hoge: b
```

```python:fabfile.py（追加）
#ansible-playbookと同じようにfabfileの置いてある所（もしくは実行するディレクトリ）の元にあるhost_vars, group_varsを参照するようにする。
inventory.set_playbook_basedir('.')

def show_var():
  vars = inventory.get_variables(env.host)
  run("echo %s" % vars['hoge'])
```
***

> $ fab -R web_servers show_var
> [127.0.0.1] Executing task 'show_var'
> [127.0.0.1] run: echo a
> [127.0.0.1] out: a
> [127.0.0.1] out: 
> 
> [127.0.0.2] Executing task 'show_var'
> [127.0.0.2] run: echo b
> [127.0.0.2] out: b
> [127.0.0.2] out: 
> 
> 
> Done.
> Disconnecting from 127.0.0.2... done.
> Disconnecting from 127.0.0.1... done.


***

##グループごとに変数を設定するgroup_varsを参照する。

```:group_vars/web_servers
type: web
```

```:group_vars/db_servers
type: db

```

```python:fabfile.py（追加）
def show_group_var():
  vars = inventory.get_variables(env.host)
  run("echo %s" % vars['type'])
```

> $ fab -R all show_group_var
> [127.0.0.1] Executing task 'show_group_var'
> [127.0.0.1] run: echo web
> [127.0.0.1] out: web
> [127.0.0.1] out: 
>
> [127.0.0.2] Executing task 'show_group_var'
> [127.0.0.2] run: echo web
> [127.0.0.2] out: web
> [127.0.0.2] out: 
> 
> [127.0.0.3] Executing task 'show_group_var'
> [127.0.0.3] run: echo db
> [127.0.0.3] out: db
> [127.0.0.3] out: 
> 
> 
> Done.
> Disconnecting from 127.0.0.3... done.
> Disconnecting from 127.0.0.2... done.
> Disconnecting from 127.0.0.1... done.

#まとめ
たった数行の追加で既存のAnsibleインベントリをそのまま参照しつつFabricを便利に使うことができる。もちろんFabricだけ使う場合にも有効なので是非どうぞ。