DEV Community

Cover image for ANSIBLE - AUTOMAÇÃO DE BACKUPS
Thamayron
Thamayron

Posted on

11 1

ANSIBLE - AUTOMAÇÃO DE BACKUPS

Sobre Ansible

O Ansible é uma ferramenta de automação sem agente que gerencia hosts por meio de módulos através do protocolo SSH (por padrão). Uma vez instalado, o Ansible pode gerenciar remotamente, uma grande quantidade de máquinas, a partir de um servidor, ou seja, após instalar o Ansible, o servidor irá utilizar SSH para se comunicar com os hosts definidos em sua configuração.

Ansible pode ser instalado e executado em qualquer máquina com Sistema Operacional baseado em UNIX (Red Hat, Debian, CentOS, macOS e qualquer um dos BSDs), não sendo possível utilizá-lo em Windows. É necessária a utilização do Python (Python 2 (versão 2.7) ou Python 3 (versão 3.5 e superior)).

Sobre o projeto

Neste post iremos utilizar o Ansible para rotinas de Backup de ativos de rede (Network Automation), podemos utilizá-lo em uma rede com equipamentos de diversas marcas e modelos.

Neste cenário utilizaremos:
Host Ansible:
Máquina Windows, com WSL (Windows Subsystem for Linux), utilizando "Ubuntu 20.04.1 LTS"

Ubuntu

Hosts para backup:
Switch CISCO L3 (Layer 3 - Camada 3)
Switch HUAWEI L2 (Layer 2 - camada 2)
Roteador MIKROTIK
Roteador HUAWEI

Topologia Utilizada

Topologia

Instalando Ansible

Para instalar o Ansible no Ubuntu, iremos atualizar o sistema.

$ sudo apt update
Enter fullscreen mode Exit fullscreen mode

Instalar Python e Ansible

$ sudo apt install python3 python3-pip python-utils ansible -y
Enter fullscreen mode Exit fullscreen mode

Também podemos instalar através do gerenciador de pacotes do Python, o pip (como iremos trabalhar com o Python3, instalaremos e utilizaremos pip3)

$ sudo apt install python3 python3-pip python-utils  -y
$ pip3 install ansible
Enter fullscreen mode Exit fullscreen mode

Obs.: durante o processo de criação e testes, tivemos um problema com a versão do Ansible.
No ambiente Ubuntu após o início dos testes, utilizamos a versão "ansible 2.9.6" e após a conclusão, tudo funcionou corretamente.
Posteriormente em novos testes em novas máquinas Ubuntu e CentOS, após a instalação do Ansible, a versão instalada foi a "ansible 2.9.18", e o mesmo código não estava funcionando, após diversas pesquisas, encontramos um problema de versão após o "ansible 2.9.7" para huawei (ce_config) e juniper (junos_facts e junos_config), para corrigir este problema, realizamos o downgrade da versão do ansible.

Checando versão do python, pip e ansible

$ python -V ou python --version
$ python3 -V ou python3 --version
$ ansible --version
Enter fullscreen mode Exit fullscreen mode

Caso precise saber qual python ou ansible está utilizando

$ which python
$ which python3
$ which ansible
Enter fullscreen mode Exit fullscreen mode

Downgrade do ansible

$ pip install ansible==[version]
$ pip3 install ansible==[version]
Enter fullscreen mode Exit fullscreen mode

Exemplo:

$ pip install ansible==2.9.6
$ pip3 install ansible==2.9.6
Enter fullscreen mode Exit fullscreen mode

Após a instalação e checagem das versões, iremos então para a utilização do Ansible em Network Automation, em rotinas de Backup.

Para este projeto utilizamos apenas dois arquivos: hosts (arquivo de inventário que contém os hosts e suas variáveis) e main.yml (playbook utilizado para realizar as tarefas).

Criando local de trabalho

Iniciando, criamos um diretório no home para o Ansible e dentro do diretório os arquivos:

Criaremos um diretório para trabalhar com o Ansible.

$ mkdir ansible
Enter fullscreen mode Exit fullscreen mode

Entraremos no diretório criado.

$ cd ansible
Enter fullscreen mode Exit fullscreen mode

Para checagem em qual diretório estamos.

$ pwd 
Enter fullscreen mode Exit fullscreen mode

Criando o arquivo hosts e o main.yml

$ touch hosts main.yml
Enter fullscreen mode Exit fullscreen mode

Listamos os arquivos dentro do diretório atual

$ ls
Enter fullscreen mode Exit fullscreen mode

Arquivo - hosts do Ansible

Primeiro iremos tratar o arquivo hosts, neste arquivo iremos declarar os hosts que serão realizados os backups de forma automática.

O arquivo hosts possui o formato INI ou YAML, neste projeto iremos utilizar o formato INI.

Dentro do arquivo hosts iremos trabalhar com grupos, identificados através de colchetes “[]” e com variáveis que irão diferenciar características de cada grupo (caso necessário).

[all:vars] - criamos um grupo de "variáveis globais" que serão aplicadas em todos os hosts que não possuírem variáveis definidas exclusivamente.
Este grupo não é obrigatório, as variáveis podem ficar “soltas” no topo do arquivo, mas preferimos utilizar este formato para organizar o arquivo.

As variáveis utilizadas neste grupo são:

[all:vars]
ansible_user=USER_HERE // Usuário
ansible_password=USER_PASSWORD_HERE // Senha
ansible_become=yes // Permite receber privilégios de "enable"
ansible_become_password=USER_ROOT_PASSWORD_HERE // senha de "enable"
ansible_become_method=enable // para informar ao sistema operacional o privilégio de “enable”, para checagem de opções de become: “ansible-doc -t become -l”
ansible_port=22 // Porta de conexão SSH aos hosts
ansible_connection=network_cli // Plugin para acesso SSH aos hosts
gather_facts=false // Coletar fatos sobre o host remoto 
Enter fullscreen mode Exit fullscreen mode

Os demais grupos foram criados para cada vendor/marca de equipamentos, os nomes foram escolhidos para melhor identificação e agrupamento de hosts: [hosts_cisco], [hosts_huawei],[hosts_mikrotik].

Podemos declarar os nomes dos hosts de três formas distintas, como mostradas abaixo, em nosso arquivo iremos utilizar a forma 1:

1- HOSTNAME ansible_host=HOST_IP_ADDRESS

[hosts_cisco]
SW_CISCO_01 ansible_host=10.0.0.1
[hosts_mikrotik]
RT_MIKROTIK_01 ansible_host=10.0.0.4
Enter fullscreen mode Exit fullscreen mode

2- HOST_IP_ADDRESS

[hosts_huawei]
10.0.0.2 // SW_HUAWEI_01
Enter fullscreen mode Exit fullscreen mode

3- HOSTNAME (esta opção precisamos declarar o IP e HOSTNAME no arquivo /etc/hosts)

Editando arquivo /etc/hosts (escolha seu editor vi/vim/nano/pico)

$ sudo vim /etc/hosts
Enter fullscreen mode Exit fullscreen mode

Inserindo os dados dentro do arquivo /etc/hosts

# ANSIBLE HOSTS
# IP_ADDRESS     HOSTNAME
10.0.0.3         RT_HUAWEI_01
Enter fullscreen mode Exit fullscreen mode

Editando o arquivo hosts Ansible (escolha seu editor vi/vim/nano/pico)

$ vim hosts
Enter fullscreen mode Exit fullscreen mode
[hosts_huawei]
10.0.0.2 // SW_HUAWEI_01
RT_HUAWEI_01
Enter fullscreen mode Exit fullscreen mode

Após informados os endereços IPs e/ou Hostnames iremos configurar as variáveis locais para cada tipo de host (caso necessário).

Neste caso utilizamos apenas a "variável local" ansible_network_os, que será utilizada para informar ao Ansible o SO (Sistema Operacional) do host, pois são equipamentos de marcas diferentes, neste caso utilizamos hosts Huawei, Cisco e Mikrotik.

HUAWEI => ansible_network_os=ce
CISCO => ansible_network_os=ios
MIKROTIK => ansible_network_os=routeros

Caso possuam usuários, senhas e portas de acesso diferentes para cada equipamento, será necessário inserir as linhas de ansible_user, ansible_password, ansible_become_password e ansible_port em cada grupo, para que possam utilizar as credenciais corretas.

Exemplo do arquivo hosts finalizado:

[all:vars]
ansible_user=admin
ansible_password=Password123
ansible_become_password=RootPassword123
ansible_port=22
ansible_connection=network_cli
ansible_become=yes
ansible_become_method=enable
gather_facts=false

[hosts_cisco]
SW_CISCO_01 ansible_host= 10.0.0.1

[hosts_cisco:vars]
ansible_network_os=ios

[hosts_huawei]
SW_HUAWEI_01 ansible_host= 10.0.0.2
RT_HUAWEI_01 ansible_host= 10.0.0.3

[hosts_huawei:vars]
ansible_network_os=ce

[hosts_mikrotik]
RT_MIKROTIK_01 ansible_host= 10.0.0.4

[hosts_mikrotik:vars]
ansible_network_os=routeros
Enter fullscreen mode Exit fullscreen mode

PLAY BOOK

O arquivo playbook do Ansible é um arquivo YAML, este tipo de arquivo é iniciado por “---" e precisa de indentação (dois espaços para cada nível) para sua configuração, assim como precisa da extensão .yml no final do nome do arquivo.

Por padrão definimos um nome (name) para o grupo de atividades que queremos realizar, em seguida definimos os hosts (hosts) que farão parte daquele grupo de atividades, informamos para o Ansible que não queremos que ele colete fatos (gather_facts) sobre o host remoto e ignore_errors definimos para que caso haja algum erro o Ansible siga para a próxima tarefa, entre outras possíveis variáveis que podem ser inseridas nesta seção, em seguida iremos realizar as tarefas (tasks).

Tarefas (tasks):
Nesta seção onde serão executados os módulos e enviados comandos para os hosts remotos afim de realizar diversos tipos de ações, em nosso caso, iremos utilizar os módulos de rede para cada equipamento (ios_config para cisco, ce_config para huawei, routeros_command para mikrotik), realizaremos os backups dos hosts e salvaremos no diretório escolhido, renomeando da forma que acharmos melhor.

Com o módulo de rede, seja ele ios_config ou ce_config podemos utilizar a função de backup (backup), sem que precisemos utilizar comandos da cli do vendor, para isso utilizamos esta função e suas opções (backup_options), neste caso apenas dir_path.

OBSERVAÇÕES IMPORTANTES SOBRE MIKROTIK
  • O Mikrotik não possui um módulo Ansible de Redes para realização dos backups, como nos outros vendors, então iremos realizar os backups executando os comandos necessários no roteador via CLI e enviando para nosso servidor, via FTP.
  • Os comandos (commands) executados no Mikrotik são próprios da CLI do vendor.
  • As variáveis vars (ftp_server_var, ftp_user_var e ftp_pass_var) possuem os dados de autenticação do servidor FTP, a variável date será utilizada para renomear o arquivo salvo e a variável caminho_arquivo corresponde ao caminho para o arquivo desejado.
  • Serão realizados dois backups, o arquivo.backup e arquivo.src

O diretório é definido através da opção dir_path, sendo este o local onde ficará salvo o arquivo no servidor e caso o diretório desejado não exista, o mesmo será criado.

O nome do arquivo por padrão tem o formato:
HOSTNAME_config.YYYY-MM-DD@HH:MM:SS

Para renomearmos os arquivos de backup, utilizamos as variáveis especiais do Ansible:
inventory_hostname - coleta o hostname do host
ansible_host - coleta o hostname e endereço IP do host

PLAY BOOK - main.yml

---
- name: Rotina de backup de hosts Cisco
  hosts: hosts_cisco
  gather_facts: no
  ignore_errors: yes

  tasks:
    - name: Backup host config - Cisco
      ios_config:
        backup: yes
        backup_options:
          dir_path: "/home/ansible/{{ inventory_hostname }}"

- name: Rotina de backup de hosts Huawei
  hosts: hosts_huawei
  gather_facts: no
  ignore_errors: yes

  tasks:
    - name: Backup host config - Huawei
      ce_config:
        backup: yes
        backup_options:
          dir_path: "/home/ansible/{{ ansible_host }}"

- name: Rotina de Backup de hosts Mikrotik
  hosts: hosts_mikrotik
  gather_facts: no
  ignore_errors: yes

  vars:
    ftp_server_var: "ftpipaddress"
    ftp_user_var: "ftpuser"
    ftp_pass_var: "ftppassword"
    date: "{{ lookup('pipe', 'date +%Y-%m-%d@%H:%M:%S') }}"
    caminho_arquivo: /home/ansible/{{ inventory_hostname }}
  tasks:
     - name: Create a directory if it does not exist
       ansible.builtin.file:
         path: "{{ caminho_arquivo }}"
         state: directory
         mode: '0755'

     - name: Backup host config (file.backup) - Mikrotik
       routeros_command:
         commands:
           - /system backup save name "{{ inventory_hostname }}"
           - /tool fetch address={{ ftp_server_var }} src-path={{ inventory_hostname }}.backup user={{ ftp_user_var }} password={{ ftp_pass_var }} upload=yes port=21 mode=ftp dst-path={{ caminho_arquivo }}/{{ inventory_hostname }}_config.{{ date }}.backup
           - :delay 5
           - /file remove "{{ inventory_hostname }}.backup"

     - name: Backup host config (file.src) - Mikrotik
       routeros_command:
         commands:
           - /export file={{ inventory_hostname }}
           - /tool fetch address={{ ftp_server_var }} src-path={{ inventory_hostname }}.rsc user={{ ftp_user_var }} password={{ ftp_pass_var }} upload=yes port=21 mode=ftp dst-path={{ caminho_arquivo }}/{{ inventory_hostname }}_config.{{ date }}.rsc
           - :delay 5
           - /file remove "{{ inventory_hostname }}.rsc"

Enter fullscreen mode Exit fullscreen mode

Executando Ansible

Neste tópico iremos executar o Ansible para que realize a rotina de backup dos hosts cadastrados.
O comando ansible-playbook irá utilizar arquivo hosts como inventário e utilizará o arquivo main.yml como playbook.

$ ansible-playbook -i hosts main.yml
Enter fullscreen mode Exit fullscreen mode

Caso precisemos fazer troubleshooting ao executar o comando acima, podemos utilizar -vvv, para que sejam mostrados mais informações de saída.

$ ansible-playbook -i hosts main.yml -vvv
Enter fullscreen mode Exit fullscreen mode

Saída do Ansible

-> ansible-playbook -i hosts main.yml

PLAY [Rotina de backup de hosts Cisco] *********************************************************************************
TASK [Backup host config - Cisco] **************************************************************************************
changed: [SW_CISCO_01]

PLAY [Rotina de backup de hosts Huawei] ********************************************************************************
TASK [Backup host config - Huawei] *************************************************************************************
changed: [SW_HUAWEI_01]
changed: [RT_HUAWEI_01]

PLAY [Rotina de Backup de hosts Mikrotik] ******************************************************************************
TASK [Create a directory if it does not exist] *************************************************************************
changed: [RT_MIKROTIK_01]

TASK [Backup host config (file.backup) - Mikrotik] *********************************************************************
ok: [RT_MIKROTIK_01]

TASK [Backup host config (file.src) - Mikrotik] ************************************************************************
ok: [RT_MIKROTIK_01]

PLAY RECAP *************************************************************************************************************
SW_CISCO_01              : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
SW_HUAWEI_01             : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
RT_HUAWEI_01             : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
RT_MIKROTIK_01           : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Enter fullscreen mode Exit fullscreen mode

Agendamento dos Backups

Neste tópico agendaremos a execução do Ansible via Cron, para que a rotina de backup, seja realizada toda sexta-feira as 23:59.
Para abrir editar, utilizamos o comando:

$ crontab -e
Enter fullscreen mode Exit fullscreen mode

Dentro do arquivo, inserimos as informações abaixo:

# AGENDAMENTO CRON MANUAL - 23:59 TODA SEXTA FEIRA (5)
59 23 * * 5 /bin/ansible-playbook -i /home/ansible/hosts /home/ansible/main.yml > /home/ansible/log_ansible.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Para listarmos os agendamentos que existem no nosso sistema.

$ crontab -l
Enter fullscreen mode Exit fullscreen mode

Referências

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (1)

Collapse
 
trevisolli profile image
Gustavo Trevisolli

Foda demais, salvou minha vida hoje! Nem foi sobre gerar o backup, mas fazer um scan das redes dos mikrotiks e salvar num ftp. Parabéns pelo artigo!

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay