IaC Ansible – Estruturando um inventário

Na ideia de fazer um IaC precisamos ter um local que represente o estado de como nossa estrutura deve ser, para o Ansible esse local é o inventory. Nele ficam armazenadas as informações dos seus hosts e variáveis que são usadas na execução do seu playbook.

A dificuldade esta em como “montar” um “bom” inventário, pois nem tudo esta bem claro na documentação. 🙂

O link da documentação oficial esta aqui: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

Como dividir os diretórios e arquivos?

A melhor maneira que encontrei para compor foi me baseando no modelo apresentado nesse documento: https://docs.ansible.com/ansible/latest/user_guide/sample_setup.html#sample-directory-layout

Onde existe um diretório para cada “ambiente” (production, staging), sendo possível separa as suas respectivas informações.

inventories/
   production/
      hosts               # inventory file for production servers
      group_vars/
         group1.yml       # here we assign variables to particular groups
         group2.yml
      host_vars/
         hostname1.yml    # here we assign variables to particular systems
         hostname2.yml

   staging/
      hosts               # inventory file for staging environment
      group_vars/
         group1.yml       # here we assign variables to particular groups
         group2.yml
      host_vars/
         stagehost1.yml   # here we assign variables to particular systems
         stagehost2.yml

library/
module_utils/
filter_plugins/

site.yml
webservers.yml
dbservers.yml

roles/
    common/
    webtier/
    monitoring/
    fooapp/

A minha escolha para essa estrutura esta na facilidade da gestão do deste conteúdo, pois todo esse inventário pode estar no mesmo repositório do git. Não precisando tem um repositório para cada “ambiente”.

Mas nem tudo é host

É agora que o bicho pega. Que você entra no vale das sombras.

Existem coisas como um cluster kubernetes, um cluster de banco de dados, um serviço de nuvem, que não são hosts. Não existe um servidor que o Ansible vai conectar para executar as tarefas. Mas você precisa que o playbook seja executado, como fazer?

Por sorte (ou evolução do produto), você pode criar um “fake host”. Algo que o Ansible vai tratar como host, mas não vai se conectar a ele, para isso, basta usar a key:value ansible_connection: local em um host, como abaixo:

all:
  hosts:
    meu-fake-host:
      ansible_connection: local

Assim o Ansible ira executar essas informações localmente (onde o playbook esta sendo executado) e consequentemente pode ser uma chamadas para a SDK de uma nuvem instaladas no local que executa o playbook.

Tratando em arquivos atômicos ou dividindo em subdiretórios

O Ansible faz um fullscan nos arquivos abaixo do nível inicial do inventário, mas ele não carrega o conteúdo dos subdiretórios mesmo com os nomes dos diretórios ou arquivos estarem no “formato” padrão.

Mas para fazer isso funcionar existe uma solução, que eu acho ainda mais elegante. Eu sou “partidário” do modelo de atomização (um dia faço um post sobre esse modelo), e seguindo por essa linha, o Ansible permite que cada arquivo seja “auto contido”.

O que isso quer dizer? quer você pode ter um arquivo “completo” e Ansible junta com outros arquivos “completos”, fazendo em memória um grande “completão”.

Desta foram, podemos ter algo assim:

inventories/
   production/
      mysql/
         mysql-cluster-intranet.yml
         mysql-cluster-crm.yml
         mysql-cluster-ecommercer.yml     

Tendo assim, um sub diretório para as configurações dos clusters mysql.

Mas para isso funcionar, o conteúdo do arquivo é o mais importante. Cada um desses arquivos deve ser algo como:

all:
  hosts:
    mysql-cluster-intranet:
      node_numbers: 10

Ao fazer o o uso de all.hosts, o Ansible consegue identificar que este arquivo mesmo não estando dentro do diretórios esperado esta descrevendo um host.

Tenha um playbook que faça 100%

Esse tema não é bem vinculado ao inventário, mas vela a pena repetir.

Tenha um paybook que faça a chamada para os seus outros playbook e que no fim, faça 100% das suas configurações.

O ideal (“certo”) é você atomizar os seus playbooks, mas ter 1 que se for chamado, execute tudo, do inicio ao fim da construção do seu ambiente.

“E digo mais.” Recomendo ainda que pelo menos uma vez por mês você destrua todo o seu ambiente de homologação, desenvolvimento, etc, ambientes não produtivo e execute esse playbook para refazer tudo a partir do zero.

Não digo para você fazer isso na produção, porque provavelmente vai ter problema (vai dar merda), mas se você já esta fazendo isso a algum tempo em homologação, vai na fé e coloca em produção pra fazer também.

Da parte teórica é isso. Abraços e até o próximo post.