Comecei a estudar a ferramenta de provisionamento, gerenciamento de configuração e deploy de aplicações do momento, o ansible e nesse artigo vou compartilhar as minhas anotações dos conceitos fundamentais dessa poderosa ferramenta.
Pegue o seu café, abra o seu terminal e let's do it!
Devemos pensar em ansible como automação, ele vem para otimizar por exemplo, o tempo gasto com a manutenção ou implantação de servidores (se você é um administrador de sistemas) ou seu tempo com os seus routers, switches etc. (se você é um engenheiro de redes).
Automatizar é o seu objetivo.
💡 Ansible = Automation
I, Robot - 20th Century Fox (2004)
O ansible é da RedHat, muito simples de operar e você não precisa saber programar para usá-lo (pode te ajudar se souber, mas não é um pré requisito).
Abaixo seguem alguns conceitos de ansible, que precisamos entendê-los antes de operar o Ansible para a automação de rede/infraestrutura.
CONCEITOS FUNDAMENTAIS
Control node
É de onde a mágica acontece, é apenas no control node que o ansible precisa ser instalado, pois como veremos mais adiante, o ansible é agentless, ou seja, ele opera sem a premissa de ter um client/agent instalado nos hosts que você quer atingir.
Managed nodes
Aqui ficam os dispositivos de rede ou servidores que gerenciamos com o ansible no control node. Também chamados de hosts, não precisam ter o ansible instalados neles.
Inventory
Onde listamos os nosso managed nodes que iremos gerenciar com o ansible, também conhecido como "hostfile" Toda a organização dos managed nodes é feita no inventory, que fica em /etc/ansible/hosts
Modules
Um módulo normalmente abstrai uma tarefa do sistema, como lidar com pacotes ou criar e alterar arquivos. O Ansible possui diversos módulos integrados, com um utilitário chamado
ansible-doc é possível consultar todos os módulos disponíveis numa instalação padrão do Ansible, mas você também pode criar módulos personalizados:
$ ansible-doc -l
- Tasks
São tarefas para executar nos hosts. Podemos executá-las com comandos ad-hoc diretamente na linha de comando sem o uso de Playbooks, mas os comandos Ad-Hoc executam apenas um
módulo por vez. E se quisermos criar uma sequência de tarefas com os módulos disponíveis? Aí que entram as playbooks.
- Playbooks
Listas ordenadas de tarefas, a playbook basicamente é composto por ‘play’ e ‘tasks’. Uma ‘play’ é análoga a uma jogada ensaiada de basquete. Define-se quais jogadores participarão (Hosts
alvo) e quais passos (tasks) serão executados. As playbook são escritas em YAML.
POR QUE USAR ANSIBLE?
Como vimos anteriormente, não há mais espaço para tarefas repetitivas hoje em dia, precisamos automatizar essas tarefas e otimizar o nosso tempo e produtividade, vamos a um exemplo simples:
Um administrador provisiona 100 servidores por dia e deve executar uma série de comandos em cada um deles antes de entregá-los aos usuários, "meio" trabalhoso, né?!
Com ansible esses comandos podem ser colocados em uma playbook e executados nos 100 servidores, em uma tacada só.
É isso mesmo, não é necessário acessar todas as 100 máquinas (managed nodes) para rodar os comandos, você só precisa fazer a gerência dessa configuração no seu ansible (control node) e uma executar uma vez e irá atingir os 100 servidores. Que tal?
ANSIBLE É AGENTLESS (SEM AGENTE)
O fato de o ansible ser agentless é uma das coisas mais legais, porque não precisamos instalar um client/agent no host que queremos gerenciar e muitas vezes isso não é possivel, especialmente
para engenheiros de redes porque por exemplo, temos routers e switches Cisco rodando cisco IOS, não é possível instalar coisas neles. Portanto todas as instruções são executadas em uma máquina
de controle que se comunica com clientes remotos por SSH.
Idempotência e ansible
Eu confesso que nem conhecia o significado dessa palavra, mas vi que ela é bastante recorrente quando o assunto é automação de TI, parafraseando o glossário do ansible "uma operação é
idempotente se o resultado da sua execução é sempre o mesmo sem que haja qualquer intervenção." O que isso quer dizer? Quer dizer que você pode executar seus playbooks várias
vezes e o resultado final deveria ser o mesmo: os managed nodes estarão no "estado desejado". Se o playbook falhar, é possível solucionar o problema e executar o playbook novamente. Como o
playbook é idempotente, os managed nodes precisam estar no "estado desejado" e nenhuma outra mudança ocorrerá.
No link abaixo temos o glossário do ansible:
https://docs.ansible.com/ansible/latest/reference_appendices/glossary.html
Lab de ansible + vagrant
Agora vamos brincar um pouco de ansible.
Requisitos:
- Instalação do Ansible em um control node.
- Acesso SSH para se comunicar com os managed nodes.
- E python, o ansible pode ser executado com o Python 2 (versão 2.7) ou Python 3 (versões 3.5 e
superior) instalado.
Infraestrutura do lab
Para podermos executar um pouco dessa teoria, vamos criar um simples laboratório composto por três "maquinetas":
- Uma VM será o Control Node
- Duas VMs para Managed Nodes
O provisionamento dessas máquinas será feito com o Vangrant, escrevi um artigo sobre isso aqui.
Instalando o ansible no control node (Ubuntu):
[vagrant@ansible-control:~] $ sudo apt update
[vagrant@ansible-control:~] $ sudo apt install software-properties-common
[vagrant@ansible-control:~] $ sudo apt-add-repository ppa:ansible/ansible
[vagrant@ansible-control:~] $ sudo apt install ansible -y
Lembrando que como o ansible é agentless, essa instalação é feita apenas no control node.
Instalação do ansible:
https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html
Hosts (Inventory)
Agora vamos listar os managed nodes que queremos atingir nesse laboratório.
Acessando /etc/ansible/ e se listarmos o conteúdo desse diretório:
Podemos ver o arquivo ansible.cfg que é o arquivo de configuração do ansible e o arquivo hosts que é onde vamos fazer o inventário dos managed nodes.
Lembrando que o arquivo hosts é um ponto chave no funcionamento do ansible, ele é o inventário e todos os managed nodes que queremos controlar devem estar aqui.
Vamos usar um editor de texto vim para editar esse arquivo e inserir os dois servidores do lab:
[vagrant@ansible-control:~/etc/ansible] $ sudo vim hosts
No final do arquivo vou inserir os servidores, como boa prática recomenda-se inserir por grupos e até mesmo por questão de elegância visual no arquivo, portanto no final do arquivo:
[webservers]
192.168.0.102
192.168.0.103
O [webservers] é o grupo e abaixo inseri os endereços IP dos servidores. E assim apontamos os managed nodes no nosso querido inventário.
Agora para podermos autenticar nos managed nodes, vamos utilizar o método de par de chaves SSH.
Para maiores informações, sobre o assuntoo acesse: https://www.ssh.com/ssh/key/
Acesso SSH
Primeiro vou gerar o par de chaves no control node.
[vagrant@ansible-control:~/.ssh] $ ssh-keygen
Esse comando gera um par de chaves, conhecidas como chave pública e chave privada, esse não é o foco desse artigo, mas usando uma analogia:
- Chave pública (public key) fica no host que quero acessar = cadeado. 🔒
- Chave privada (private key) fica no host que estou usando para acessar = chave. 🔑
As chaves são geradas num diretório oculto da home do usuário (.ssh). No exemplo do laboratório:
/home/vagrant/.ssh/
Agora vamos copiar essas chaves para os managed nodes usando o utilitário ssh-copy-id.
[vagrant@ansible-control:~/.ssh] $ ssh-copy-id vagrant@192.168.0.102
[vagrant@ansible-control:~/.ssh] $ ssh-copy-id vagrant@192.168.0.103
O que esse comando faz é copiar a chave pública para o host de destino em /home/vagrant/.ssh/authorized_keys que é o arquivo que lista as conexões SSH autorizadas para o
host.
Feito isso temos conexão com os managed hosts por par de chaves SSH.
Comandos ad-hoc
Havendo conexão SSH entre o control node e os managed nodes, vamos começar a brincar de ansible, primeiro com comandos ad-hoc que como vimos anteriormente são comando executados
direto na linha de comando.
Vamos testar a comunicação com o comando abaixo:
[vagrant@ansible-control] $ ansible all -m ping
E conforme a saída do comando, tudo ocorreu bem e estamos com comunicação entre o control node e os managed nodes.
Uma outra forma de fazer isso é em vez de declarar "all" significando todos os managed nodes do inventário, posso passar apenas o nome do grupo, o que é muito útil, aqui é um lab, mas numa
infraestrutura real você poderá ter grupos de servidores, grupos de routers, switches etc. e você pode querer aplicar determinada ação a apenas um grupo específico e não em todos (all).
Então em vez disso, declaramos o nome do grupo [webservers].
[vagrant@ansible-control] $ ansible webservers -m ping
Outro exemplo simples de comando ad-hoc para localizar o nome e a versão do sistema operacional dos dois managed nodes:
[vagrant@ansible-control] $ ansible webservers -a "cat /etc/os-release"
Ou podemos executar um comando do módulo de shell direto nos servidores, criando um arquivo vazio em /tmp/ com nome "novo":
[vagrant@ansible-control] $ ansible webservers -m shell -a "touch/tmp/novo"
Agora que entendemos os elementos básicos da execução do Ansible, podemos ir para a automação de tarefas repetitivas usando Playbooks.
Playbooks
O jeito mais poderoso de usar ansible é por meio de playbooks, como vimos anteriormente, uma playbook basicamente é composto por ‘play’ e ‘tasks’ e é um arquivo YAML (.yml).
É recomendado começar com playbooks simples, para que a medida que o entendimento com relação a estrutura das playbooks for crescendo, você vá expandindo as possibilidades..
Vamos criar um playbook muito simples apenas para teste nesse lab.
[vagrant@ansible-control] sudo vim check-nano.yml
--- #Sempre inicia com esses três traços
- name: check-nano #Play
remote_user: root
hosts: webservers #Grupo ou All
tasks: #Task
- name: garantir que o nano esteja lá
apt: #Module
name: nano
state: latest #estado
Portanto ao executar esse playbook, eu quero checar se o editor de texto nano está instalado e na versão mais recente nesses servidores pertencentes ao grupo webservers e se não estiver instalado,
passei o módulo apt para instalação do mesmo.
Executar playbook
Para executar o playbook, rode o comando abaixo:
[vagrant@ansible-control] $ ansible-playbook -check-nano.yml
Não foi necessário especificar o grupo, pois fizemos isso dentro do playbook.
Saída do comando:
Antes de executar esse playbook, eu me certifiquei de que o nano não estava presente nos servidores de destino, justamente para podermos observar as saídas do comando.
Agora que foi instalado com sucesso o nano, vamos executar mais uma vez o playbook:
[vagrant@ansible-control] $ ansible-playbook -check-nano.yml
Lembra da tal Idempotência? Que podemos executar um playbook várias vezes e o resultado final será o mesmo: desde que os managed nodes estejam no "estado desejado"? Pois é, nesse ponto os meus servidores estão com o estado desejado (com o nano instalado em cada um deles), sendo assim não ocorre nenhuma alteração (changed=0) quando executei o playbook novamente.
Sensacional!
Enfim pessoal, usamos apenas exemplos simples nesse lab, mas é possível fazer coisas muito maiores com essa ferramenta espetacular, estude ansible!
Você pode encontrar mais informações na documentação oficial do ansible:
https://docs.ansible.com
Abraços!
Max
📧 contato@maxaddress.com.br
ℹ️ linkedin.com/in/maxwlima
🌐 www.maxaddress.com.br