📜 ⬆️ ⬇️

Cooking Juniper Network with Ansible



One day, I decided to switch from the usual rsyslog collecting logs from all devices to something else, the choice and so on to this topic a little (selected Graylog2), but the result was the task of replacing the host syslog settings on all Juniper devices.

In principle, running through the handles (or throwing a script on perl) over a hundred devices and clicking the command is not a problem, but there is a good bundle of tasks to automate the management of both network devices and a couple of hundred servers already in my head. If there are no problems with Windows in my environment (we use SCCM), then with the Linux environment, mass operations acquire either manual operations or bash scripts (you can control SCCM, but this option is inconvenient, to say the least).
')
And since I have long wanted to start using Ansible , it was chosen as the start for this task (for Chef and Puppet, however, the tasks are not so large, and the threshold of entry is already greater).

Ansible installation


Ansible installation is simple, since everything is out of the box (for this task we used the ubuntu server on 04/16/03):

sudo apt-add-repository ppa:ansible/ansible sudo apt-get update sudo apt-get install ansible 

Change the settings in /etc/ansible/ansible.cfg
 #     roles_path = /etc/ansible/roles #  ,   ,        SSH   . host_key_checking = False # log_path = /var/log/ansible.log      ,      . 


Juniper module


Juniper in the subject and great guys, they have developed a module. Information about it can be found on the off site: Ansible for JunOS . Starting with Ansible 2.1, it is natively enabled in core modules Ansible .

Install this module and check it in the list:

 sudo ansible-galaxy install Juniper.junos ansible-galaxy list 

Also, to use the module, we need nccclient

 sudo apt-get install python-pip pip install ncclient 

Connect to devices


Ansible can connect to Juniper devices in several ways, the default protocol is Netconf and port 830. It is also possible to use telnet and serial console connection, but telnet is relatively not secure, and serial is not very specific for specific tasks, although the initial setting of the “bare” hardware with a connection can be too thin to be automated with it.

Netconf can also be used in the usual 22 ssh port, and as a transport, simply use cli.

about netconf
What is Netconf not bad disclosed in one of the old publications on Habré .

For authorization on devices, I would like to immediately set up authorization by key. For convenience, we generate the RSA key for convenience (why the DSA will not be understood further). After we copy it to the previously created /etc/ansible/.ssh for ease of use.

 ssh-keygen -t rsa cp /root/.ssh/id_rsa.pub /etc/ansible/.ssh/ansible.pub cp /root/.ssh/id_rsa /etc/ansible/.ssh/ansible 

According to the results on target devices, it would be necessary to manually create a user with a public key:

 set system login user ansible class super-user authentication ssh-rsa "<SSH-key>" 

But we also automate it further.

Hosts


To whom we connect, we describe in the / etc / ansible / hosts file.
It is possible to describe device groups and variables in it, since I use different Juniper devices, so I will immediately create several groups:

/ etc / ansible / hosts
 [junex2200] 192.168.111.101 [junex3300] 192.168.111.51 [junexcore] 192.168.111.4 [junexdc] 192.168.111.11 [alljuniper:children] junex2200 junex3300 junexcore junexdc [alljuniper:vars] ansible_jun_username=ansible ansible_jun_port=22 ansible_jun_timeout=60 ansible_ssh_private_key_file=/etc/ansible/.ssh/ansible 


In this file, I identified 4 groups, added 1 device to each group. After that, I made a general group and added variables for authorization that will be used in the playbook. The user will be “ansible” , the port will use 22, since the 830 is not enabled by default, and we will increase the timeout to 60, as with the commit time it can easily be more than the standard 10 seconds.

if you want to enable netconf on juniper
set system services netconf ssh

Playbook initial setup


I made the initial setup in a separate playbook . Since I have a user to connect to all devices, I will use the login / password input in the playbook to create the user “ansible” with our key. Also, if you wish, you can enable Netconf on port 830, but I did not notice the difference, so I consider this superfluous.

Create the directory / etc / ansible / playbooks / juniper and in it our first playbook init.yml

We analyze the content:

 --- - name: juniper initialization playbook # PB hosts: alljuniper #  hosts    #  juniper roles: - Juniper.junos connection: local gather_facts: no #   /  ,   vars_prompt: - name: "DEVICE_USERNAME" promt: "Device username" private: no - name: "DEVICE_PASSWORD" promt: "Device password" private: yes #      vars: provider_info: host: "{{ inventory_hostname }}" username: "{{ DEVICE_USERNAME }}" password: "{{ DEVICE_PASSWORD }}" port: "{{ ansible_jun_port }}" timeout: "{{ ansible_jun_timeout }}" #    tasks: #    - name: junos check connection wait_for: host: "{{ inventory_hostname }}" port: "{{ ansible_jun_port }}" timeout: 10 #  - name: junos create ansible user with key-auth junos_user: provider: "{{ provider_info }}" name: "{{ ansible_jun_username }}" role: super-user sshkey: "{{lookup('file', '/etc/ansible/.ssh/ansible.pub') }}" state: present 

To create a user, we use the junos_user module. The module can create a user only with the rsa key and therefore we generated it. In principle, you can use junos_config and write straight our line indicating dsa key.

 set system login user ansible class super-user authentication ssh-dsa "<SSH-key>" 

Launch playbook


We start the playbook created by us init.yml:

 sudo ansible-playbook init.yml 

Execution result
 DEVICE_USERNAME: megaswitchuser DEVICE_PASSWORD: PLAY [juniper initialization playbook] ******************************************************************************** TASK [junos check connection] ******************************************************************************** ok: [192.168.111.101] ok: [192.168.111.51] ok: [192.168.111.4] ok: [192.168.111.11] TASK [junos create ansible user with key-auth] ******************************************************************************** changed: [192.168.111.101] changed: [192.168.111.51] changed: [192.168.111.4] changed: [192.168.111.11] PLAY RECAP ******************************************************************************** 192.168.111.101 : ok=2 changed=1 unreachable=0 failed=0 192.168.111.51 : ok=2 changed=1 unreachable=0 failed=0 192.168.111.4 : ok=2 changed=1 unreachable=0 failed=0 192.168.111.11 : ok=2 changed=1 unreachable=0 failed=0 


changed = 1
means about a successful change, you can go to any device and yes the user will already be created there.

When you restart the playbook, the changes will not be made again, and it will write
changed = 0

Syslog setup


We have a junos_logging module. In principle, in most cases you can use it, but I need to enter advanced parameters for the host, but they are not supported in this module. Therefore, we use the universal tool, the junos_config module to add a new host, and the junos_logging module to remove the old one.

We create a playbook syslog.yml, in it we will already use key authorization for our user ansible.

 --- - name: juniper set syslog to graylog2 # PB hosts: alljuniper #  hosts    #  juniper roles: - Juniper.junos connection: local gather_facts: no #     ,       hosts, keyfile     vars: provider_info: host: "{{ inventory_hostname }}" username: "{{ ansible_jun_username }}" port: "{{ ansible_jun_port }}" timeout: "{{ ansible_jun_timeout }}" #    tasks: #    - name: junos check connection wait_for: host: "{{ inventory_hostname }}" port: "{{ ansible_jun_port }}" timeout: "{{ ansible_jun_timeout }}" #  - name: set juniper syslog host junos_config: provider: "{{ provider_info }}" #     lines: - set system syslog host 192.168.111.210 any any - set system syslog host 192.168.111.210 port 2514 - set system syslog host 192.168.111.210 structured-data brief #    comment: update config add syslog graylog2 #      junos_logging - name: delete old syslog host junos_logging: provider: "{{ provider_info }}" dest: host name: 192.168.111.208 facility: any level: any state: absent 

Run:

 sudo ansible-playbook syslog.yml 

Execution result
 PLAY [juniper set syslog to graylog2] ******************************************************************************** TASK [junos check connection] ******************************************************************************** ok: [192.168.111.101] ok: [192.168.111.51] ok: [192.168.111.4] ok: [192.168.111.11] TASK [set juniper syslog host] ******************************************************************************** changed: [192.168.111.101] changed: [192.168.111.51] changed: [192.168.111.4] changed: [192.168.111.11] TASK [delete old syslog host] ******************************************************************************** changed: [192.168.111.101] changed: [192.168.111.51] changed: [192.168.111.4] changed: [192.168.111.11] PLAY RECAP ******************************************************************************** 192.168.111.4 : ok=3 changed=1 unreachable=0 failed=0 192.168.111.11 : ok=3 changed=1 unreachable=0 failed=0 192.168.111.51 : ok=3 changed=1 unreachable=0 failed=0 192.168.111.101 : ok=3 changed=1 unreachable=0 failed=0 



Going to any of the Junipers, it is obvious that our new syslog server was registered in the settings, and the old one was deleted.

Optionally, you can see the commit history with a comment from the playbook:

 show system commit 

 0 2018-03-07 15:12:49 KRAT by ansible via netconf update config add syslog graylog2 

Calling the playbook again will also not change the configuration, but will report that everything is “OK” and there are no changes.

Results


We set up the environment to automate the settings in our network, now you can easily manage our network. Tasks that can be solved using the Juniper module for Ansible are not limited to configuration changes, we can also update the software version, reboot devices, make backup configurations and much more.

Plans


I outlined the following plans for myself on this topic with Ansible for the near future.


The tool is really excellent and I only regret that I did not start using it earlier. Whether you have one machine with Linux or 100 different switches, it's never too late and it's not too early to start automating your actions.

Tested equipment list


Juniper: EX3300, EX2200, EX4550
JunOS: 12.2R6.4, 12.3R3.4, 12.3R4.6, 12.3R6.6, 12.3R6.6, 12.2R9.4, 12.2R12.4

PS: already in the process of writing the article I came across an article on the same topic on Habré, so I tried to more fully cover the topic.

Source: https://habr.com/ru/post/350636/


All Articles