はじめに
前回の記事で、Cisco IOS-XEのACL操作をRESTCONFで行いました。前回は操作ツールとしてPythonを使いましたが、今回はAnsibleのrestconf_get、restconf_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でアクセスするための情報を定義します。
[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名TESTとTEST2をそれぞれ1行ずつ設定しました。
その後、restconf_getモジュールを用い、GETメソッドで拡張ACL情報を取得しました。
---
- 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情報を取得しました。
---
- 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情報を取得しました。
---
- 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行ずつ読み込んで設定変更する等が考えられると思います。