Tóm tắt: Junos trong Ansible đi qua NETCONF (ansible.netcommon.netconf, port 830). Config dạng set/text/XML → junipernetworks.junos.junos_config (lines hoặc src + src_format). Config có cấu trúc → resource module như junipernetworks.junos.junos_interfaces. Quy trình an toàn: --check --diff → chạy thật với confirm: 5 → kiểm tra → task confirm_commit: true. Bản IOS XR tương ứng: Đẩy cấu hình IOS XR bằng Ansible.
Luồng hoạt động
flowchart LR A["playbook"] --> B["--check --diff"] B -->|"load, commit check, rollback 0"| C{"Diff đúng?"} C -->|Không| A C -->|Có| D["chạy thật, confirm: 5"] D -->|"commit confirmed 5"| E[("Junos")] E --> F{"Verify OK?"} F -->|Có| G["confirm_commit: true"] F -->|Không| H["không làm gì, tự rollback sau 5 phút"]
Cấu hình
Chuẩn bị
set system services netconf sshpython3 -m pip install ncclient jxmlease
ansible-galaxy collection install junipernetworks.junos ansible.netcommonansible_network_os: junipernetworks.junos.junos
ansible_connection: ansible.netcommon.netconf
ansible_port: 830
ansible_user: "{{ lookup('env', 'NET_USER') }}"
ansible_password: "{{ lookup('env', 'NET_PASS') }}"junos_command (lệnh show) chạy được cả với network_cli, nhưng junos_config và các resource module cần netconf. Một nhóm host nên dùng chung netconf cho đơn giản.
junos_config với lệnh set
- name: Đổi description và MTU
hosts: junos
gather_facts: false
tasks:
- name: Load lệnh set, commit confirmed 5 phút
junipernetworks.junos.junos_config:
lines:
- set interfaces ge-0/0/1 description to-pe2-hcm
- set interfaces ge-0/0/1 mtu 9192
comment: "CHG-1234 uplink description"
confirm: 5
backup: true
backup_options:
dir_path: backup/
filename: "{{ inventory_hostname }}.conf"
register: result
- name: Kiểm tra interface sau commit
junipernetworks.junos.junos_command:
commands: show interfaces ge-0/0/1 terse
register: verify
- name: Xác nhận commit (hủy hẹn giờ rollback)
junipernetworks.junos.junos_config:
confirm_commit: true
when: verify.stdout[0] is search('ge-0/0/1\s+up\s+up')Tham số hay dùng của junos_config:
| Tham số | Ý nghĩa |
|---|---|
lines |
Danh sách lệnh set/delete (ngầm định format set) |
src + src_format |
File/template config; src_format: set, text, xml, json (không đặt thì module tự đoán) |
update |
Cách load: merge (mặc định), override, replace, update; tương đương load merge/override/replace/update |
confirm |
Số phút cho commit confirmed; 0 = commit bình thường |
confirm_commit |
true = chỉ gửi commit để xác nhận commit confirmed trước đó |
check_commit |
Chỉ commit check rồi bỏ thay đổi, không commit |
comment |
Comment của commit, xem bằng show system commit |
rollback |
Số rollback (0-49): load rollback N rồi commit |
backup + backup_options |
Lưu config hiện tại về máy chạy Ansible trước khi đổi |
junos_config từ template
set protocols bgp group {{ bgp_group }} type external
set protocols bgp group {{ bgp_group }} neighbor {{ peer_ip }} peer-as {{ peer_asn }}
set protocols bgp group {{ bgp_group }} neighbor {{ peer_ip }} description "{{ peer_desc }}"
set protocols bgp group {{ bgp_group }} neighbor {{ peer_ip }} import {{ policy_in }}
set protocols bgp group {{ bgp_group }} neighbor {{ peer_ip }} export {{ policy_out }}- name: Thêm BGP peer từ template set
junipernetworks.junos.junos_config:
src: templates/bgp_peer.set.j2
src_format: set
comment: "CHG-1235 peer {{ peer_ip }}"
confirm: 5update: override (hoặc src_format: text kèm update: override) thay toàn bộ cấu hình bằng nội dung file. File thiếu system/interfaces fxp0 là mất đường quản lý. Chỉ dùng khi template sinh đủ toàn bộ config, và luôn kèm confirm.
Template viết kiểu text (ngoặc nhọn) cũng được, đặt src_format: text. Cú pháp vòng lặp/điều kiện xem Jinja2 cho template cấu hình mạng.
Resource module
- name: Interface theo kiểu khai báo
hosts: junos
gather_facts: false
tasks:
- name: Description + MTU
junipernetworks.junos.junos_interfaces:
config:
- name: ge-0/0/1
description: to-pe2-hcm
mtu: 9192
enabled: true
state: merged
- name: IPv4 trên unit 0
junipernetworks.junos.junos_l3_interfaces:
config:
- name: ge-0/0/1
unit: 0
ipv4:
- address: 192.0.2.1/31
state: merged| Loại cấu hình | Module |
|---|---|
| Interface vật lý | junos_interfaces |
| IP trên unit | junos_l3_interfaces |
| LAG / LACP | junos_lag_interfaces, junos_lacp, junos_lacp_interfaces |
| BGP | junos_bgp_global, junos_bgp_address_family |
| OSPF | junos_ospfv2, junos_ospf_interfaces |
| Static route | junos_static_routes |
| Prefix-list, policy | junos_prefix_lists, junos_policy_options |
| Firewall filter | junos_acls, junos_acl_interfaces |
state có cùng ý nghĩa như bên IOS XR (merged, replaced, overridden, deleted, gathered, rendered, parsed). state: rendered sinh XML/lệnh offline, tiện để review trong merge request.
Chạy
# 1. Check mode + diff trên 1 host: load, commit check, rồi bỏ thay đổi
ansible-playbook -i inventory push_set.yml --check --diff -l mx1-hni
# 2. Chạy thật, ít host một lúc
ansible-playbook -i inventory push_set.yml --diff -f 5
# 3. Kiểm tra trên thiết bị
# show system commit
# show configuration | compare rollback 1Muốn quay lại bản trước bằng Ansible: task junipernetworks.junos.junos_config với rollback: 1 (load rollback 1 rồi commit). Trên CLI xem Junos CLI cheatsheet.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
ncclient is required / jxmlease is required |
Thiếu thư viện Python trên máy chạy Ansible (đúng interpreter) | pip install ncclient jxmlease vào cùng venv với ansible |
unable to connect to NETCONF / timeout port 830 |
Chưa bật netconf ssh hoặc filter lo0 chặn 830 |
set system services netconf ssh, mở 830 trong filter bảo vệ RE |
configuration database locked |
Có người đang configure exclusive hoặc session cũ treo |
show system users, request system logout session <id> |
| Commit tự rollback sau vài phút | Dùng confirm: N nhưng không có task confirm_commit (hoặc task đó bị skip) |
Thêm task xác nhận; kiểm tra điều kiện when |
syntax error khi load |
Sai src_format (file set nhưng để text) |
Đặt rõ src_format: set |
--check báo changed |
Đúng hành vi: check mode vẫn load để tính diff, sau đó rollback 0 | Đọc phần diff, không coi changed là đã commit |
| Không thấy diff | Thiếu --diff khi chạy |
Thêm --diff, hoặc register rồi xem key diff |
Lỗi persistent connection, timeout chung xem Ansible network troubleshooting.