てくなべ (tekunabe)

ansible / network / automation

[Ansible] 「つまずき Ansible 【Part6】Juniper Junos に何かしてみる」ふりかえり

はじめに

2020/06/20 に、YouTube Live で「[つまずき Ansible 【Part6】Juniper Junos に何かしてみる(https://www.youtube.com/watch?v=jJedVzaGDRU)」という配信をしました。 実際に作業しながらエラーと戦って進めるシリーズです。

tekunabe.connpass.com

今回は、Juniper Junos の機器への接続確認、show コマンド実行、インターフェース設定する Playbook を作りました。

環境は vLabs を利用しました。

つまずいたエラーと原因、対処をふりかえります。

動画

www.youtube.com


■ 疎通確認

ncclient が見つからないエラーが発生

以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible -i inventory.ini junos -m junos_facts
[WARNING]: Platform linux on host vsrx1 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.
vsrx1 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "msg": "Failed to import the required Python library (ncclient) on stumble's Python /home/vagrant/envs/ansible/bin/python3. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter: No module named 'ncclient'"
}

原因

NETCONF 接続に必要な ncclient がインストールされていないため。

対処

以下のコマンドで nccliant をインストール。

$ pip install ncclient


■ インターフェースの description 設定スタティックルートの追加

lxml が見つからないエラーが発生

以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml 

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
[WARNING]: Platform linux on host vsrx1 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.
fatal: [vsrx1]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "lxml is not installed."}

PLAY RECAP **********************************************************************************************************
vsrx1                      : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

原因

Ansible をインストールした venv には lxml は入っているが、Playbook 実行に利用する Python 環境(今回の場合、デフォルト /usr/bin/python)には入っていなかった。

対処

PlyaPython インタープリタの指定を追加。

---
- hosts: junos
  gather_facts: false

  vars:    
    ansible_python_interpreter: ~/envs/ansible/bin/python    # 追加

network_cli が使えないエラーが発生

junos_interfaces モジュールnetwork の組み合わせで、以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "msg": "Connection type 'network_cli' is not valid for 'junos_interfaces' module. Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"}

PLAY RECAP **********************************************************************************************************
vsrx1                      : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

原因

junos_interafaces モジュールは network_cli には対応しておらず、netconf のみ対応しているため。

参考: https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html:

対処

netconf を利用する。

もし、タスク個別にコネクションプラグインを指定する場合は、以下のようにタスク変数で指定する。

    - name: set int
      junos_interfaces:
        config:
          - name: ge-0/0/0
            description: funa
      vars:
        ansible_connection: netconf     # ここ
        ansible_port: 33001             # ここ

Configuration database is not open というエラーが発生

※ 配信時は放置しして終わりましたが、配信終了後に対処しました

以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "module_stderr": "", "module_stdout": "\n{\"msg\": \"b'\\\\nconfiguration database modified\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n\n{\"msg\": \"b'\\\\nConfiguration database is not open\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP **********************************************************************************************************

原因

手作業で設定変更を試みた時に、未コミットの変更を残してしまったため。

[edit]
ansible@vSRX-addr-0# show | compare 
[edit interfaces ge-0/0/0]
-   description funa;
+   description funa2;

[edit]
ansible@vSRX-addr-0# exit 
The configuration has been changed but not committed
Exit with uncommitted changes? [yes,no] (yes) 

Exiting configuration mode

ansible@vSRX-addr-0>    # 未コミットの変更が残っている。

Ansible としては、安全のために設定変更を控えた。

(配信時はコンフィグ不整合を起こしたといってしまいましたが、正しくは不整合を起こさないために安全側に倒したものです)

対処

手作業で設定変更を試みたた未コミットの変更を破棄。

ansible@vSRX-addr-0> configure 
Entering configuration mode
The configuration has been changed but not committed

[edit]
ansible@vSRX-addr-0# 

[edit]
ansible@vSRX-addr-0# rollback 
load complete

[edit]
ansible@vSRX-addr-0# exit 
Exiting configuration mode

ansible@vSRX-addr-0> 


おまけ

閲覧したサイト

作った各種ファイル

インベントリ: inventory.ini

[ios]
rt01 ansible_host=192.168.1.11
rt02 ansible_host=192.168.1.12

[eos]
eos1 ansible_host=192.168.1.133

; 以下追加
[junos]
vsrx1 ansible_port=33001

変数定義ファイル: group_vars/junos.yml




Playbook: juos_show.yml

show version の実行と表示。

---
- hosts: junos
  gather_facts: false
  
  tasks:
    - name: show version
      junos_command:
        commands:
          - show version
      register: resgister_show_version
  
    - name: debug
      debug:
        msg: "{{ resgister_show_version.stdout_lines }}"

Playbook: juos_set.yml

インターフェースの description 設定。

---
- hosts: junos
  gather_facts: false

  vars:
    ansible_python_interpreter: ~/envs/ansible/bin/python   # 追加
  
  tasks:
    - name: set int
      junos_interfaces:
        config:
          - name: ge-0/0/0
            description: kingyo

全実行ログ

クリックして開く(長いです)

(ansible) [vagrant@stumble stumble]$ ansible -i inventory.ini junos -m junos_facts
[WARNING]: Platform linux on host vsrx1 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.
vsrx1 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "msg": "Failed to import the required Python library (ncclient) on stumble's Python /home/vagrant/envs/ansible/bin/python3. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter: No module named 'ncclient'"
}
(ansible) [vagrant@stumble stumble]$ pip install ncclient
Collecting ncclient
  Downloading https://files.pythonhosted.org/packages/dd/7f/700ffea36c4c1c72d7581ef3dc3f40ec9756fd161816cd258cd303cd9f39/ncclient-0.6.7.tar.gz (605kB)
    100% |████████████████████████████████| 614kB 214kB/s 
Requirement already satisfied: setuptools>0.6 in /home/vagrant/envs/ansible/lib/python3.6/site-packages (from ncclient)
Requirement already satisfied: paramiko>=1.15.0 in /home/vagrant/envs/ansible/lib/python3.6/site-packages (from ncclient)
Collecting lxml>=3.3.0 (from ncclient)
(ansible) [vagrant@stumble stumble]$ ansible -i inventory.ini junos -m junos_facts
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
[WARNING]: Platform linux on host vsrx1 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.
vsrx1 | SUCCESS => {
    "ansible_facts": {
        "ansible_net_api": "netconf",
        "ansible_net_filesystems": [
            "/dev/gpt/junos",
            "tmpfs",
            "tmpfs",
            "host_corefiles",
            "host_volatile",
            "host_log",
            "host_traffic_log",
            "host_local",
            "host_aamwd",
            "host_geoip",
            "host_secinteld",
            "host_app_disk"
        ],
        "ansible_net_gather_network_resources": [],
        "ansible_net_gather_subset": [
            "hardware",
            "default",
            "interfaces"
        ],
        "ansible_net_has_2RE": false,
        "ansible_net_hostname": "vSRX-addr-0",
        "ansible_net_interfaces": {
            ".local.": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Loopback"
            },
            "dsc": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Software-Pseudo"
            },
            "em0": {
                "admin-status": "up",
                "macaddress": "02:00:00:00:00:04",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "1000mbps",
                "type": "Ethernet"
            },
            "em1": {
                "admin-status": "up",
                "macaddress": "52:54:00:21:26:49",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "1000mbps",
                "type": "Ethernet"
            },
            "em2": {
                "admin-status": "up",
                "macaddress": "52:54:00:d9:7c:01",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "Unspecified",
                "type": "Ethernet"
            },
            "fti0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "FTI"
            },
            "fxp0": {
                "admin-status": "up",
                "macaddress": "00:50:56:01:0c:00",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "1000mbps",
                "type": "Ethernet"
            },
            "ge-0/0/0": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:d8:85",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/1": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:c6:23",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/2": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:f9:11",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/3": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:6f:db",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/4": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:04:91",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/5": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:d0:57",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/6": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:41:9d",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/7": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:da:ed",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "gr-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "GRE"
            },
            "gre": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "GRE"
            },
            "ip-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "IPIP"
            },
            "ipip": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "IPIP"
            },
            "irb": {
                "admin-status": "up",
                "macaddress": "4c:96:14:c4:b1:70",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Ethernet"
            },
            "lo0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Loopback"
            },
            "lsi": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Software-Pseudo"
            },
            "lsq-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "1504",
                "oper-status": "up",
                "speed": null,
                "type": null
            },
            "lt-0/0/0": {
                "admin-status": "up",
                "macaddress": "02:96:14:c4:b1:73",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "Logical-tunnel"
            },
            "mt-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "Multicast-GRE"
            },
            "mtun": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Multicast-GRE"
            },
            "pimd": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "PIMD"
            },
            "pime": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "PIME"
            },
            "pp0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "1532",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "PPPoE"
            },
            "ppd0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "PIMD"
            },
            "ppe0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "PIME"
            },
            "sp-0/0/0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "9192",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "Adaptive-Services"
            },
            "st0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "9192",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Secure-Tunnel"
            },
            "tap": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Software-Pseudo"
            },
            "vlan": {
                "admin-status": "up",
                "macaddress": "00:00:00:00:00:00",
                "mtu": "1518",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": "VLAN"
            },
            "vtep": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Software-Pseudo"
            }
        },
        "ansible_net_memfree_mb": 27784,
        "ansible_net_memtotal_mb": 955320,
        "ansible_net_model": "vsrx",
        "ansible_net_modules": [
            {
                "description": "VSRX",
                "name": "Midplane",
                "part_number": "750-058562",
                "serial_number": "42227D10",
                "version": "REV 08"
            },
            {
                "name": "Pseudo CB 0"
            },
            {
                "description": "VSRX-S",
                "name": "Routing Engine 0",
                "part_number": "BUILTIN",
                "serial_number": "BUILTIN"
            },
            {
                "chassis_sub_module": null,
                "description": "FPC",
                "name": "FPC 0",
                "part_number": "611-049549",
                "serial_number": "RL3714040884",
                "version": "REV 07"
            }
        ],
        "ansible_net_python_version": "2.7.5",
        "ansible_net_routing_engines": {
            "null": {
                "cpu_background": "0",
                "cpu_background1": "0",
                "cpu_background2": "0",
                "cpu_background3": "0",
                "cpu_idle": "84",
                "cpu_idle1": "95",
                "cpu_idle2": "98",
                "cpu_idle3": "98",
                "cpu_interrupt": "2",
                "cpu_interrupt1": "0",
                "cpu_interrupt2": "0",
                "cpu_interrupt3": "0",
                "cpu_system": "14",
                "cpu_system1": "4",
                "cpu_system2": "1",
                "cpu_system3": "1",
                "cpu_temperature": "0 degrees C / 32 degrees F",
                "cpu_user": "1",
                "cpu_user1": "1",
                "cpu_user2": "1",
                "cpu_user3": "1",
                "last_reboot_reason": "0x4000:VJUNOS reboot",
                "load_average_fifteen": "0.47",
                "load_average_five": "0.57",
                "load_average_one": "0.74",
                "memory_buffer_utilization": "82",
                "memory_system_total": "933",
                "memory_system_total_used": "774",
                "memory_system_total_util": "83",
                "model": "VSRX-S",
                "serial_number": "BUILTIN",
                "slot": null,
                "start_time": "2020-06-20 09:54:25 UTC",
                "status": "OK",
                "temperature": "0 degrees C / 32 degrees F",
                "up_time": "1 hour, 15 minutes, 11 seconds"
            }
        },
        "ansible_net_serialnum": "XXX",
        "ansible_net_system": "junos",
        "ansible_net_version": "18.3R1.9",
        "ansible_network_resources": {},
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_show.yml 

PLAY [junos] *********************************************************************************

TASK [show version] **************************************************************************
[WARNING]: Platform linux on host vsrx1 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.
ok: [vsrx1]

TASK [debug] *********************************************************************************
ok: [vsrx1] => {
    "msg": [
        [
            "Hostname: vSRX-addr-0",
            "Model: vsrx",
            "Junos: 18.3R1.9",
            "JUNOS OS Kernel 64-bit  [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS libs [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS runtime [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS time zone information [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS libs compat32 [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS 32-bit compatibility [20180816.8630ec5_builder_stable_11]",
            "JUNOS py extensions [20180920.185504_builder_junos_183_r1]",
            "JUNOS py base [20180920.185504_builder_junos_183_r1]",
            "JUNOS OS vmguest [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS crypto [20180816.8630ec5_builder_stable_11]",
            "JUNOS network stack and utilities [20180920.185504_builder_junos_183_r1]",
            "JUNOS libs [20180920.185504_builder_junos_183_r1]",
            "JUNOS libs compat32 [20180920.185504_builder_junos_183_r1]",
            "JUNOS runtime [20180920.185504_builder_junos_183_r1]",
            "JUNOS Web Management Platform Package [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx libs compat32 [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx runtime [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx platform support [20180920.185504_builder_junos_183_r1]",
            "JUNOS common platform support [20180920.185504_builder_junos_183_r1]",
            "JUNOS srxtvp runtime [20180920.185504_builder_junos_183_r1]",
            "JUNOS pppoe [20180920.185504_builder_junos_183_r1]",
            "JUNOS mtx network modules [20180920.185504_builder_junos_183_r1]",
            "JUNOS modules [20180920.185504_builder_junos_183_r1]",
            "JUNOS srxtvp modules [20180920.185504_builder_junos_183_r1]",
            "JUNOS srxtvp libs [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx libs [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx Data Plane Crypto Support [20180920.185504_builder_junos_183_r1]",
            "JUNOS daemons [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx daemons [20180920.185504_builder_junos_183_r1]",
            "JUNOS SRX TVP AppQos Daemon [20180920.185504_builder_junos_183_r1]",
            "JUNOS High End AppQos Daemon [20180920.185504_builder_junos_183_r1]",
            "JUNOS Extension Toolkit [20180920.185504_builder_junos_183_r1]",
            "JUNOS Phone-home [20180920.185504_builder_junos_183_r1]",
            "JUNOS J-Insight [20180920.185504_builder_junos_183_r1]",
            "JUNOS Online Documentation [20180920.185504_builder_junos_183_r1]",
            "JUNOS jail runtime [20180816.8630ec5_builder_stable_11]",
            "JUNOS FIPS mode utilities [20180920.185504_builder_junos_183_r1]"
        ]
    ]
}

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

(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ ansible-doc junos_interfaces
> JUNOS_INTERFACES    (/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/modules/network/junos/junos_i

        This module manages the interfaces on Juniper Junos OS network devices.

  * This module is maintained by The Ansible Network Team
OPTIONS (= is mandatory):

- config
        The provided configuration
        [Default: (null)]
        suboptions:
          description:
            description:
            - Interface description.
            type: str
          duplex:
            choices:
            - automatic
            - full-duplex
            - half-duplex
            description:
            - Interface link status. Applicable for Ethernet interfaces only, either in half
              duplex, full duplex or in automatic state which negotiates the duplex automatically.
            type: str
          enabled:
            default: true
            description:
            - Administrative state of the interface.
            - Set the value to `true' to administratively enabled the interface or `false'
              to disable it.
            type: bool
          hold_time:
            description:
            - The hold time for given interface name.
            suboptions:
              down:
                description:
                - The link down hold time in milliseconds.
                type: int
              up:
                description:
                - The link up hold time in milliseconds.
                type: int
            type: dict
          mtu:
            description:
            - MTU for a specific interface.
            - Applicable for Ethernet interfaces only.
            type: int
          name:
            description:
            - Full name of interface, e.g. ge-0/0/0.
            required: true
            type: str
          speed:
            description:
            - Interface link speed. Applicable for Ethernet interfaces only.
            type: int
        
        type: list

- state
        The state of the configuration after module completion
        (Choices: merged, replaced, overridden, deleted)[Default: merged]
        type: str


NOTES:
      * This module requires the netconf system service be enabled on the remote device
        being managed.
      * Tested against vSRX JUNOS version 18.4R1.
      * This module works with connection `netconf'. See L(the Junos OS Platform
        Options,../network/user_guide/platform_junos.html).


REQUIREMENTS:  ncclient (>=v0.6.4)

AUTHOR: Ganesh Nalawade (@ganeshrn)
        METADATA:
          status:
          - preview
          supported_by: network
        

EXAMPLES:

# Using deleted

# Before state:
# -------------
# user@junos01# show interfaces
# ge-0/0/1 {
#    description "Configured by Ansible-1";
#    speed 1g;
#    mtu 1800
# }
# ge-0/0/2 {
#    description "Configured by Ansible-2";
#    ether-options {
#        auto-negotiation;
#    }
# }

- name: "Delete given options for the interface (Note: This won't delete the interface itself if any other values are
  junos_interfaces:
    config:
      - name: ge-0/0/1
        description: 'Configured by Ansible-1'
        speed: 1g
        mtu: 1800
      - name: ge-0/0/2
        description: 'Configured by Ansible -2'
    state: deleted

# After state:
# ------------
# user@junos01# show interfaces
# ge-0/0/2 {
#    ether-options {
#        auto-negotiation;
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml 

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
[WARNING]: Platform linux on host vsrx1 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.
fatal: [vsrx1]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "lxml is not installed."}

PLAY RECAP **********************************************************************************************************
vsrx1                      : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

(ansible) [vagrant@stumble stumble]$ pip install lxml
Requirement already satisfied: lxml in /home/vagrant/envs/ansible/lib/python3.6/site-packages
You are using pip version 9.0.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ python 
Python 3.6.8 (default, Apr  2 2020, 13:34:55) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import lxml
>>> 
>>> 
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>> 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ python python
python: can't open file 'python': [Errno 2] No such file or directory
(ansible) [vagrant@stumble stumble]$ which python
~/envs/ansible/bin/python
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml 

PLAY [junos] *****************************************************************************************************

TASK [set int] ***************************************************************************************************
changed: [vsrx1]

PLAY RECAP *******************************************************************************************************
vsrx1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --check --diff

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
[edit interfaces ge-0/0/0]
-   description kingyo;
+   description funa;
changed: [vsrx1]

PLAY RECAP **********************************************************************************************************
vsrx1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
[edit interfaces ge-0/0/0]
-   description kingyo;
+   description funa;
changed: [vsrx1]

PLAY RECAP **********************************************************************************************************
vsrx1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "msg": "Connection type 'network_cli' is not valid for 'junos_interfaces' module. Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"}

PLAY RECAP **********************************************************************************************************
vsrx1                      : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff
^CTraceback (most recent call last):
  File "/home/vagrant/envs/ansible/bin/ansible-playbook", line 62, in <module>
    import ansible.constants as C
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/constants.py", line 174, in <module>
    config = ConfigManager()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/config/manager.py", line 279, in __init__
    self._base_defs = self._read_config_yaml_file(defs_file or ('%s/base.yml' % os.path.dirname(__file__)))
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/config/manager.py", line 305, in _read_config_yaml_file
    return yaml_load(config_def, Loader=SafeLoader) or {}
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/__init__.py", line 114, in load
    return loader.get_single_data()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/constructor.py", line 49, in get_single_data
    node = self.get_single_node()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 36, in get_single_node
    document = self.compose_document()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 55, in compose_document
    node = self.compose_node(None, None)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
    node = self.compose_mapping_node(anchor)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
    item_value = self.compose_node(node, item_key)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
    node = self.compose_mapping_node(anchor)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
    item_value = self.compose_node(node, item_key)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 82, in compose_node
    node = self.compose_sequence_node(anchor)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 110, in compose_sequence_node
    while not self.check_event(SequenceEndEvent):
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/parser.py", line 98, in check_event
    self.current_event = self.state()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/parser.py", line 379, in parse_block_sequence_first_entry
    return self.parse_block_sequence_entry()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/parser.py", line 382, in parse_block_sequence_entry
    if self.check_token(BlockEntryToken):
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/scanner.py", line 115, in check_token
    while self.need_more_tokens():
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/scanner.py", line 152, in need_more_tokens
    self.stale_possible_simple_keys()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/scanner.py", line 286, in stale_possible_simple_keys
    for level in list(self.possible_simple_keys):
KeyboardInterrupt
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

PLAY [junos] ********************************************************************************************************

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "module_stderr": "", "module_stdout": "\n{\"msg\": \"b'\\\\nconfiguration database modified\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n\n{\"msg\": \"b'\\\\nConfiguration database is not open\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP **********************************************************************************************************
vsrx1                      : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

(ansible) [vagrant@stumble stumble]$ 

Part7 にむけて

リリースされたばかりの Ansible 2.10.0b1 で遊びます。

https://tekunabe.connpass.com/event/180268/

参加ブログ

参加ブログありがとうございます!

note.com