Como instalar e configurar o Ansible no Ubuntu?

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!

Deixe uma resposta