Ansible ZabbixモジュールでZabbix設定を自動化

12月、Advent Calendarの季節になりました。ということで今年はZabbixのAdvent Calendarにチャレンジしてみます！完走できるかな？皆さんよろしくお願いします！！

まず初日はAnsible(構成管理ツール)を使ってZabbixの設定を自動化する方法をご紹介。

# Ansible moduleって？

Ansibleは様々な処理をymlの定義ファイルに基づいて自動化できるよう幅広い処理ロジックをモジュールとして管理しています。
モジュールはより優先度の高いモジュール群をcoreとして管理し、その他様々なモジュールはextraという状態で管理されています。Ansibleの仕様に従う形で処理を実施できるようなPythonのコードを書けば非常に簡単にモジュール追加できるような仕組みとなっています。

現状、どのようなモジュールがあるかはこちらを参照してください。

[coreモジュール](https://github.com/ansible/ansible-modules-core)
[extraモジュール](https://github.com/ansible/ansible-modules-extras)
[All module manual](http://docs.ansible.com/ansible/list_of_all_modules.html)

# Ansible Zabbix moduleで何ができる？

このようなモジュールの1つとしてZabbixの設定を行うためのものが提供されています。現状、extraモジュールとして管理されています。
Zabbix moduleはコントロール対象ごとにわかれていて、以下のようなものがあります。

* zabbix_group (ver.1.8で実装)
* zabbix_maintenance (ver.1.8で実装)
* zabbix_host (ver.2.0で実装予定)
* zabbix_hostmacro (ver.2.0で実装予定)
* zabbix_screen (ver.2.0で実装予定)

2015/11/29現在、安定版としてリリースされているAnsibleは、1.9.4となっており、zabbix_groupとzabbix_maintenanceのみが含まれています。2.0で追加実装される予定となっていて、今後いろいろと適用範囲が広がるのではないかと思います。

そこで、今回はこのZabbix moduleを使って自動化する方法についてご紹介します。

# 導入

Zabbix moduleを利用するには実行元のサーバにPythonのZabbix APIライブラリ***zabbix-api***が必要となります。
Ansibleは通常、SSHで接続して処理を実行することになりますが、リモート先を起点としてこのZabbix moduleを実行したい場合にはリモート側にzabbix-apiのPythonライブラリをインストールする必要があるので注意が必要です。

しかし、このZabbix moduleは以降で解説する通り、Zabbix APIのURLを指定して処理が実行できるため、基本的には処理の起点はAnsibleをインストールしたサーバからで問題ないかと思います。

リモートのサーバにAnsibleで自動処理を行い、完了後、Zabbixにホスト登録をするといったシーンの場合、実行先のホストとしてはリモートサーバを指定して処理を実行し、Zabbix moduleを実行する部分のplaybookのみlocal_actionとして指定することでAnsibleがインストールされているローカル環境から実行することができます。

インストール方法は以下です。

## Ansibleのインストール

通常の安定版であればpipを使って以下を実行すればOKです。

```shell-session
$ pip install ansible
```

今回は、まだ正式版がリリースされていないAnsible 2.0のrc版を試すため、ソースコードから導入しました。

```shell-session
$ git clone git://github.com/ansible/ansible.git --recursive
$ cd ./ansible
$ pip install paramiko PyYAML Jinja2 httplib2 six #Ansibleに必要最低限のライブラリ
$ source ./hacking/env-setup #path設定等がダウンロードしたソースコードのbinに張られる
```

## zabbix-api Pythonライブラリのインストール

追加でzabbix-apiライブラリの導入が必要なのでインストールします。

```shell-session
$ pip install zabbix-api
```

これで事前準備はOK。

# playbookを書く
ここからは実際にplaybookを書いてZabbixの設定を自動化していきます。

## ホストを追加する

moduleにzabbix_hostを指定し、ZabbixAPI接続およびhostの追加に必要な情報をパラメータとして指定すればOKです。

```yaml:add-zabbix-host.yml
- hosts: localhost
  connection: local
  tasks:
    - name: Create a new host or update an existing host's info
      local_action:
        module: zabbix_host
        server_url: http://localhost/zabbix
        login_user: Admin
        login_password: zabbix
        host_name: ExampleHost
        host_groups:
          - Linux servers
        link_templates:
          - Template OS Linux
        status: enabled
        state: present
        interfaces:
          - type: 1
            main: 1
            useip: 1
            ip: 10.2.2.2
            dns: ""
            port: 10050
          - type: 4
            main: 1
            useip: 1
            ip: 10.3.3.3
            dns: ""
            port: 12345
```
これを実行すると以下の図のようにホストが新規作成されます。

```shell-session
$ ansible-playbook add-zabbix-host.yml
```
![ansible_host.png](https://qiita-image-store.s3.amazonaws.com/0/45851/d1efffa7-ed0d-981d-974b-6eac867bb895.png)

ホストを追加するだけなら「Zabbix Agentの自動登録機能とかでいいやん！」となりそうですが、AnsibleのZabbix moduleを使う利点としては、***更新にも追随して自動化できる***というところです。
stateの部分に着目してください。

ここにはpresent(存在していること)もしくはabsent(存在しないこと)が指定でき、present(デフォルト設定)とすることでymlファイルに指定した状態を保つように処理が自動化されます。
そのため、すでにホストが存在していても変更されている箇所の更新を自動化してくれます。
※ただし、上記設定例には記載していないですが、forceというパラメータがあり、ここをnoに設定すれば更新は行われません。

先ほどのymlファイルの一つ目のインタフェースのIPアドレスを10.2.2.2から10.2.2.100に変更して、再度playbookを実行します。
すると問題なくインタフェース情報のみ更新されます。

![host_change.png](https://qiita-image-store.s3.amazonaws.com/0/45851/51e88d90-7f15-edd7-efc2-549c6a1a2578.png)


Zabbix APIには、host.createというメソッド、host.updateというメソッドが別々に用意されており、Zabbix APIを用いて処理を自動化するにはホストの存在を確認して使い分けをしなければなりません。
そういった部分をAnsibleのmodule側でカバーしてくれているところは非常に使い勝手が良いポイントかと思います。

## 【参考】Zabbix Agentの自動登録

ZabbixにはAgentが起動時に自身の情報をZabbixに送付し、ホスト登録やテンプレート割当等を自動化できる機能があります。
この自動登録の機能は、***ホスト名をベース***にすでに登録されているかいないかを判定し、存在していないホスト情報が送られてきた時のみ登録作業を実施します。
そのため、一度ホスト登録されると、インタフェース情報の変更やテンプレート割当の変更等の更新処理は実施されません。
Zabbix Agentの自動登録のこういった仕様の制限もあり、Ansibleによって柔軟に自動化できる機構が活用できると非常に便利になるのではないかと思います。

#  その他活用例

その他の活用例としては、Zabbix moduleの中にはスクリーンの自動設定用のモジュールも含まれます。
例えば複数のホストのCPU使用率の一覧をスクリーンで一括で見たいといった場合、既存のZabbixの機能だけだと自動登録は難しく手作業が発生してしまいます。
こういったシーンにうまく活用すると、スクリーンの作成まで自動化できます。

```shell-session
- hosts: localhost
  connection: local
  tasks:
  - name: Create a new screen or update an existing screen's items
    local_action:
      module: zabbix_screen
      server_url: http://localhost/zabbix
      login_user: Admin
      login_password: zabbix
      screens:
        - screen_name: ExampleScreen1
          host_group: ansible test
          state: present
          graph_names:
            - CPU load
            - Memory usage
          graph_width: 200
          graph_height: 100
```
このplaybookを実行すると、「ansible test」というホストグループに含まれる全ホストの「CPU load」と「Memory usage」のグラフをExampleScreen1という名前のスクリーンに一括登録します。
出来上がったスクリーンは次のような感じです。

![screen.png](https://qiita-image-store.s3.amazonaws.com/0/45851/5c50daee-2c23-fde1-45fa-023a8f7931be.png)

1種類のグラフが横一列に並ぶような構成となります。
あまり細かくコントロールする機能はないですが、必要な情報をざっと一覧化するだけであればうまく活用できそうです。

# まとめ

Zabbixには多くの自動化機能があります。うまく使いこなせばほぼ全自動で監視運用が実現できます。それでも少し手の届きにくいところはZabbix APIを使ってつくり込んだりといった工夫が必要になります。そういったシーンにAnsibleのZabbix moduleを活用すれば自分で作りこむ部分を極力少なく適用できるかと思います。
Zabbix moduleの今後の機能拡張にも期待です。

Zabbix Advent Calendarの2日目は_BSmile_さんよろしくお願いします！！