てんこ

ブログ名は愛猫(てん)の愛称です。中身は個人のIT系学習記録です。

AnsibleでA10のvThunderをいじってみた

今回は、AnsibleでA10 NetworksさんのvThunderにおいて、ClassListを定義する操作をやってみました。

Ansibleをインストールするだけでは導入されないモジュールをインストールから試すのが初めてなので、そのあたりも書いてみたいと思います。

A10さん機器向けのもくもく会用のコンテンツはこちらで公開されています。

圧倒的感謝!

中を確認してみたら、確かにa10_protocolが必要になってたりなど、最新のモジュールの仕様に合わせたコンテンツになっていました。

Ansible関連の実践記事一覧はこちら


目的

A10Networksさんのモジュールでどんな感じの操作ができるか確認するため。

環境

  • ansible: 2.9.0
  • python: 3.6.8 (virtualenv環境配下)
  • vThunder: 4.1.1-P9 build 105

モジュール実行環境の整備

A10 Networksさんのモジュールの導入方法はこちらに、丁寧に解説頂いています。

https://github.com/kishizuka4989/ansible_training_a10_thuner_adc/blob/master/1.0-adc-primer/202001_Ansible_Guide.pdf

私は、virtualenv環境だったので、以下の流れで実施。

■ 1. virtualenvをActivate

$ source <venv_path>/bin/activate
(venv_name)$ 

■ 2. gitでa10さんのリポジトリからデータをCloneしpipでインストール

$ git clone https://github.com/a10networks/a10-ansible a10-ansible 
$ cd a10-ansible/
$ pip install -e .

■3. 環境変数を修正(導入方法の要点に記載あり)

 $ export ANSIBLE_LIBRARY="/home/ansible/a10-ansible/a10_ansible/library"

■4. ansible.cfgを修正(virtualenv環境なため、これを入れないと、エラーが発生しました)

[defaults]
()
interpreter_python=/home/ansible/p3-ansible29/bin/python3

【参考】発生するエラーの内容

TASK [Create Class] **************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: NameError: name 'module' is not defined

Playbookのリファレンス

モジュールそのもののは、Gitに公開されています。

トップページに簡単な解説がありますが、それ以外のまとまったドキュメントはモジュールの中身を見て使い方を把握する…という感じなようです。

(もしかしたら法人として相談したらリファレンスガイドみたいなPDFを頂けたりするのかしら…)

ただ、いくつかサンプルPlaybookも公開されていますので、Playbook作成そのものにはあまり困らなさそうです。

特徴

上記の公開モジュールのTOPにも記載がありますが、A10さんのモジュールは他のモジュールと少し毛色が違う感じのstateが用意されています。

state 動作 説明
present 作成/上書き いつもの
absent 削除 いつもの
noop 情報取得 指定したモジュールに関連する現状設定取得
get_type: single で指定された要素の情報を取得
get_type: list でモジュールに関連する全情報を取得
get_type: oper でステータス情報を取得?(未確認)
get_type: stats でカウンタ情報を取得?(未確認)※指定なしだとこれっぽい

試しに、適当にclasslistを設定して情報を取ってみたものはこちら。

■取得用のPlaybook

---
- hosts: vthunder
  connection: local
  gather_facts: no

  vars:
    a10_host: "{{ ansible_host }}"

  tasks:
  - name: Create Class
    a10_class_list:
      a10_host: "{{ a10_host }}"
      a10_username: "{{ a10_username }}"
      a10_password: "{{ a10_password }}"
      a10_port: "{{ a10_port }}"
      a10_protocol: "{{ a10_protocol }}"
      name: "listname"
      state: noop
      get_type: single
    register: results

  - name: debug
    debug: 
      var: results

■出力結果

TASK [debug] *********************************************************************************************************************************************
ok: [192.168.10.63] => {
    "results": {
        "changed": false,
        "failed": false,
        "message": "",
        "original_message": "",
        "result": {
            "class-list": {
                "ac-list": [
                    {
                        "ac-key-string": "office365",
                        "ac-match-type": "contains"
                    },
                    {
                        "ac-key-string": "mogemoge.com",
                        "ac-match-type": "equals"
                    }
                ],
                "file": 0,
                "name": "listname",
                "type": "ac",
                "uuid": "d6168ac6-37df-11ea-a057-000c296a0844"
            }
        }
    }
}

注意点

fortios用のモジュールの癖で、情報取得→その要素を使ってPlaybook作成、なんていう流れがあったんですが、A10さんの場合、機器から帰ってくるキーがそのままPlaybook側で使える、というわけではなさそうです。

例:ClassListのタイプ

■情報取得で得られる形式

"type": "ac",

■Playbookでの指定方法

ntype: "ac"

このあたりは一定のルールはなさそうなので、都度モジュールの上のほうを見ながら、Requireを探したりキー情報を探したりする必要がありそうです。

また、fortiosのときにもあった、ハイフンとアンダーバーの変換も実施されているようでした。(こちらも本体内部はハイフン)

作成したPlaybook

前置きが長くなりましたが、こんなPlaybookを作って、ClassListを宣言することができました。

---
- hosts: vthunder
  connection: local
  gather_facts: no

  vars:
    a10_host: "{{ ansible_host }}"

  tasks:
  - name: Create Class
    a10_class_list:
      a10_host: "{{ a10_host }}"
      a10_username: "{{ a10_username }}"
      a10_password: "{{ a10_password }}"
      a10_port: "{{ a10_port }}"
      a10_protocol: "{{ a10_protocol }}"
      name: "listname"
      ntype: "ac"
      ac_list: 
         - ac_match_type: "contains"
           ac_key_string: "office365"
         - ac_match_type: "equals"
           ac_key_string: "mogemoge.com"
      state: present
    register: results

  - name: debug
    debug: 
      var: results


  - name: Write memory
    a10_write_memory:
      a10_host: "{{ a10_host }}"
      a10_username: "{{ a10_username }}"
      a10_password: "{{ a10_password }}"
      a10_port: "{{ a10_port }}"
      a10_protocol: "{{ a10_protocol }}"      
      state: present
      partition: all     

■出力結果

TASK [debug] *********************************************************************************************************************************************
ok: [192.168.10.63] => {
    "results": {
        "changed": true,
        "class-list": {
            "ac-list": [
                {
                    "ac-key-string": "office365",
                    "ac-match-type": "contains"
                },
                {
                    "ac-key-string": "mogemoge.com",
                    "ac-match-type": "equals"
                }
            ],
            "file": 0,
            "name": "listname",
            "type": "ac",
            "uuid": "303d478a-37e8-11ea-a057-000c296a0844"
        },
        "failed": false,
        "message": "",
        "original_message": "",
        "result": {}
    }
}

TASK [Write memory] **************************************************************************************************************************************
changed: [192.168.10.63]

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

■WebUI上で作成されたものを確認

f:id:tatematsu_san:20200115224643p:plain

感想

もくもく会以外で実際に触ってみた感想として、初動こそ少し手惑いましたが、本体内でエラーになった場合でもしっかりとリターンメッセージを返してくれたりと、これまで触ってきたfortios用モジュールよりもだいぶ丁寧に作られているなあ、という印象でした。(fortiiosモジュールは、エラーコードしか返してくれないので…)

今回作成したClassListは、前回のFortiosのSSL復号除外リストと同様、HTTPアクセス系の動きをコントロールするために利用します。このリストを共通化しつつForti/A10の各々の形式に変化して投入すれば、やりたいことができそうです。

このような、機器を挟んだ情報の連動をAnsibleを中心に組み立てたいところなので、もう少しいろいろと考えながら検証してみたいと思います。