O gerenciamento de configurações é uma parte fundamental e de extrema importância dentro do ciclo de vida DevOps. Manter a infraestrutura automatizada de forma orquestrada é um fator importantissímo dentro de uma organização.
Existem várias ferramentas para gerenciamento de configuração, por exemplo, Puppet, Ansible, Chef, SaltStack. E claro, o Ansible, que é uma das ferramentas mais populares atualmente e com menor curva de aprendizado nos permite gerenciar de 1 a milhares de servidores de forma rápida e simplificada.
Introdução
Uma das grandes vantagens do Ansible, é que ele é “Agentless”, ou seja, ele não depende de instalação de agente no host em que desejamos gerenciar bastando somente o serviço SSH ativo e o Python instalado no host em que desejamos gerenciar, facilitando muito a nossa vida não é mesmo?
Para a implantação do Ansible em nosso ambiente vamos utilizar como exemplos dois servidores virtuais com o sistema operacional Ubuntu Server 20.04 sendo eles:
ubuntu-server-01 (IP: 192.168.153.16): Onde será instalado o Ansible (Podemos dizer que será nosso servidor Ansible).
ubuntu-server-02 (IP: 192.168.153.17): Um servidor em nossa rede que desejamos gerencia-lo pelo nosso Ansible server.
Instalando o Ansible
Antes de iniciarmos a instalação confirme que o seu sistema operacional esteja atualizado:
sudp apt update
O repositório padrão do Ubuntu 20.04 já contém a ultima release estável do Ansible:
sudo apt-cache policy ansible
ansible:
Installed: (none)
Candidate: 2.9.6+dfsg-1
Version table:
2.9.6+dfsg-1 500
500 http://br.archive.ubuntu.com/ubuntu focal/universe amd64 Packages
Sendo assim, você pode instalar o Ansible com o seguinte comando:
sudo apt install ansible
Após a instalação do pacote você pode conferir o resultado com o seguinte comando:
ansible --version
Deverá ser apresentado o resultado como o abaixo:
ansible 2.9.6
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/amc/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
executable location = /usr/bin/ansible
python version = 3.8.2 (default, Jul 16 2020, 14:00:26) [GCC 9.3.0]
Configurando o nó de controle do Ansible
Com o Ansible já instalado, é hora de colocarmos a mão na massa e configurá-lo.
Ansible Inventory
O Ansible Inventory é o arquivo onde definimos os hosts que serão gerenciados pelo nosso Ansible. O caminho padrão do arquivo é o /etc/ansible/hosts. Você pode criar um arquivo customizado do mesmo em outro local, porém, é necessário no momento em que for executar o Ansible utilizar o parâmetro -i <path> do arquivo customizado.
No arquivo de inventário também pode ser armazenado variáveis relacionado a um determinado host ou grupo de hosts. Segue algumas informações relevantes:
- Você pode especificar um host pelo hostname ou endereço ip;
- Um grupo de hosts é delimitado definido pelo elemento [header];
- Um host/IP pode pertencer a vários grupos de hosts;
Segue um exemplo de um arquivo de inventário do Ansible contendo hosts não agrupados, hosts agrupados, intervalo de hosts, etc:
# Hosts não agrupados
server01.amctecnologia.intra
192.168.153.1
# Range de hosts
192.168.153.[100:115]
#Grupo de hosts com ranges definidos
[servidoresweb]
web[01:04].amctecnologia.intra
# Hosta dentro do grupo database
[database]
db[01:03].amctecnologia.intra
db04.amctecnologia.intra
db08.amctecnologia.intra
#Definindo o nome do host com seu respectivo IP
[apps]
apps01 ansible_host=192.168.153.113
Neste tutorial eu vou definir um arquivo de inventário customizado dentro do meu home directory criando nele um grupo chamado “TESTE” onde irá constar o ubuntu-server-02:
mkdir $HOME/ansible
vim $HOME/ansible/hosts
[TESTE]
ubuntu-server-02 ansible_host=192.168.153.17
OBS: Qualquer host individual fora de algum grupo deve ser declarado no início do arquivo antes de definir qualquer grupo.
Você pode listar os hosts cadastrados em seu inventário com o seguinte comando:
ansible-inventory -i $HOME/ansible/hosts --list -y
Segue abaixo o exemplo contendo a saída do comando:
all:
children:
TESTE:
hosts:
ubuntu-server-02:
ansible_host: 192.168.153.17
ungrouped: {}
Configurando as chaves de autenticação SSH
Como dito anteriormente, utilizamos o SSH para gerenciarmos os hosts pelo Ansible, com isto, necessitamos gerar as chaves SSH e copiarmos para os hosts a serem gerenciados de modo que seja possível autenticarmos nos hosts sem a necessidade de autenticação com senha. Para isto siga as etapas abaixo:
Gerando a chave SSH
Execute o comando abaixo:
ssh-keygen
Para gerar a chave sem senha, simplesmente aperte a tecla ENTER quando for solicitado senha:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/amc/.ssh/id_rsa):
Created directory '/home/amc/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/amc/.ssh/id_rsa
Your public key has been saved in /home/amc/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:uM5Luy6/HiX+pJ2Yz2+ItvWwOFuz4OeuyCYZ5ExVkfw amc@ubuntu-server-01
The key's randomart image is:
+---[RSA 3072]----+
| ooo |
| . o |
| . . |
| o .E |
| = o S |
| + . + |
| o *.*. |
| o.o*+/oB. |
| oo*^&@oo |
+----[SHA256]-----+
Copiando a chave gerada para o host remoto:
ssh-copy-id -o StrictHostKeyChecking=no amc@192.168.153.17
No comando acima, a chave gerada foi copiada para o host de ip 192.168.153.17 utilizando o usuário “amc” do host remoto. Altere de acordo com o ip e usuário do seu host remoto.
A saída do comando deverá ser exibida assim:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/amc/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
amc@192.168.153.17's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -o 'StrictHostKeyChecking=no' 'amc@192.168.153.17'"
and check to make sure that only the key(s) you wanted were added.
Para testar execute o comando:
ssh amc@192.168.153.17
Alterando o respectivo usuário e ip do host remoto, você deverá se conectar ao host remoto sem ser solicitado nenhuma senha. Se isto aconteceu, a troca de chaves deu certo!
Nesta demonstração, usaremos um usuário com privilégios de execução de comandos root sem solicitação de senha, porém para isto, precisamos configurar no host remoto para que isto seja possível. No host remoto como usuário “root” execute o seguinte comando:
echo "amc ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/amc
Lembre-se de alterar o usuário de acordo com o desejado no host remoto, no nosso exemplo estamos utilizando o usuário amc, configure de acordo com o seu ambiente ok?
Testando a conexão do Ansible com o host remoto
O Ansible utiliza o módulo ping para testar a conectividade dele com os hosts remotos, de acordo com o nosso inventário criado abaixo, vamos relembra-lo novamente?
ansible-inventory -i $HOME/ansible/hosts --list -y
all:
children:
TESTE:
hosts:
ubuntu-server-02:
ansible_host: 192.168.153.17
ungrouped: {}
No exemplo abaixo, utilizando o usuário “amc” vamos testar a conectividade:
ansible -i $HOME/ansible/hosts -m ping -u amc all
Retorno do teste de conectividade com sucesso:
ubuntu-server-02 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
Retorno do teste com falha de conectividade com o host remoto:
ubuntu-server-02 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.153.17 port 22: Connection timed out",
"unreachable": true
}
Executando comandos ad-hoc no Ansible
Caso você tenha alguma tarefa que raramente se repete, você pode utilizar comandos ad-hoc para executa-las em seus hosts remotos gerenciados pelo Ansible. Segue alguns exemplos:
Testando conectividade de seu host remoto com a internet
ansible -i $HOME/ansible/hosts -a "ping 8.8.8.8 -c 3" all -u amc
No comando acima pelo servidor ansible solicitamos um ping a partir do dos hosts gerenciados por ele para o ip 8.8.8.8, exemplo de saída:
ubuntu-server-02 | CHANGED | rc=0 >>
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=24.5 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=115 time=24.6 ms (DUP!)
64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=19.4 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=115 time=19.4 ms (DUP!)
64 bytes from 8.8.8.8: icmp_seq=3 ttl=116 time=19.2 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, +2 duplicates, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 19.218/21.406/24.552/2.555 ms
Verificar espaço em disco dos hosts remotos
ansible -i $HOME/ansible/hosts -a "df -h" all -u amc
No comando acima pelo servidor ansible executamos o comando “df -h” a partir dos hosts gerenciados por ele, exemplo de saída:
ubuntu-server-02 | CHANGED | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
udev 449M 0 449M 0% /dev
tmpfs 99M 1020K 98M 2% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 3.9G 2.2G 1.5G 60% /
tmpfs 491M 0 491M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 491M 0 491M 0% /sys/fs/cgroup
/dev/sda2 976M 103M 806M 12% /boot
/dev/loop0 55M 55M 0 100% /snap/core18/1705
/dev/loop1 69M 69M 0 100% /snap/lxd/14804
/dev/loop2 28M 28M 0 100% /snap/snapd/7264
tmpfs 99M 0 99M 0% /run/user/1000
Copiar um arquivo específico para os hosts remotos
ansible -i $HOME/ansible/hosts -m copy -a "src=/etc/hosts dest=/etc/hosts" all -u amc --become
No exemplo acima estamos copiando o arquivo /etc/hosts do servidor ansible para todos os hosts remotos cadastrados no inventário:
ubuntu-server-02 | CHANGED => {
"changed": true,
"checksum": "7e3e758762bcb2f12783b0b50261ce66bcdf5aec",
"dest": "/etc/hosts",
"gid": 0,
"group": "root",
"md5sum": "7c9077c3a5265b1249f05ccba5d2dc6d",
"mode": "0644",
"owner": "root",
"size": 267,
"src": "/home/amc/.ansible/tmp/ansible-tmp-1596742880.9852812-51942724752263/source",
"state": "file",
"uid": 0
}
Conclusão
Finalizamos aqui este tutorial abordando a instalação e execução de alguns exemplos básicos de uso do Ansible mostrando uma pequena parte do que ele é capaz! Em breve disponibilizarei novos tutorias e dicas sobre Ansible.
Até a próxima!