Cisco IOS-XEのACLをRESTCONFで操作する(Ansible編)


はじめに

前回の記事で、Cisco IOS-XEのACL操作をRESTCONFで行いました。前回は操作ツールとしてPythonを使いましたが、今回はAnsibleのrestconf_getrestconf_configモジュールで簡単に試してみました。

AnsibleとRESTCONFの組み合わせは、公式ドキュメントに加え以下記事を参考にさせて頂きました。
[Ansible] restconf_get モジュールで Cisco IOS XE のインターフェース情報を取得してみる
[Ansible] restconf_config モジュールで Cisco IOS XE のSyslogサーバー設定追加・削除してみる

1. 用意した環境

Cisco DevNet SandboxのIOS XE on CSR Recommended CodeのCSR1000v 16.9.3を利用させて頂きました。
Ansibleは2.9.0を使用しました。

2. Inventoryファイル

CSR1000vへRESTCONFでアクセスするための情報を定義します。

inventory_restconf1.ini
[cisco]
csr1000v-1 ansible_host=[IPアドレス/ホスト名] ansible_user=[ユーザ名] ansible_password=[パスワード]

[cisco:vars]
ansible_connection=httpapi
ansible_network_os=restconf
ansible_httpapi_port=443
ansible_httpapi_use_ssl=yes
ansible_httpapi_validate_certs=no

3. ACLマージ・取得

まずACL設定が無い状態から、2つのACLを作成してみます。

3-1. Playbook

restconf_configモジュールを用い、PATCHメソッドでACL名TESTTEST2をそれぞれ1行ずつ設定しました。
その後、restconf_getモジュールを用い、GETメソッドで拡張ACL情報を取得しました。

playbook_restconf_create_acl3.yml
---

- hosts: cisco
  gather_facts: no

  tasks:
    - name: create new acl
      restconf_config:
        path: /data/Cisco-IOS-XE-native:native/ip
        method: patch
        content: "{{ content_data | to_json }}"
#        content: "{{ lookup('file', 'acl.json') }}"
      vars:
        content_data:
          Cisco-IOS-XE-native:ip:
            access-list:
              Cisco-IOS-XE-acl:extended:
                - access-list-seq-rule:
                  - ace-rule:
                      action: permit
                      dest-ipv4-address: 192.168.100.0
                      dest-mask: 0.0.0.255
                      ipv4-address: 192.168.4.0
                      mask: 0.0.0.255
                      protocol: ip
                    sequence: 30
                  name: TEST
                - access-list-seq-rule:
                  - ace-rule:
                      action: permit
                      dest-ipv4-address: 192.168.100.0
                      dest-mask: 0.0.0.255
                      ipv4-address: 192.168.7.0
                      mask: 0.0.0.255
                      protocol: ip
                    sequence: 70
                  name: TEST2

    - name: get acl info
      restconf_get:
        path: /data/Cisco-IOS-XE-native:native/ip/access-list/extended
      register: result

    - name: debug
      debug:
        msg: "{{ result }}"

3-2. 実行結果

想定通り2つのACLが作成されました。

$ ansible-playbook -i inventory_restconf1.ini playbook_restconf_create_acl3.yml

PLAY [cisco] **********************************************************************************************************

TASK [create new acl] *************************************************************************************************
changed: [csr1000v-1]

TASK [get acl info] ***************************************************************************************************
ok: [csr1000v-1]

TASK [debug] **********************************************************************************************************
ok: [csr1000v-1] => {
    "msg": {
        "changed": false,
        "failed": false,
        "response": {
            "Cisco-IOS-XE-acl:extended": [
                {
                    "access-list-seq-rule": [
                        {
                            "ace-rule": {
                                "action": "permit",
                                "dest-ipv4-address": "192.168.100.0",
                                "dest-mask": "0.0.0.255",
                                "ipv4-address": "192.168.4.0",
                                "mask": "0.0.0.255",
                                "protocol": "ip"
                            },
                            "sequence": "30"
                        }
                    ],
                    "name": "TEST"
                },
                {
                    "access-list-seq-rule": [
                        {
                            "ace-rule": {
                                "action": "permit",
                                "dest-ipv4-address": "192.168.100.0",
                                "dest-mask": "0.0.0.255",
                                "ipv4-address": "192.168.7.0",
                                "mask": "0.0.0.255",
                                "protocol": "ip"
                            },
                            "sequence": "70"
                        }
                    ],
                    "name": "TEST2"
                }
            ]
        }
    }
}

PLAY RECAP ************************************************************************************************************
csr1000v-1                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

4. ACL削除・取得

続いて、既存ACLの削除を行ってみます。

4-1. Playbook

restconf_configモジュールを用い、DELETEメソッドで先ほど作成したTEST2を削除しました。
その後、restconf_getモジュールを用い、GETメソッドで拡張ACL情報を取得しました。

playbook_restconf_delete_acl.yml
---

- hosts: cisco
  gather_facts: no

  tasks:
    - name: delete acl
      restconf_config:
        path: /data/Cisco-IOS-XE-native:native/ip/access-list/extended=TEST2
        method: delete

    - name: get acl info
      restconf_get:
        path: /data/Cisco-IOS-XE-native:native/ip/access-list/extended
      register: result

    - name: debug
      debug:
        msg: "{{ result }}"

4-2. 出力結果

TEST2が削除され、TESTだけになった事が分かります。

$ ansible-playbook -i inventory_restconf1.ini playbook_restconf_delete_acl.yml

PLAY [cisco] **********************************************************************************************************

TASK [delete acl] *****************************************************************************************************
changed: [csr1000v-1]

TASK [get acl info] ***************************************************************************************************
ok: [csr1000v-1]

TASK [debug] **********************************************************************************************************
ok: [csr1000v-1] => {
    "msg": {
        "changed": false,
        "failed": false,
        "response": {
            "Cisco-IOS-XE-acl:extended": [
                {
                    "access-list-seq-rule": [
                        {
                            "ace-rule": {
                                "action": "permit",
                                "dest-ipv4-address": "192.168.100.0",
                                "dest-mask": "0.0.0.255",
                                "ipv4-address": "192.168.4.0",
                                "mask": "0.0.0.255",
                                "protocol": "ip"
                            },
                            "sequence": "30"
                        }
                    ],
                    "name": "TEST"
                }
            ]
        }
    }
}

PLAY RECAP ************************************************************************************************************
csr1000v-1                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

5. ACLリプレイス・取得

最後に、既存設定を上書きし、別のACLを作成してみます。

5-1. Playbook

restconf_configモジュールを用い、PUTメソッドでACL名TEST3を1行設定しました。
その後、restconf_getモジュールを用い、GETメソッドで拡張ACL情報を取得しました。

playbook_restconf_create_acl.yml
---

- hosts: cisco
  gather_facts: no

  tasks:
    - name: create new acl
      restconf_config:
        path: /data/Cisco-IOS-XE-native:native/ip/access-list
        method: put
        content: "{{ content_data | to_json }}"
#        content: "{{ lookup('file', 'acl.json') }}"
      vars:
        content_data:
          Cisco-IOS-XE-native:access-list:
            Cisco-IOS-XE-acl:extended:
              - access-list-seq-rule:
                - ace-rule:
                    action: permit
                    dest-ipv4-address: 192.168.100.0
                    dest-mask: 0.0.0.255
                    ipv4-address: 192.168.9.0
                    mask: 0.0.0.255
                    protocol: ip
                  sequence: 30
                name: TEST3

    - name: get acl info
      restconf_get:
        path: /data/Cisco-IOS-XE-native:native/ip/access-list/extended
      register: result

    - name: debug
      debug:
        msg: "{{ result }}"

5-2. 出力結果

想定通り、TEST3のみ表示されました。

$ ansible-playbook -i inventory_restconf1.ini playbook_restconf_create_acl.yml

PLAY [cisco] **********************************************************************************************************

TASK [create new acl] *************************************************************************************************
changed: [csr1000v-1]

TASK [get acl info] ***************************************************************************************************
ok: [csr1000v-1]

TASK [debug] **********************************************************************************************************
ok: [csr1000v-1] => {
    "msg": {
        "changed": false,
        "failed": false,
        "response": {
            "Cisco-IOS-XE-acl:extended": [
                {
                    "access-list-seq-rule": [
                        {
                            "ace-rule": {
                                "action": "permit",
                                "dest-ipv4-address": "192.168.100.0",
                                "dest-mask": "0.0.0.255",
                                "ipv4-address": "192.168.9.0",
                                "mask": "0.0.0.255",
                                "protocol": "ip"
                            },
                            "sequence": "30"
                        }
                    ],
                    "name": "TEST3"
                }
            ]
        }
    }
}

PLAY RECAP ************************************************************************************************************
csr1000v-1                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

最後に

今回はPlaybookのサンプルのみになってしまいましたが、自動化の観点では、ACLマージ用PlaybookのCisco-IOS-XE-acl:extended:配下の変数をパラメーター表で定義し、loopで1行ずつ読み込んで設定変更する等が考えられると思います。