В жизни каждой развивающейся сети наступает момент, когда необходимо задуматься о её восстанавливаемости после различных видов сбоев, будь то аппаратные неисправности в оборудовании или ошибки админа. В таком случае, очень полезно иметь под рукой резервную конфигурацию устройства для быстрого восстановления работоспособности сети. В данной статье, мы рассмотрим как можно с помощью GitLab и Ansible, развернуть сервер для сбора и хранения резервных конфигураций сетевого оборудования, производства Cisco Systems и Juniper Networks.

Исходя из сложившихся обстоятельств, развертывание системы сбора резервных конфигураций осуществлялось на сервере с OC Astra Linux SE 1.7. Что особо не влияет порядок действий, за исключением пары моментов о которых я расскажу ниже.

Первым нюансом стало то, что после установки пакета ansible, необходимые модули и коллекции для взаимодействия с оборудованием Cisco и Juniper не загрузились, как это происходит при скачивании с репозиториев Ubuntu. После анализа недостающих компонентов, я установил всё необходимое с помощью следующих команд:

pip3 install xmltodict
pip3 install jxmlease
pip3 install junos-eznc
pip install ncclient
ansible-galaxy collection install juniper.device
ansible-galaxy collection install -s https://old-galaxy.ansible.com cisco.ios
pip install --user --break-system-packages ansible-pylibssh paramiko

После установки ansible и всех необходимых зависимостей, содаём docker-compose.yml с контейнерами GitLab:

version: '3.5'
services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    hostname: 192.168.1.1
    restart: unless-stopped
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        gitlab_rails['gitlab_shell_ssh_port'] = 8822
    ports:
      - "80:80"
      - "8822:22"
    volumes:
      - ~/gitlab/etc:/etc/gitlab
      - ~/gitlab/var/opt:/var/opt/gitlab
      - ~/gitlab/var/log:/var/log/gitlab
    networks:
      - gitlab_net

  gitlab-runner:
    image: gitlab/gitlab-runner:alpine
    restart: unless-stopped
    depends_on:
      - gitlab
    volumes:
      - ~/gitlab/etc/gitlab-runner:/etc/gitlab-runner
      - ~/gitlab/var/run/docker.sock:/var/run/docker.sock
    networks:
      - gitlab_net

networks:
  gitlab_net:

Подгрузка нового контейнера осуществляется командой:

docker-compose up -d --build

Теперь, можно приступить к основному этапу настройки: - конфигурация ansible.

Для начала необходимо составить inventory-файл, иными словами список хостов, с которыми будет взаимодействовать Ansible. Файл ивентаризации можно создать как в корневом каталоге Ansible, так и в домашней директории, главное указать путь до созданного файла в /etc/ansible/ansible.cfg. В моем случае, файл инвентаризации располагается в каталоге playbooks: ~/playbooks/myhost.ini. Также, для удобства, все узлы сети целесообразно разбить на группы по типу оборудования, например, ios и junos.

Пример inventory-файла, ~/playbooks/myhost.ini:

[ios]
Cisco_3945 ansible_host=10.35.48.1 ansible_user=admin ansible_password=admin_password
Cisco_3750 ansible_host=10.35.48.2 ansible_user=admin ansible_password=admin_password

[junos]
Jun_mx5 ansible_host=10.35.49.1 ansible_user=admin ansible_password=admin_password
Jun_ex4200 ansible_host=10.35.49.2 ansible_user=admin ansible_password=admin_password

После этого создаем playbook для сбора резервных конфигураций с сетевых устройств:

ios_backup.yml

---
- name: "Collect IOS facts"
  hosts: ios
  gather_facts: no
  connection: network_cli
  become: yes
  become_method: enable
  tasks: # сбор конфигов на сервер-ansible
    - name: configs
      ios_command:
        commands: show running-config
      register: ios_config
    - name: Copy facts to files
      copy:
        content: "{{ ios_config.stdout[0] }}"
        dest: "/home/qwerty/playbooks/cisco/{{inventory_hostname}}_config.cfg" # путь куда конфиги сохраняются локально

- name: "GIT"
  hosts: localhost

  tasks:

    - name: "print time" # определение времени для gitlab
      command: date
      register: time
      changed_when: false
      delegate_to: localhost
      run_once: yes
    
    - name: "Configure Git user"
      git_config:
        name: "user.name"
        value: "qwerty"
        scope: "global"
  
    - name: "Configure Git email"
      git_config:
        name: "user.email"
        value: "qwerty@qwerty"
        scope: "global"

    - name: "git command" # отправка конфигов на сервер-gitlab
      shell: |
        git add .
        git commit -m "Device Backup on {{time.stdout}} " 
        git push --set-upstream origin main
      args:
        chdir: /home/qwerty/playbooks/cisco
      delegate_to: localhost
      run_once: yes   

junos_backup.yml

---
- name: "test"
  hosts: junos
  connection: local
  gather_facts: no
  collections: juniper.device


  tasks:
      - name: "test2" # сбор конфигов на сервер-ansible
        juniper.device.config:
          retrieve: "committed"
          dest: "/home/qwerty/playbooks/juniper/{{ inventory_hostname }}-system-config" # путь куда конфиги сохраняются локально

- name: "GIT"
  hosts: localhost

  tasks:
  
    - name: "print time" # определение времени для gitlab
      command: date
      register: time
      changed_when: false
      delegate_to: localhost
      run_once: yes

    - name: "git command" # отправка конфигов на сервер-gitlab
      shell: |
        git add .
        git commit -m "Device Backup on {{time.stdout}} " 
        git push --set-upstream origin main
      args:
        chdir: /home/qwerty/playbooks/juniper
      delegate_to: localhost
      run_once: yes

Затем создаем каталог group_vars, с файлами ios.yml и junos.yml

ios.yml

ansible_python_interpreter: /usr/bin/python3
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: cisco.ios.ios
ansible_become: yes
ansible_become_method: enable
ansible_become_password: admin_password
ansible_host_key_checking: false

junos.yml

ansible_python_interpreter: /usr/bin/python3
ansible_host_key_checking: false
ansible_network_os: junipernetworks.junos.junos
ansible_connection: ansible.netcommon.netconf
ansible_user: admin
ansible_password: admin_password

На этом, подготовительная часть закончена, можно приступать к настройке взаимодействия GitLab и Ansible. Переходим в gitlab http://<ip-сервера>, username: root, пароль находится на сервере в файле ~/gitlab/etc/initial_root_password. После этого необходимо изменить пароль и создать нового пользователя.

1) Кликаем на иконку пользователя -> Edit profile -> SSH Keys -> Add new key -> вставляем публичный ключ сервера Ansible.

2) Создаем группу backup и новый проект:

После этого копируем созданные репозитории Git на сервер Ansible.

Пример команд для Git репозитория Cisco:

git clone ssh://git@<ip-gitlab>:8822/backup/cisco.git
cd cisco
git config --local user.name "qwerty"
git config --local user.email "qwerty@mail.ru"
git switch --create main
touch README.md
git add README.md
git commit -m "add README"
git push --set-upstream origin main
cd ..

Теперь всё готово для запуска playbook:

ansible-playbook -i myhosts.ini ios_backup.yml

После успешного выполнения заходим в GitLab и проверяем backups устройств.

Комментарии (3)


  1. Grand_piano
    09.07.2025 17:32

    Я просто тихонечко оставлю это здесь - https://github.com/ytti/oxidized/blob/master/docs/Supported-OS-Types.md


  1. Grand_piano
    09.07.2025 17:32

    И ещё - переходите уже на 1.8, вздохните полной грудью, а не вот это вот всё..... Поверьте, сразу же почувствуете серьёзное облегчение в работе.


  1. NAI
    09.07.2025 17:32

    ansible_password=admin_password

    Да ну серьезно? Пароли от железок в текстовом файле... ансибл имеет свой vault шифрование, не можете в асибл, у гитлаба есть возможность использовать env'ы.

    show running-config

    Copy facts to files

    N-лет не работаю с циской, но разве ios разучилась делать copy running-... ftp:// Причем прям на железке же и расписание можно было настроить.

    Т.е. задача сводится к двум(трем) командам на bash, размещенными в крон, без всяких раннеров