ansible のインベントリ情報をもとに gitlab の wiki を更新する

クラウド上でインフラを構築したあと、チームメンバー間で共有するために、サーバーの一覧情報を Wiki に書きこむの、めんどくさい。
と思ったので、ansible のインベントリ情報をもとに gitlab の wiki を更新するというのをやってみました。

## 前提

* 利用する Gitlab のホストを `gitlab.your-company.com` とします
* 利用する Gitlab プロジェクトのパスを `your/project` とします
* あらかじめ `your/project` プロジェクトのページに 1 つ以上の Wiki ページを作っておく必要があるっぽいです (git を初期化しておくため？)
* あらかじめ `git clone git@gitlab.your-company.com` できるように SSH と Git を設定しておく必要があります

## 用意するファイル

インベントリはこんな感じだとします。

inventory/development

```
# cat inventory/development 
[rails]
rails001 public_ip=XXX.XXX.XXX.1 private_ip=192.168.10.1
rails002 public_ip=XXX.XXX.XXX.2 private_ip=192.168.10.2
rails003 public_ip=XXX.XXX.XXX.3 private_ip=192.168.10.3

[mysql]
mysql001 public_ip=XXX.XXX.XXX.11 private_ip=192.168.10.11
mysql002 public_ip=XXX.XXX.XXX.12 private_ip=192.168.10.12
mysql003 public_ip=XXX.XXX.XXX.13 private_ip=192.168.10.13

[redis]
mysql001 public_ip=XXX.XXX.XXX.21 private_ip=192.168.10.21
mysql002 public_ip=XXX.XXX.XXX.22 private_ip=192.168.10.22
mysql003 public_ip=XXX.XXX.XXX.23 private_ip=192.168.10.23

```

こんな playbook を作ります。

**update-wiki.yml**:

```
---
- name: Update wiki information
  hosts: all
  vars:
    gitlab_host: gitlab.your-company.com
    gitlab_path: your/project
  remote_user: root
  tasks:
  - name: Clone wiki repository
    local_action: "git repo=git@{{ gitlab_host }}:{{ gitlab_path }}.wiki.git dest=/tmp/{{ gitlab_path }}.wiki version=master"
    run_once: yes
  - name: Create sub directory
    local_action: "file path=/tmp/{{ gitlab_path }}.wiki/environments state=directory"
    run_once: yes
  - name: Update template
    local_action: "template src=update-wiki.md dest=/tmp/{{ gitlab_path }}.wiki/environments/{{ inventory_file | basename }}.md"
    run_once: yes
  - name: Push to repository
    local_action: "shell cd /tmp/{{ gitlab_path }}.wiki/ && git add . && git commit -mupdate && git push origin master"
    run_once: yes
    ignore_errors: yes
```

やってることとしてはこんな感じ。

1. `git@gitlab.your-company.com:your/project.wiki.git` を clone
2. `environments/development.md` というファイルにサーバーの一覧情報を書き込む
3. 上記を git add + commit + push

上記 playbook で参照されているテンプレートはこんな感じです。
(if のところがちょっとイマイチなので直したい…。)

**update-wiki.md**:

```
## Environment: {{ inventory_file | basename }}

| Group | Host | Public IP | Private IP |
|-------|------|-----------|------------|
{% for group, hosts in groups.iteritems() %}
{% if group != "all" and
      group != "ungrouped" and
      group != "development" and
      group != "staging" and
      group != "production" %}
{% for host in hosts %}
| {{ group }} | {{ host }} | {{ hostvars[host].public_ip }} | {{ hostvars[host].private_ip }} |
{% endfor %}
{% endif %}
{% endfor %}
```

## 実行してみる

インベントリのホストにログインする必要はないので `--connection local` をつけて `ansible-playbook` コマンドを実行します。

```
# ansible-playbook --connection local -i inventory/development update-wiki.yml 

PLAY [Update wiki information] *************************************************
(略)
```

余談ですが、2 回連続で実行したりすると、Git リポジトリに更新がないため「push する必要がないよ」エラーが出てしまいますが、`ignore_errors: yes` を指定しているので問題ないと思われます。

で、実行が完了すると、`https://gitlab.your-company.com/your/project/wikis/environments/development` に下記のようなページが作成されました。

![](https://i.gyazo.com/1a265beca7e46420305ef91fa0fcea7b.png)

## まとめ

ansible のインベントリ情報をもとに gitlab の wiki を更新することができました。
便利なのか微妙な気もするけど、サーバー一覧以外にも応用がききそうだし、インフラ情報を ansible のリポジトリで集中管理するような運用ができそうので、使いようによってはいいのかもしれません。

## 参考資料

* [Ansible マジック変数の一覧と内容 \- Qiita](http://qiita.com/h2suzuki/items/15609e0de4a2402803e9)
* [Ansibleチートシート（実行周り） \- Qiita](http://qiita.com/unarist/items/39f5510f95c752c10df1)
* [git \- Deploy software \(or files\) from git checkouts — Ansible Documentation](http://docs.ansible.com/ansible/git_module.html)
* [Ansible git module not checking out a branch \- Stack Overflow](http://stackoverflow.com/questions/30799503/ansible-git-module-not-checking-out-a-branch)
* [ansibleでの実行結果のsuccess/failedとignore\_errors/failed\_whenがよくわからなかったので調べてみた \- Qiita](http://qiita.com/sakaimo/items/67659a093f58d1922d54)