てくなべ (tekunabe)

ansible / network / automation

[Ansible] Fortigate (fortiosモジュール)を httpapi コネクションプラグイン経由で触ってみた

はじめに

Ansible 2.8 以降、400以上大量に増えている fortios モジュール。Ansible 2.9 では httpapi コネクションプラグインにも対応しました。

httpapi コネクションプラグインに対応することにより、以下のようなメリットがあります。

  • Playbook がスッキリする
    • タスクごとに指定していた情報などを一括で変数で指定可能
  • インベントリ管理の統一化
    • サーバーなどと同じように、インベントファイルで、対象ホストを定義可能
  • 環境構築が少し楽に
    • Python ライブラリ fortiosapi が不要

従来の方式(legacy mode)を利用されたこちらの記事を拝見しました。

tenko.hatenablog.jp

こちらの記事を参考にさせていただいて、同じ処理を httpapi コネクションプラグインを利用するとどうなるか、という観点でご紹介します。

httpapi を利用できる fortios モジュールは Ansible 2.8 と 2.9 で追加されたモジュール

[2019/11/10 追記]

fortios_facts モジュールのように、Ansible 2.9 で追加されたモジュールには、公式ドキュメントの説明ページに

Support both legacy mode (local_action) and httpapi と書いてるので、httpapi に対応していることが分かります。

それだけでなく、fortios_firewall_address のような Ansible 2.8 で追加されたモジュールにまで遡って対応されているようでした。

色々調べていくと、モジュールのコード内に、httpapi と区別するための legacy_mode に関する定義があるモジュールが httpapi に対応しているであろう、とあたりがつきました。

これに基づいて調べた、httpapi に対応している fortios モジュールの一覧は以下のとおりです(Ansible 2.9.0 現在)。

結果としては、Ansible 2.8 と 2.9 で追加されたモジュールと一致しました。

クリックして広げる

準備

インベントリファイル、変数定義ファイル、Playbook を作成します。

インベントリファイル

対象の fortigate のホスト情報をインベントリに定義します。ここでは fortios というグループに所属させます。

  • inventory.ini
[fortios]
fortios01 ansible_host=10.0.0.254

後述の Playbook の hosts でこのグループ fortios を指定します。

変数定義ファイル

グループ fortios に所属するホストが利用する変数を定義します。 以下のように、認証情報や証明書検証の有無を指定できます。

  • group_vars/fortios.yml
ansible_user: admin                 # ユーザー名
ansible_password: xxxxxxx           # パスワード
ansible_network_os: fortios         # ネットワークOS
ansible_connection: httpapi         # httpapi コネクションプラグインを利用
ansible_httpapi_use_ssl: yes        # https を利用
ansible_httpapi_validate_certs: no  # 証明書の検証は無効

legacy mode で利用する各タスクに指定する接続情報と、httpapi コネクションプラグインの変数の対応は以下のとおりです。

項目 legacy mode のオプション httpapi コネクションプラグインの変数
ユーザー名 username ansible_user
パスワード password ansible_password
SSL/TLS の利用有無 https ansible_httpapi_use_ssl
証明書検証の有無 ssl_verify ansible_httpapi_validate_certs

なお、httpapi コネクションプラグインで利用できる変数の一覧は以下を参照してください。

docs.ansible.com

Playbook

fortios_facts モジュールを利用して除法を取得して、debug で出力させるサンプルです。

  • fortios_test.yml
---
- hosts: fortios    # localhost ではなくインベントリで定義したグループ
  gather_facts: false
  vars:
    vdom: "root"

  tasks:
  - name: Get Facts.
    fortios_facts:      # タスクに接続情報は不要
      vdom: "{{ vdom }}"
      gather_subset:
        - fact: 'system_status_select'
    register: getfact_result

  - name: Debug
    debug: 
      var: getfact_result

タスク(ここでは fortios_facts を利用ているタスク)には、接続情報( host username password オプション)は不要です。逆にタスクに接続情報が指定されていると、httpapi コネクションプラグインではく、legacy mode になるのでご注意ください。

Playbook 実行

Playbook を実行します。

$ ansible-playbook -i ../inventory.ini forti_test.yml 

PLAY [fortios] *******************************************************************************

TASK [Get Facts.] ****************************************************************************
ok: [fortios01]

TASK [Debug] *********************************************************************************
ok: [fortios01] => {
    "getfact_result": {
        "ansible_facts": {
            "ansible_net_gather_network_resources": [],
            "ansible_net_gather_subset": [],
            "ansible_network_resources": {
                "system_status_select": {
                    "action": "select",
                    "build": 1010,
                    "http_method": "GET",
                    "name": "status",
                    "path": "system",
                    "results": {},
                    "serial": "FGxxxxxxxxxxxx",
                    "status": "success",
                    "vdom": "root",
                    "version": "v6.2.2"
                }
            },
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": false,
        "failed": false,
        "warnings": [
            "Platform darwin on host fortios01 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information."
        ]
    }
}

PLAY RECAP ***********************************************************************************
fortios01                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

無事に接続して、システム情報が表示されました。

まとめ

Ansible から fortigate に対して、httpapi コネクションプラグインを利用して接続してみました。

前述の通り、Playbook がスッキリする、インベントリ管理の統一化、環境構築が少し楽に、といったメリットがありますので、対応しているモジュールであれば、httpapi コネクションプラグインが便利そうです。

ただ、Playbook 内に httpapi コネクションプラグインが利用できないモジュールも混在してる場合は、利用しているモジュールのすべてで利用できる方式に統一するほうがよさそうです。

参考

[2019/11/10 追記]

Python 2 系だと

addinfourl instance has no attribute

というエラーが発生するという情報がありました。

tenko.hatenablog.jp

[2019/12/05 追記]

Ansible 2.9.2 で Python 2/3 両方で使えるようになったようです。

ansible/CHANGELOG-v2.9.rst at stable-2.9 · ansible/ansible · GitHub

fortios httpapi plugin - fix the issue that fortios httpapi plugin does not support python2