
1. Definindo os passos
Primeiramente vamos definir o que será feito. Precisamos saber os passos que serão executados, que no exemplo inicial será:
1. Baixar o pacote do repositório oficial do zabbix
2. Instalar o pacote do repositório (dpkg/rpm)
3. Instalar o pacote via repositório (apt/yum)
4. Substituir o arquivo de configuração (zabbix_agentd.conf)
5. Incluir o serviço na inicialização do sistema e inicia-lo.
2. Instalando o Ansible
A instalação do ansible é muito simples, podendo ser feita através do repositório da distribuição. Com exceção do CentOS, onde é necessário instalar antes o repositório EPEL.
No CentOS, execute os passos:
# yum install epel-relese; yum install ansible |
No Debian, execute os passos:
# apt-get install ansible |
Mais informações sobre instalação do Ansible podem ser obtidas em: http://docs.ansible.com/ansible/intro_installation.html
3. Criando a estrutura do Ansible
Após instalado o Ansible precisamos criar a estrutura do mesmo no diretório corrente, seguindo o modelo abaixo:
# tree
.
├── handlers
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
│ └── zabbix_agentd.conf.j2
└── vars
└── main.yml |
Criamos inicialmente os diretórios:
No CentOS e Debian, execute os passos:
# mkdir {handlers,tasks,templates,vars} |
Em seguida precisamos criar o YAML com todas ou ao menos as principais tarefas que serão executadas em etapas pelo ansible. Basicamente ele tem as instruções que vamos passar, como “instalar pacote X”, “iniciar serviço X”, etc.
Falaremos mais no decorrer deste post para que fique mais claro o entendimento. Mas caso tenha interesse em obter a fonte direta sobre, mais informações podem ser obtidas em: http://docs.ansible.com/ansible/playbooks.html
No CentOS e Debian, execute os passos:
# vim tasks/main.yml --- - name: Configurar e instalar agente zabbix hosts: all handlers: - include: "../handlers/main.yml" tasks: - name: Adiciona variaveis include_vars: "../vars/main.yml" - name: Instalar repositorio CentOS get_url: url: http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch.rpm dest: /tmp/zabbix-release-3.0-1.el7.noarch.rpm mode: 0777 - name: Instalar repositorio Debian get_url: url: http://repo.zabbix.com/zabbix/3.0/debian/pool/main/z/zabbix-release/zabbix-release_3.0-1+jessie_all.deb dest: /tmp/zabbix-release_3.0-1+jessie_all.deb mode: 0777 - name: Executando zabbix.rpm yum: name=/tmp/zabbix-release-3.0-1.el7.noarch.rpm state=present when: ansible_distribution == "CentOS" - name: Executando zabbix.deb apt: deb=/tmp/zabbix-release_3.0-1+jessie_all.deb when: ansible_distribution == "Debian" - name: Instalar agente zabbix CentOS yum: name=zabbix-agent state=latest when: ansible_distribution == "CentOS" - name: Instalar agente zabbix apt: name=zabbix-agent state=latest when: ansible_os_family == "Debian" - name: Preparar arquivo de configuração template: src=../templates/zabbix_agentd.conf.j2 dest=/etc/zabbix/zabbix_agentd.conf owner=root group=root mode=0644 notify: - Iniciar agente zabbix :x! |
Criado o arquivo de tarefas, precisamos criar o arquivo de Manipulação, Handlers dentro do contexto do ansible significa a operação de serviços. Basicamente Handlers são como tarefas, a única diferença, é que geralmente eles são executados após uma notificação de uma ou mais tarefas.
No CentOS e Debian, execute os passos:
# vim handlers/main.yml --- - name: Iniciar agente zabbix service: name=zabbix-agent state=started enabled=yes :x! |
Feito o arquivo de manipulação (handlers), precisamos criar o arquivo que conterá as variáveis (no nosso exemplo, usaremos apenas uma), são onde podemos modifica-las e tornar nosso playbook dinâmico e de fácil manipulação.
No CentOS e Debian, execute os passos:
# vim vars/main.yml zserver: zabbix.dominio.com.br :x! |
E por fim criamos o arquivo modelo de configuração, onde pode notar que estamos usando dentro do mesmo a variável que definimos e outra variável com nome de ansible_hostname, que é uma variável interna do próprio ansible com intuito de identificar dinamicamente o hostname da máquina que esta sendo executado.
Mais informações sobre variáveis do ansible podem ser encontradas em: http://docs.ansible.com/ansible/playbooks_variables.html
No CentOS e Debian, execute os passos:
# vim templates/zabbix_agentd.conf.j2 PidFile=/var/run/zabbix/zabbix_agentd.pid LogFile=/var/log/zabbix/zabbix_agentd.log LogFileSize=0 Server={{ zserver }} ServerActive={{ zserver }} Hostname={{ ansible_hostname }} Include=/etc/zabbix/zabbix_agentd.d/ :x! |
4. Entendendo o Ansible
Entendemos que o Ansible segmento sua estrutura, mas precisamos entender o que esse amontoado de arquivos estão fazendo. Vamos lá, primeiramente vamos analisar o cabeçalho do arquivo de tarefas.
Onde a função name representa o nome da tarefa, a função hosts em qual grupo de hosts este playbook será executado, no exemplo deixei como all (todos), a função handlers basicamente indica o arquivo onde será herdado os manipuladores usados pelo playbook caso seja feita alguma notificação solicitando uma operação.
--- - name: Configurar e instalar agente zabbix hosts: all handlers: - include: "../handlers/main.yml" A função tasks contém todos os passos que serão executados pelo nosso playbook, toda a receitinha de bolo. Em seguida temos a função include_vars, indicando o arquivo que contém as variáveis que serão usadas pelo ansible. |
tasks:
- name: Adiciona variaveis
include_vars: "../vars/main.yml" |
Neste trecho estamos usando a função get_url onde podemos fazer download de arquivos, determinar o local onde será salvo e a permissão do arquivo. Seria similar ao executar no terminal o comando “wget http://site.com/arquivo”. Estamos usando nessa situação o módulo get_url para download de arquivos, mais informações sobre esse módulo podem ser obtidas na documentação oficial: http://docs.ansible.com/ansible/get_url_module.html
- name: Instalar repositorio CentOS get_url: url: http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch.rpm dest: /tmp/zabbix-release-3.0-1.el7.noarch.rpm mode: 0777 - name: Instalar repositorio Debian get_url: url: http://repo.zabbix.com/zabbix/3.0/debian/pool/main/z/zabbix-release/zabbix-release_3.0-1+jessie_all.deb dest: /tmp/zabbix-release_3.0-1+jessie_all.deb mode: 0777 |
Neste trecho é onde damos a instrução ao ansible para instalar o pacote que baixamos anteriormente, e essa ação será executada de acordo com a condição da distribuição Linux utilizada. Seria similar ao executar manualmente no terminal "dpkg -i pacote.deb" ou "rpm -ivh pacote.rpm". Estamos usando o módulo apt e o módulo yum, que podem ser vistos de forma mais clara na documentação oficial: http://docs.ansible.com/ansible/apt_module.html e http://docs.ansible.com/ansible/yum_module.html
- name: Executando zabbix.rpm yum: name=/tmp/zabbix-release-3.0-1.el7.noarch.rpm state=present when: ansible_distribution == "CentOS" - name: Executando zabbix.deb apt: deb=/tmp/zabbix-release_3.0-1+jessie_all.deb when: ansible_distribution == "Debian" |
Este trecho corresponde a instalação dos pacotes via repositório, que seria o equivalente ao executar manualmente “apt-get install pacote” ou “yum install pacote”. Estamos usando o módulo apt e o módulo yum, que podem ser vistos de forma mais clara na documentação oficial: http://docs.ansible.com/ansible/apt_module.html e http://docs.ansible.com/ansible/yum_module.html
- name: Instalar agente zabbix CentOS yum: name=zabbix-agent state=latest when: ansible_distribution == "CentOS" - name: Instalar agente zabbix apt: name=zabbix-agent state=latest when: ansible_os_family == "Debian" |
E por fim, usamos a função template, onde indicamos o arquivo de configuração usando as variáveis que determinamos, e o destino onde esse modelo será copiado. O arquivo final já é inserido com os seus valores definidos. E por último é possível ver a função notify, que tem o intuito de notificar o handler (manipulador), onde faremos o start do serviço, que seria o equivalente a executar no terminal “systemctl start servico” ou “service servico start”.
- name: Preparar arquivo de configuração template: src=../templates/zabbix_agentd.conf.j2 dest=/etc/zabbix/zabbix_agentd.conf owner=root group=root mode=0644 notify: - Iniciar agente zabbix |
5. Testando o Ansible: Provisionamento local
Feito os procedimentos anteriores, podemos testar o Ansible e valida-lo. Vamos executar este procedimento localmente, ou seja, na máquina corrente.
Por tanto, abra o seu terminal e dentro do diretório corrente do módulo criado, execute o comando a seguir, fique atento com relação a saída, devendo ser semelhante a saída abaixo:
No CentOS e Debian, execute os passos:
# ansible-playbook -i "localhost," -c local tasks/main.yml PLAY [Configurar e instalar agente zabbix] ************************************ GATHERING FACTS *************************************************************** ok: [localhost] TASK: [Adiciona variaveis] **************************************************** ok: [localhost] TASK: [Instalar repositorio CentOS] ******************************************* ok: [localhost] TASK: [Instalar repositorio Debian] ******************************************* ok: [localhost] TASK: [Executando zabbix.rpm] ************************************************* skipping: [localhost] TASK: [Executando zabbix.deb] ************************************************* changed: [localhost] TASK: [Instalar agente zabbix CentOS] ***************************************** skipping: [localhost] TASK: [Instalar agente zabbix] ************************************************ changed: [localhost] TASK: [Preparar arquivo de configuração] ************************************** changed: [localhost] NOTIFIED: [Iniciar agente zabbix] ********************************************* ok: [localhost] PLAY RECAP ******************************************************************** localhost : ok=8 changed=3 unreachable=0 failed=0 |
E como podemos validar se funcionou corretamente? Simples:
No CentOS execute os passos:
# rpm -qa| grep zabbix zabbix-release-3.0-1.el7.noarch zabbix-agent-3.0.4-1.el7.x86_64 # systemctl status zabbix-agent ● zabbix-agent.service - Zabbix Agent Loaded: loaded (/usr/lib/systemd/system/zabbix-agent.service; enabled; vendor preset: disabled) Active: active (running) since Qua 2016-09-21 19:29:37 UTC; 29min ago (...) # cat /etc/zabbix/zabbix_agentd.conf (...) Server=zabbix.dominio.com.br ServerActive=zabbix.dominio.com.br Hostname=ansible01 (...) |
No Debian execute os passos:
# dpkg -l| grep zabbix ii zabbix-agent 1:3.0.4-1+jessie amd64 Zabbix network monitoring solution - agent ii zabbix-release 3.0-1+jessie all Zabbix official repository configuration # systemctl status zabbix-agent ● zabbix-agent.service - Zabbix Agent Loaded: loaded (/lib/systemd/system/zabbix-agent.service; enabled) Active: active (running) since Wed 2016-09-21 19:56:30 GMT; 3min 53s ago (...) # cat /etc/zabbix/zabbix_agentd.conf (...) Server=zabbix.dominio.com.br ServerActive=zabbix.dominio.com.br Hostname=ansible02 (...) |
6. Testando o Ansible: Provisionamento remoto
Anteriormente foi realizado o provisionamento do agente zabbix através do ansible em uma máquina local. Mas se quisermos provisionar este mesmo ambiente em diversos servidores remotamente via SSH? Lembre-se que o ansible não tem agente ou cliente, o único pré-requisito a existência do SSH na máquina de destino a ser executado.
Vamos-lá! Primeiro precisamos editar o arquivo hosts do Ansible, onde determinamos os nossos grupos de hosts. Edite o arquivo /etc/ansible/hosts, e inclua no final da linha os endereços e o nome do seu grupo de hosts, como no meu exemplo abaixo:
No CentOS e Debian, execute os passos:
# vim /etc/ansible/hosts [minhasmaquinas] 192.168.150.10 192.168.150.11 :x! |
Criado o nosso grupo de hosts, primeiramente devemos incluir a nossa chave pública do ssh nas máquinas remotas seguindo os passos a seguir. Primeiramente geramos a chave e em seguida incluímos as mesmas dentro dos servidores.
Gerando a chave pública e privada do SSH com o comando abaixo. Aperte enter em todas opções, deixando a chave sem passphrase:
No CentOS e Debian, execute os passos:
# ssh-keygen |
Gerada a chave é preciso adicionar a chave pública nas máquinas remotas da seguinte forma, e fornece a senha correta de root:
No CentOS e Debian, execute os passos:
# ssh-copy-id root@192.168.150.11 # ssh-copy-id root@192.168.150.10 |
Podemos validar se a comunicação entre nossa máquina e os servidores remotos estão perfeitas executando o comando abaixo. A saída deve ser parecida com essa:
No CentOS e Debian, execute os passos:
# ansible minhasmaquinas -m ping 192.168.150.11 | success >> { "changed": false, "ping": "pong" } 192.168.150.10 | success >> { "changed": false, "ping": "pong" } |
E finalmente podemos testar o uso do nosso módulo nas máquinas remotas, onde ele deverá instalar o agente zabbix e configura-lo corretamente. Execute o comando abaixo e confira a saída:
No CentOS e Debian, execute os passos:
# ansible-playbook -l minhasmaquinas tasks/main.yml PLAY [Configurar e instalar agente zabbix] ************************************ GATHERING FACTS *************************************************************** ok: [192.168.150.10] ok: [192.168.150.11] TASK: [Adiciona variaveis] **************************************************** ok: [192.168.150.10] ok: [192.168.150.11] TASK: [Instalar repositorio CentOS] ******************************************* ok: [192.168.150.11] ok: [192.168.150.10] TASK: [Instalar repositorio Debian] ******************************************* ok: [192.168.150.11] ok: [192.168.150.10] TASK: [Executando zabbix.rpm] ************************************************* skipping: [192.168.150.11] changed: [192.168.150.10] TASK: [Executando zabbix.deb] ************************************************* skipping: [192.168.150.10] changed: [192.168.150.11] TASK: [Instalar agente zabbix CentOS] ***************************************** skipping: [192.168.150.11] changed: [192.168.150.10] TASK: [Instalar agente zabbix] ************************************************ skipping: [192.168.150.10] changed: [192.168.150.11] TASK: [Preparar arquivo de configuração] ************************************** changed: [192.168.150.11] changed: [192.168.150.10] NOTIFIED: [Iniciar agente zabbix] ********************************************* ok: [192.168.150.11] changed: [192.168.150.10] PLAY RECAP ******************************************************************** 192.168.150.10 : ok=8 changed=4 unreachable=0 failed=0 192.168.150.11 : ok=8 changed=3 unreachable=0 failed=0 |
7. Conhecendo outros módulos do Ansible
O Ansible possui uma variedade enorme de módulos que já vem nativos e também disponibiliza módulos extras que podem se obtidos e ter mais informações através de sua documentação oficial: http://docs.ansible.com/ansible/modules_by_category.html
Neste exemplo vamos instalar o MySQL e criar uma base de dados chamada “mydatabase”. No caso, no Debian iremos instalar o MySQL e no CentOS o MariaDB, que é o fork versão open do MySQL. Importante se atentar também aos pré-requisitos de cada módulo ou função usada pelo ansible, por exemplo, para o uso do MySQl precisamos instalar a biblioteca MySQLdb do python para que o ansible possa se conectar ao SGBD.
Todos os módulos oficiais disponíveis do ansible estão em sua documentação oficial, assim como esta do MySQL: http://docs.ansible.com/ansible/mysql_db_module.html
Então vamos editar novamente o nosso playbook e vamos adicionar o seguinte:
No CentOS e Debian, execute os passos:
# vim tasks/main.yml (...) - name: Instalar MySQLdb CentOS yum: name=MySQL-python state=latest when: ansible_distribution == "CentOS" - name: Instalar MySQLdb Debian apt: name=python-mysqldb state=latest when: ansible_os_family == "Debian" - name: Instalar MariaDB yum: name=mariadb-server state=latest when: ansible_distribution == "CentOS" notify: - Iniciar mariadb CentOS - name: Instalar MySQL apt: name=mysql-server state=latest when: ansible_os_family == "Debian" notify: - Iniciar mysql Debian (...) :x! |
Em seguida vamos editar o handlers indicando o start do serviço MySQL nos sistemas e também acionar ele para criar a base de dados:
No CentOS e Debian, execute os passos:
# vim handlers/main.yml (...) - name: Iniciar mariadb CentOS service: name=mariadb state=started enabled=yes notify: - Criar base de dados - name: Iniciar mysql Debian service: name=mysql state=started enabled=yes notify: - Criar base de dados - name: Criar base de dados mysql_db: name=mydatabase state=present (...) :x! |
Após a edição, precisamos executar o playbook para validar as tarefas que incluímos.
No CentOS e Debian, execute os passos:
# ansible-playbook -l minhasmaquinas tasks/main.yml PLAY [Configurar e instalar agente zabbix] ************************************ GATHERING FACTS *************************************************************** ok: [192.168.150.10] ok: [192.168.150.11] TASK: [Adiciona variaveis] **************************************************** ok: [192.168.150.10] ok: [192.168.150.11] TASK: [Instalar repositorio CentOS] ******************************************* ok: [192.168.150.11] ok: [192.168.150.10] TASK: [Instalar repositorio Debian] ******************************************* ok: [192.168.150.11] ok: [192.168.150.10] TASK: [Executando zabbix.rpm] ************************************************* skipping: [192.168.150.11] changed: [192.168.150.10] TASK: [Executando zabbix.deb] ************************************************* skipping: [192.168.150.10] changed: [192.168.150.11] TASK: [Instalar agente zabbix CentOS] ***************************************** skipping: [192.168.150.11] changed: [192.168.150.10] TASK: [Instalar agente zabbix] ************************************************ skipping: [192.168.150.10] changed: [192.168.150.11] TASK: [Instalar MySQLdb CentOS] *********************************************** skipping: [192.168.150.11] ok: [192.168.150.10] TASK: [Instalar MySQLdb Debian] *********************************************** skipping: [192.168.150.10] ok: [192.168.150.11] TASK: [Instalar MariaDB] ****************************************************** skipping: [192.168.150.11] changed: [192.168.150.10] TASK: [Instalar MySQL] ******************************************************** skipping: [192.168.150.10] changed: [192.168.150.11] TASK: [Preparar arquivo de configuração] ************************************** changed: [192.168.150.11] changed: [192.168.150.10] NOTIFIED: [Iniciar agente zabbix] ********************************************* ok: [192.168.150.11] changed: [192.168.150.10] NOTIFIED: [Iniciar mariadb CentOS] ******************************************** changed: [192.168.150.10] NOTIFIED: [Iniciar mysql Debian] ********************************************** ok: [192.168.150.11] NOTIFIED: [Criar base de dados] *********************************************** changed: [192.168.150.10] PLAY RECAP ******************************************************************** 192.168.150.10 : ok=12 changed=7 unreachable=0 failed=0 192.168.150.11 : ok=11 changed=4 unreachable=0 failed=0 |
E por fim, podemos conferir se a base de dados foi criada com sucesso.
No CentOS e Debian, execute os passos:
# mysql (...) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mydatabase | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) MariaDB [(none)]> |
8. Conclusão
Como podemos ver o Ansible é uma ótima solução de provisionamento de ambientes, bastante dinâmica e eficiente. Existe alguns contras, claro, como a exigente sintaxe e indentação do seu playbook. No entanto sua lógica é bastante simples. Além de possuir vantagens em relação a sua expansão, já que a própria documentação fornece ideais e sugestões para você desenvolver seus próprios módulos para serem usados em seus playbooks. Enfim, fico por aqui, e espero que essa dica seja útil para todos aqueles empenhados em aplicar essa solução em seu dia a dia.