ANSIBLE SERIES: h.t.wrt* … Inventories: HOSTS

Precursores de um fim anunciado, esses são os inventários. Calma! Não estou dizendo que ninguém aqui vai morrer! Estou me referindo apenas a este post. Nele prometi que o final da série seria dividido em várias partes, sendo elas: Ansible GALAXY, Ansible VAULT, Ansible INVENTORIES, e Ansible para WINDOWS (na época utilizei a palavra miscelâneas para o último, ou simplesmente MISC). Duas dessas já vimos, Galaxy e Vault, faltando agora somente as outras duas, Inventories e Windows. E sim, curiosos e apressadinhos, esse será o penúltimo capítulo da saga “ANSIBLE”.

Então, vamos lá! Como organizar um conjunto de máquinas/servidores? Bem, um inventário nada mais é do que um registro de informações a respeito de determinada coleção de itens/recursos. Especificamente para nós, estamos em busca de nomes de hosts, endereços IP, portas, usuários, senhas, e afins. Para obter tais dados, em um primeiro momento, não tem jeito … A não ser logando no seu vCenter, Proxmox, ou OpenStack e listando máquina por máquina. Mas não se desespere ainda! Evidentemente que, como tudo na vida, existe outro meio … Primeiro adicione um novo usuário local no nó controlador (ex: ansible) Em seguida, crie o mesmo usuário (quero dizer, todos os logins serão iguais) nos outros nós a serem gerenciados. Retorne ao master e gere uma chave SSH com o dito ‘usuário’. Depois copie para os demais ‘usuários’ (mesmo nome) presentes em cada slave. Execute o comando ad-hoc usando o módulo ping com o intuito de testar a comunicação. Uma vez bem sucedida, utilize o módulo debug para saber o IP e HOSTNAME de cada um. Ao final, copie e cole tudo no arquivo de inventário padrão do Ansible: /etc/ansible/hosts

Fácil não? Mas devagar que não é só isso! Existe uma infinidade de detalhes e pormenores que podem te ajudar. Me acompanhe, por favor!

>_ Básico do básico: FORMATOS, HOSTS e GRUPOS

Flexível e bastante amigável, o Ansible possibilita um verdadeiro leque de opções quando se trata de inventários. Por exemplo, podemos ter:

  • um único arquivo para todos os hosts
  • vários arquivos separados por grupos e subgrupos
  • formatos específicos para plugins específicos

/etc/ansible/hosts

Principal arquivo de inventário, o mesmo é automaticamente criado quando se instala o ANSIBLE pela primeira vez. Caso essa seja a sua escolha, “um arquivo para tudo e todos”, é recomendado que cadastre aqui. O formato aceito para trabalhar é o tão conhecido INI (padrão informal para arquivos de configuração) Sua aparência será mais ou menos assim:

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

Reparem que podemos deixar máquinas “soltas”, ou agrupadas, de acordo com finalidade/uso. Para nomear um grupo de servidores você deve colocá-lo entre colchetes, sempre e sem exceções.

Também é possível escrever o mesmo arquivo no formato YAML, que é aceito pelo Ansible. Vejam:

all:
  hosts:
    mail.example.com:
  children:
    webservers:
      hosts:
        foo.example.com:
        bar.example.com:
    dbservers:
      hosts:
        one.example.com:
        two.example.com:
        three.example.com:

ansible-playbook -i <path>

( /whatever_location/some_folder/your_inventory )

Se prefere separar as coisas, então talvez seja melhor criar vários arquivos nomeados por ambiente. Por exemplo:

/home/username/hlg_srvs

[linux-rhel]
centos6.example.com
centos7.example.com
centos8.example.com

[linux-deb]
debian11.example.com
ubuntu22-04.example.com

/home/username/prd_srvs

[windows]
2008R2.example.com
2012R2.example.com

[redhat]
el9.example.com

[suse]
leap.example.com
tumbleweed.example.com

E na hora de rodar um playbook ou executar um comando ad-hoc, informe o parâmetro -i + caminho:

ansible-playbook -i /home/victor/hlg_srvs test.yml
ansible -i /home/victor/prd_srvs -m ping all

inventory plugins

Para trabalhar com formatos e plugins específicos, antes de editar/criar seu arquivo inventário, primeiro verifique outro arquivo, o de configuração chamado /etc/ansible/ansible.cfg

Nele procure por enable_plugins na seção intitulada de [inventory]

[inventory]
enable_plugins = host_list, script, auto, yaml, ini, toml

Coloque aqui o nome completo (fully qualified name) do PLUGIN

[inventory]
enable_plugins = host_list, script, auto, yaml, ini, toml, namespace.collection_name.inventory_plugin_name

E construa seu arquivo inventário de acordo com o plugin. Por exemplo, veja a seguir:

# demo.aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
  - us-east-2
keyed_groups:
  # add hosts to tag_Name_value groups for each aws_ec2 host's tags.Name variable
  - key: tags.Name
    prefix: tag_Name_
    separator: ""
  # If you have a tag called "Role" which has the value "Webserver", this will add the group
  # role_Webserver and add any hosts that have that tag assigned to it.
  - key: tags.Role
    prefix: role
groups:
  # add hosts to the group development if any of the dictionary's keys or values is the word 'devel'
  development: "'devel' in (tags|list)"
  # add hosts to the "private_only" group if the host doesn't have a public IP associated to it
  private_only: "public_ip_address is not defined"
compose:
  # use a private address where a public one isn't assigned
  ansible_host: public_ip_address|default(private_ip_address)
  # alternatively, set the ansible_host variable to connect with the private IP address without changing the hostname
  # ansible_host: private_ip_address
  # if you *must* set a string here (perhaps to identify the inventory source if you have multiple
  # accounts you want to use as sources), you need to wrap this in two sets of quotes, either ' then "
  # or " then '
  some_inventory_wide_string: '"Yes, you need both types of quotes here"'

>_ Inventários: VARIÁVEIS

Sempre úteis em qualquer linguagem, as variáveis nos permitem informar novos e diferentes valores sem necessariamente ter que editar o código-fonte toda vez. No caso do Ansible, você pode muito bem definir variáveis apenas para um host específico, ou quem sabe, para um grupo de máquinas inteiro. Entretanto, nem tudo são flores, pois conforme seu inventário cresce, também aumenta a complexidade de gerenciá-las. Sendo assim, talvez você opte por armazená-las em arquivos separados, que não o inventário. Leia mais aqui

Associando uma variável por máquina ( 1 : 1 ) HOST VARS

É possível assinalar uma variável específica para um único host, e depois utilizá-la em seus playbooks. Veja como:

INI

[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

YAML

atlanta:
  hosts:
    host1:
      http_port: 80
      maxRequestsPerChild: 808
    host2:
      http_port: 303
      maxRequestsPerChild: 909

Valores exclusivos, como portas SSH fora do padrão, também funcionam como ótimas variáveis. Acrescente-as diretamente no arquivo inventário adicionando um dois-pontos (:) no final do hostname. Por exemplo:

badtux.example.com:2209

Tipos de conexão também são excelentes candidatas a variáveis. A seguir:

[targets]

localhost              ansible_connection=local
other1.example.com     ansible_connection=ssh        ansible_user=myuser
other2.example.com     ansible_connection=ssh        ansible_user=myotheruser

Associando uma variável para várias máquinas ( 1 : N ) GROUP VARS

INI

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

YAML

atlanta:
  hosts:
    host1:
    host2:
  vars:
    ntp_server: ntp.atlanta.example.com
    proxy: proxy.atlanta.example.com

Herdando uma variável para grupos ( N : N ) CHILDREN VARS

Você pode fazer grupos de grupos usando o sufixo :children em INI ou a entrada children: em YAML. Você também pode aplicar variáveis a esses grupos de grupos usando :vars ou vars:

INI

[rio]
host1
host2

[saopaulo]
host2
host3

[brazil:children]
rio
saopaulo

[brazil:vars]
some_server=ipanema.girl.example.com.br
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[southamerica:children]
brazil
argentina

YAML

all:
  children:
    southamerica:
      children:
        brazil:
          children:
            rio:
              hosts:
                host1:
                host2:
            saopaulo:
              hosts:
                host2:
                host3:
          vars:
            some_server: ipanema.girl.example.com.br
            halon_system_timeout: 30
            self_destruct_countdown: 60
            escape_pods: 2
        argentina:
        chile:
        uruguay:

Os grupos filhos têm algumas propriedades a serem observadas:

  • Qualquer host que seja membro de um grupo filho é automaticamente membro do grupo pai.
  • As variáveis de um grupo filho terão maior precedência (substituir) as variáveis de um grupo pai.
  • Os grupos podem ter vários pais e filhos, mas não relacionamentos circulares.
  • Os hosts também podem estar em vários grupos, mas haverá apenas uma instância de um host, mesclando os dados dos vários grupos.

>_ Inventários: MÚLTIPLOS ARQUIVOS

Como usar várias origens/fontes simultaneamente

Você pode atingir diversos inventários (pastas, scripts dinâmicos ou arquivos de plugins) fornecendo vários parâmetros na linha de comando ou configurando o ANSIBLE_INVENTORY. Isso pode ser útil quando estamos em busca de “alvos” presentes em ambientes separados, como homologação e produção, ao mesmo tempo que executamos X em todos eles.

Para utilizar duas fontes distintas, na linha de comando informe exatamente assim:

ansible-playbook do_something.yml -i /path/to/homolog -i /path/to/production

Tenha em mente que se houver conflitos de variáveis nos inventários, eles serão resolvidos de acordo com as regras descritas em Como as variáveis são mescladas e Precedência de variáveis: Onde devo colocar uma variável? A ordem de mesclagem é controlada pela ordem dos parâmetros de origem do inventário. Se [all:vars] no inventário de teste definir myvar = 1, mas o inventário de produção definir myvar = 2, o playbook será executado com myvar = 2. O resultado seria revertido se o playbook fosse executado com -i production -i homolog

>_ Conectando-se: Definindo PARÂMETROS, HOSTS e ETC

Para o Ansible, um arquivo de inventário (qualquer que seja) pode ou não conter parâmetros que irão controlar a conexão. Tipo de protocolo, porta, endereço IP, usuário, chave, são apenas alguns exemplos da versatilidade do ANSIBLE. Na ausência de um ou mais, a ferramenta adotará os padrões já estabelecidos de fábrica. Por exemplo, SSH na porta 22 com usuário ‘root’ do sistema.

E devido a quantidade considerável de parâmetros possíveis, fica registrado a recomendação de leitura para:

REFERÊNCIAS:

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

https://docs.ansible.com/ansible/latest/cli/ansible-inventory.html

Deixe uma resposta

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.