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"
Hosts para backup:
Switch CISCO L3 (Layer 3 - Camada 3)
Switch HUAWEI L2 (Layer 2 - camada 2)
Roteador MIKROTIK
Roteador HUAWEI
Topologia Utilizada
Instalando Ansible
Para instalar o Ansible no Ubuntu, iremos atualizar o sistema.
$ sudo apt update
Instalar Python e Ansible
$ sudo apt install python3 python3-pip python-utils ansible -y
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
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
Caso precise saber qual python ou ansible está utilizando
$ which python
$ which python3
$ which ansible
Downgrade do ansible
$ pip install ansible==[version]
$ pip3 install ansible==[version]
Exemplo:
$ pip install ansible==2.9.6
$ pip3 install ansible==2.9.6
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
Entraremos no diretório criado.
$ cd ansible
Para checagem em qual diretório estamos.
$ pwd
Criando o arquivo hosts e o main.yml
$ touch hosts main.yml
Listamos os arquivos dentro do diretório atual
$ ls
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
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
2- HOST_IP_ADDRESS
[hosts_huawei]
10.0.0.2 // SW_HUAWEI_01
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
Inserindo os dados dentro do arquivo /etc/hosts
# ANSIBLE HOSTS
# IP_ADDRESS HOSTNAME
10.0.0.3 RT_HUAWEI_01
Editando o arquivo hosts Ansible (escolha seu editor vi/vim/nano/pico)
$ vim hosts
[hosts_huawei]
10.0.0.2 // SW_HUAWEI_01
RT_HUAWEI_01
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
eansible_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
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
ouce_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
eftp_pass_var
) possuem os dados de autenticação do servidorFTP
, a variáveldate
será utilizada para renomear o arquivo salvo e a variávelcaminho_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"
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
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
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
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
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
Para listarmos os agendamentos que existem no nosso sistema.
$ crontab -l
Referências
-
Ansible
-
Inventório Ansible (HOSTS FILE)
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html
-
Variáveis Ansible
https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html
-
Instalar outra coleção do Ansible
-
Problema de versão do Ansible
-
Downgrade de versão do Ansible
https://www.unixarena.com/2019/06/downgrading-ansible-engine-on-centos-7-rhel-7.html/
-
SSH ignorar key checking
https://stackoverflow.com/questions/32297456/how-to-ignore-ansible-ssh-authenticity-checking
-
Plugin Network_cli
https://docs.ansible.com/ansible/latest/collections/ansible/netcommon/network_cli_connection.html
-
Gather Facts
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/gather_facts_module.html
-
YAML
-
CRON
https://www.digitalocean.com/community/tutorials/how-to-use-cron-to-automate-tasks-centos-8-pt
https://crontab.guru/every-week
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/cron_module.html
Top comments (1)
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!