Travis CI + docker-compose + ansibleでzabbixモジュールのCIをやる

Travis CIとdocker-composeとansibleを使ってzabbixのモジュールをテストを自動化してみました。

# やりたかったこと

* Python2.7、3.5、3.6、3.7ごとのAnsible動作試験をしたかった
* Zabbixの各バージョンでAnsibleのZabbixモジュールの動作試験をしたかった
* Zabbixの複数バージョンを使うのでコンテナを使いたかった(バージョンごとにVMのインスタンスを立てたくなかった)

# 作成したファイル

今回作ったファイルは以下に保存されています。

[https://github.com/sky-joker/travis-ci-zabbix-test](https://github.com/sky-joker/travis-ci-zabbix-test)

## travis.yml

`travis.yml` は以下のように書きました。
composeをインストールしてpipでansibleとzabbix-api(zabbixモジュールを動かすのに必要)をインストールしてコンテナを立ち上げzabbixの起動を確認するPlaybookを実行し、各コンテナが起動したらlocaleを設定してからモジュールのテストPlaybookを実行しています。
テストするpythonのバージョンは `2.7` `3.5` `3.6` `3.7` を指定しています。(3.8は無かった)

```yaml
language: python
python:
  - "2.7"
  - "3.5"
  - "3.6"
  - "3.7-dev"

services:
  - docker

install:
  - sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  - sudo chmod +x /usr/local/bin/docker-compose
  - pip install ansible zabbix-api
  - sudo docker-compose up -d
  - ansible-playbook zabbix_startup_check.yml
  - sh set_zabbix_locale.sh

script:
  - ansible-playbook test_zabbix_group.yml
```

## docker-compose.yml

ここでは、zabbix3.0からzabbix4.2までのコンテナ（公式イメージ）が起動するように定義しました。
アクセスするポートごとにzabbixのバージョンを分けました。

```yaml
---
version: '3.7'
services:
  # Zabbix Server 3.0
  zabbix30-db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: "zabbix"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
  zabbix30-server:
    image: zabbix/zabbix-server-mysql:centos-3.0-latest
    environment:
      DB_SERVER_HOST: "zabbix30-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
    depends_on:
      - "zabbix30-db"
    links:
      - "zabbix30-db"
  zabbix30-web:
    image: zabbix/zabbix-web-apache-mysql:centos-3.0-latest
    environment:
      DB_SERVER_HOST: "zabbix30-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
      ZBX_SERVER_HOST: "zabbix30-server"
      PHP_TZ: "Asia/Tokyo"
    depends_on:
      - "zabbix30-db"
      - "zabbix30-server"
    links:
      - "zabbix30-db"
      - "zabbix30-server"
    ports:
      - "8030:80"

  # Zabbix Server 3.2
  zabbix32-db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: "zabbix"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
  zabbix32-server:
    image: zabbix/zabbix-server-mysql:centos-3.2-latest
    environment:
      DB_SERVER_HOST: "zabbix32-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
    depends_on:
      - "zabbix32-db"
    links:
      - "zabbix32-db"
  zabbix32-web:
    image: zabbix/zabbix-web-apache-mysql:centos-3.2-latest
    environment:
      DB_SERVER_HOST: "zabbix32-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
      ZBX_SERVER_HOST: "zabbix32-server"
      PHP_TZ: "Asia/Tokyo"
    depends_on:
      - "zabbix32-db"
      - "zabbix32-server"
    links:
      - "zabbix32-db"
      - "zabbix32-server"
    ports:
      - "8032:80"

  # Zabbix Server 3.4
  zabbix34-db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: "zabbix"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
  zabbix34-server:
    image: zabbix/zabbix-server-mysql:centos-3.4-latest
    environment:
      DB_SERVER_HOST: "zabbix34-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
    depends_on:
      - "zabbix34-db"
    links:
      - "zabbix34-db"
  zabbix34-web:
    image: zabbix/zabbix-web-apache-mysql:centos-3.4-latest
    environment:
      DB_SERVER_HOST: "zabbix34-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
      ZBX_SERVER_HOST: "zabbix34-server"
      PHP_TZ: "Asia/Tokyo"
    depends_on:
      - "zabbix34-db"
      - "zabbix34-server"
    links:
      - "zabbix34-db"
      - "zabbix34-server"
    ports:
      - "8034:80"

  # Zabbix Server 4.0
  zabbix40-db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: "zabbix"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
  zabbix40-server:
    image: zabbix/zabbix-server-mysql:centos-4.0-latest
    environment:
      DB_SERVER_HOST: "zabbix40-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
    depends_on:
      - "zabbix40-db"
    links:
      - "zabbix40-db"
  zabbix40-web:
    image: zabbix/zabbix-web-apache-mysql:centos-4.0-latest
    environment:
      DB_SERVER_HOST: "zabbix40-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
      ZBX_SERVER_HOST: "zabbix40-server"
      PHP_TZ: "Asia/Tokyo"
    depends_on:
      - "zabbix40-db"
      - "zabbix40-server"
    links:
      - "zabbix40-db"
      - "zabbix40-server"
    ports:
      - "8040:80"

  # Zabbix Server 4.2
  zabbix42-db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: "zabbix"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
  zabbix42-server:
    image: zabbix/zabbix-server-mysql:centos-4.2-latest
    environment:
      DB_SERVER_HOST: "zabbix42-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
    depends_on:
      - "zabbix42-db"
    links:
      - "zabbix42-db"
  zabbix42-web:
    image: zabbix/zabbix-web-apache-mysql:centos-4.2-latest
    environment:
      DB_SERVER_HOST: "zabbix42-db"
      MYSQL_USER: "zabbix"
      MYSQL_PASSWORD: "zabbix"
      MYSQL_DATABASE: "zabbix"
      MYSQL_ROOT_PASSWORD: "zabbix"
      ZBX_SERVER_HOST: "zabbix42-server"
      PHP_TZ: "Asia/Tokyo"
    depends_on:
      - "zabbix42-db"
      - "zabbix42-server"
    links:
      - "zabbix42-db"
      - "zabbix42-server"
    ports:
      - "8042:80"
```

## zabbix_startup_check.yml

これは、compose実行後にzabbixの起動を確認するPlaybookです。
以下のように書いています。

```yaml
---
- name: zabbix startup check
  hosts: localhost
  gather_facts: no
  tasks:
    - name: check login to zabbix.
      uri:
        url: "http://127.0.0.1:{{ item }}/api_jsonrpc.php"
        method: POST
        body:
          jsonrpc: "2.0"
          method: "user.login"
          params:
            user: "admin"
            password: "zabbix"
          id: "1"
        body_format: json
        status_code: 200
      retries: 60
      delay: 5
      until: result is defined and 'json' in result and 'result' in result.json
      register: result
      loop:
        - 8030
        - 8032
        - 8034
        - 8040
        - 8042
```

## set_zabbix_locale.sh

デフォルトだと日本語などが使えない（英語のみ）のでコンテナ内でlocaleを設定します。

```sh
#!/bin/sh
 
for c in $( docker ps --format '{{.Names}}' | grep web ) ; do
    docker exec $c localedef -f UTF-8 -i zh_CN zh_CN
    docker exec $c localedef -f UTF-8 -i cs_CZ cs_CZ
    docker exec $c localedef -f UTF-8 -i fr_FR fr_FR
    docker exec $c localedef -f UTF-8 -i he_IL he_IL
    docker exec $c localedef -f UTF-8 -i it_IT it_IT
    docker exec $c localedef -f UTF-8 -i ko_KR ko_KR
    docker exec $c localedef -f UTF-8 -i ja_JP ja_JP
    docker exec $c localedef -f UTF-8 -i nb_NO nb_NO
    docker exec $c localedef -f UTF-8 -i pl_PL pl_PL
    docker exec $c localedef -f UTF-8 -i pt_BR pt_BR
    docker exec $c localedef -f UTF-8 -i pt_PT pt_PT
    docker exec $c localedef -f UTF-8 -i ru_RU ru_RU
    docker exec $c localedef -f UTF-8 -i sk_SK sk_SK
    docker exec $c localedef -f UTF-8 -i tr_TR tr_TR
    docker exec $c localedef -f UTF-8 -i uk_UA uk_UA
    docker exec $c apachectl -k graceful
done
```

## test_zabbix_group.yml

実際に実行するテストは以下のように書いています。

```yaml
---
- name: zabbix grpuo module test.
  hosts: localhost
  gather_facts: no
  vars:
    zabbix_server: "http://127.0.0.1"
    zabbix_user: "admin"
    zabbix_passwd: "zabbix"
    zabbix_ports:
      - 8030
      - 8032
      - 8034
      - 8040
      - 8042
    zabbix_groups:
      - Example1
      - Example2
  tasks:
    - name: create of zabbix host group.
      zabbix_group:
        server_url: "{{ zabbix_server }}:{{ item }}"
        login_user: "{{ zabbix_user }}"
        login_password: "{{ zabbix_passwd }}"
        validate_certs: no
        host_groups: "{{ zabbix_groups }}"
        state: present
      loop: "{{ zabbix_ports }}"

    - name: delete of zabbix host group.
      zabbix_group:
        server_url: "{{ zabbix_server }}:{{ item }}"
        login_user: "{{ zabbix_user }}"
        login_password: "{{ zabbix_passwd }}"
        validate_certs: no
        host_groups: "{{ zabbix_groups }}"
        state: absent
      loop: "{{ zabbix_ports }}"
```

# 実行結果例

問題なければ以下のように表示されます :)

[![](https://sky-joker.tech/wp-content/uploads/2019/05/d03421321919f2f81bff20436f3301df.png)](https://sky-joker.tech/wp-content/uploads/2019/05/d03421321919f2f81bff20436f3301df.png)

[![](https://sky-joker.tech/wp-content/uploads/2019/05/da017fac7dbdccea57d8d50b8063fa0e.png)](https://sky-joker.tech/wp-content/uploads/2019/05/da017fac7dbdccea57d8d50b8063fa0e.png)

# 2019/06/24 追記

いくつかに分かれていたファイルをPlaybook化しました。
https://gist.github.com/sky-joker/fd22535f0d715e5cd64503e13f0a8cea