Ansible で PaloAlto のアドレスオブジェクトを追加する

  • 4
    Like
  • 0
    Comment

1. Ansible のPAN-OS対応

Ansible 2.3 では、PAN-OSに対応した様々なモジュールが導入されました。
https://docs.ansible.com/ansible/list_of_network_modules.html#panos

今回は panos_address を利用して、アドレスオブジェクトを作成してみます。

2. インストール

2.1. Ansible

pip install ansible

2.2. pan-python, pandevice

PAN-OS 関連のモジュールは内部でpan-pythonとpandeviceというPythonのモジュールを利用しているためインストールしておきます。

pan-python,pandeviceのインストール
pip install pan-python pandevice

2.3. バージョン確認

バージョン確認
[root@localhost ~]# ansible --version
ansible 2.3.0.0
  config file =
  configured module search path = Default w/o overrides
  python version = 2.7.8 (default, Oct 22 2016, 09:02:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]

ansible.cfg は特に作成していません。

3. インベントリファイルの作成

インベントリファイル例(/etc/ansible/hosts)
[palo]
192.168.0.15  # 今回は1台だけ

[palo:vars]
ansible_user=admin
ansible_password=passwordpassword

4. Plyaybookの作成

以下のファイルを palo_addr.yml として作成します。

Playbook
---
- hosts: palo
  gather_facts: no
  connection: local

  tasks:
    - name: create address object
      panos_address:
        ip_address: "{{ inventory_hostname }}"  # オブジェクトのアドレスではなくPaloaltoのアドレス
        username: "{{ ansible_user }}"
        password: "{{ ansible_password }}"
        address_name: "client_pc01"
        address: "192.168.0.101/32"
        commit: False   # 今回はcommitまでしない

本モジュールの公式ドキュメントが参考になります。

5. 動作確認

5.1. アドレス追加

5.1.1 事前確認

アドレスオブジェクトが何もない状態から始めます。

コンフィグ事前確認
admin@PA-2050# show address
address;
[edit]
admin@PA-2050#

5.1.2 Playbook実行

実行
[root@localhost ~]# ansible-playbook palo_addr.yml

PLAY [palo] **************************************************************************************************

TASK [create address Object] *********************************************************************************
ok: [192.168.1.15]

PLAY RECAP ***************************************************************************************************
192.168.1.15               : ok=1    changed=1    unreachable=0    failed=0

5.1.3 コンフィグ確認

ポリシーが追加されました。

コンフィグ事後確認
admin@PA-2050# show address
address {
  client_pc01 {
    ip-netmask 192.168.0.101/32;
  }
}

5.2 アドレス変更

ここで、既存アドレスオブジェクトのアドレスを変更することにします。

5.2.1. Playbook変更

address"192.168.0.101/32" に変更します。

Playbook(アドレス変更バージョン)
---
- hosts: palo
  gather_facts: no
  connection: local

    - name: create address Object
      panos_address:
        ip_address: "{{ inventory_hostname }}"
        username: "{{ ansible_user }}"
        password: "{{ ansible_password }}"
        address_name: "client_pc01"
        address: "192.168.0.102/32"        # ここ変更
        commit: False

5.2.2 Playbook再実行

Playbookを変更したところで、もう一度実行します。

実行
[root@localhost ~]# ansible-playbook palo_addr.yml

PLAY [palo] **************************************************************************************************

TASK [create address Object] *********************************************************************************
ok: [192.168.1.15]

PLAY RECAP ***************************************************************************************************
192.168.1.15               : ok=1    changed=0    unreachable=0    failed=0

おやおや? changed=0 とあるように、で変更がかかりませんでした。

IPアドレスの変更は変更とはみなされないようです。

5.3 アドレス名変更

今度は、アドレスではなく、アドレス名を変更することにします。

5.3.1. Playbook変更

address_name"client_pc02" に変更します。

Playbook(アドレス名変更バージョン)
---
- hosts: palo
  gather_facts: no
  connection: local

    - name: create address Object
      panos_address:
        ip_address: "{{ inventory_hostname }}"
        username: "{{ ansible_user }}"
        password: "{{ ansible_password }}"
        address_name: "client_pc02"        # ここ変更
        address: "192.168.0.101/32"
        commit: False

5.3.2 Playbook再実行

実行
[root@localhost ~]# ansible-playbook palo_addr.yml

PLAY [palo] **************************************************************************************************

TASK [create address Object] *********************************************************************************
changed: [192.168.1.15]

PLAY RECAP ***************************************************************************************************
192.168.1.15               : ok=1    changed=1    unreachable=0    failed=0

今度は changed=1 となりました。

5.3.3 コンフィグ確認

変更ではなく、アドレス名が別のオブジェクトが追加されました。

コンフィグ事後確認
admin@PA-2050# show address
address {
  client_pc01 {
    ip-netmask 192.168.0.101/32;
  }
  client_pc02 {
    ip-netmask 192.168.0.101/32;
  }
}

オブジェクト名があるかないかを見て、無ければ追加という扱いのようです。

6. (補足)Python 2.6 でのエラーについて

Python 2.6 環境では ansible-playbook 実行時に pandevice 内で以下エラーとなり、正常に実行できませんでした。そのため、今回はPython 2.7 の環境で実行しています。

python2.6での実行時エラー
Using module file /root/ansible/ansible/lib/ansible/modules/network/panos/panos_security_policy.py
<192.168.1.15> ESTABLISH LOCAL CONNECTION FOR USER: root
<192.168.1.15> EXEC /bin/sh -c 'echo ~ && sleep 0'
<192.168.1.15> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1491081586.53-46889509406412 `" && echo ansible-tmp-1491081586.53-46889509406412="` echo /root/.ansible/tmp/ansible-tmp-1491081586.53-46889509406412 `" ) && sleep 0'
<192.168.1.15> PUT /tmp/tmpKdGZ_T TO /root/.ansible/tmp/ansible-tmp-1491081586.53-46889509406412/panos_security_policy.py
<192.168.1.15> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1491081586.53-46889509406412/ /root/.ansible/tmp/ansible-tmp-1491081586.53-46889509406412/panos_security_policy.py && sleep 0'
<192.168.1.15> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1491081586.53-46889509406412/panos_security_policy.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1491081586.53-46889509406412/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_JzsakO/ansible_module_panos_security_policy.py", line 264, in <module>
    import pandevice.firewall
  File "/usr/lib/python2.6/site-packages/pandevice/firewall.py", line 27, in <module>
    from pandevice import device
  File "/usr/lib/python2.6/site-packages/pandevice/device.py", line 19, in <module>
    from base import PanObject, Root, MEMBER, ENTRY
  File "/usr/lib/python2.6/site-packages/pandevice/base.py", line 1224
    option_paths = {opt: re.sub(r"\([\w\d|-]*\)", opt, path) for opt in options}
                                                               ^
SyntaxError: invalid syntax

fatal: [192.168.1.15]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_JzsakO/ansible_module_panos_security_policy.py\", line 264, in <module>\n    import pandevice.firewall\n  File \"/usr/lib/python2.6/site-packages/pandevice/firewall.py\", line 27, in <module>\n    from pandevice import device\n  File \"/usr/lib/python2.6/site-packages/pandevice/device.py\", line 19, in <module>\n    from base import PanObject, Root, MEMBER, ENTRY\n  File \"/usr/lib/python2.6/site-packages/pandevice/base.py\", line 1224\n    option_paths = {opt: re.sub(r\"\\([\\w\\d|-]*\\)\", opt, path) for opt in options}\n                                                               ^\nSyntaxError: invalid syntax\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}

7. おわりに

多少クセがあるようなので、いろいろ検証してみた方がよさそうです。