DEV Community

Stefano Martins
Stefano Martins

Posted on

4 2

Recarregando o inventário do Ansible durante a execução

Introdução

Esta dica surgiu a partir de uma dúvida no Telegram da LINUXtips e é ótima para quem precisa trabalhar com inventários dinâmicos ou realiza modificações em seu arquivo de inventário.

Imagine o seguinte cenário: Você possui um playbook que realiza modificações no seu inventário como adicionar um novo host, e durante a mesma execução do playbook precisa que este host recém-adicionado seja levado em consideração para uma próxima task ou role.

Para melhor ilustrar, criei abaixo um arquivo de inventário e um playbook que simplesmente irá imprimir todos os hosts do inventário, adicionar um novo host chamado host-03 e depois imprimir novamente os hosts:

# hosts
[all]
host-01
host-02
Enter fullscreen mode Exit fullscreen mode
# playbook.yml
--- 
- hosts: localhost
  become: true
  connection: local
  tasks:

    - name: Print list of hosts in inventory
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ groups['all'] }}"

    - name: Add host to inventory
      ansible.builtin.lineinfile:
        line: host-03
        path: ./hosts
        regexp: "^host-03"
        state: present

    - name: Print list of hosts in inventory
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ groups['all'] }}"
Enter fullscreen mode Exit fullscreen mode

Vamos executar o nosso playbook com ansible-playbook -i hosts playbook.yml, obtendo o seguinte resultado:

PLAY [localhost] ************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [localhost]

TASK [Print list of hosts in inventory] *************************************************************************************************************************************
ok: [localhost] => (item=host-01) => {
    "msg": "host-01"
}
ok: [localhost] => (item=host-02) => {
    "msg": "host-02"
}

TASK [Add host to inventory] ************************************************************************************************************************************************
changed: [localhost]

TASK [Print list of hosts in inventory] *************************************************************************************************************************************
ok: [localhost] => (item=host-01) => {
    "msg": "host-01"
}
ok: [localhost] => (item=host-02) => {
    "msg": "host-02"
}

PLAY RECAP ******************************************************************************************************************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Enter fullscreen mode Exit fullscreen mode

Percebe que foi adicionado um novo host host-03 (inclusive, você perceberá a nova entrada no arquivo hosts), porém na segunda impressão, ele continua não sendo impresso? O motivo disso é devido ao fato de que o Ansible apenas carrega na memória o inventário durante o início da execução do playbook, ignorando eventuais alterações no mesmo (inclusive para inventários dinâmicos).

Mas a pergunta que fica é: OK, e se eu precisar que alterações no meu inventário sejam à quente, para continuidade na execução? Bom, aí temos principalmente duas opções:

Opção A: utilize o módulo add_host

O módulo add_host serve para adicionarmos hosts dinamicamente à execução do Ansible, porém não persistidas no arquivo de inventário. Podemos utilizá-lo, adicionando uma task extra ao nosso playbook, carregando o host host-03 também na memória:

--- 
- hosts: localhost
  become: true
  connection: local
  tasks:

    - name: Print list of hosts in inventory
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ groups['all'] }}"

    - name: Add host to inventory file
      ansible.builtin.lineinfile:
        line: host-03
        path: ./hosts
        regexp: "^host-03"
        state: present

    - name: Add host to inventory (memory)
      ansible.builtin.add_host:
        name: host-03

    - name: Print list of hosts in inventory
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ groups['all'] }}"
Enter fullscreen mode Exit fullscreen mode

O resultado da execução é o seguinte:

PLAY [localhost] ************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [localhost]

TASK [Print list of hosts in inventory] *************************************************************************************************************************************
ok: [localhost] => (item=host-01) => {
    "msg": "host-01"
}
ok: [localhost] => (item=host-02) => {
    "msg": "host-02"
}

TASK [Add host to inventory file] *******************************************************************************************************************************************
changed: [localhost]

TASK [Add host to inventory (memory)] ***************************************************************************************************************************************
changed: [localhost]

TASK [Print list of hosts in inventory] *************************************************************************************************************************************
ok: [localhost] => (item=host-01) => {
    "msg": "host-01"
}
ok: [localhost] => (item=host-02) => {
    "msg": "host-02"
}
ok: [localhost] => (item=host-03) => {
    "msg": "host-03"
}

PLAY RECAP ******************************************************************************************************************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Enter fullscreen mode Exit fullscreen mode

Opção B: utilize a metatask refresh_inventory

Metatasks são basicamente tasks que alteram o comportamento do Ansible durante sua execução. Vamos adicionar uma delas no nosso playbook após a adição do nosso host ao arquivo de inventário para que o mesmo seja recarregado antes da nova impressão:

--- 
- hosts: localhost
  become: true
  connection: local
  tasks:

    - name: Print list of hosts in inventory
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ groups['all'] }}"

    - name: Add host to inventory file
      ansible.builtin.lineinfile:
        line: host-03
        path: ./hosts
        regexp: "^host-03"
        state: present

    - meta: refresh_inventory

    - name: Print list of hosts in inventory
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ groups['all'] }}"
Enter fullscreen mode Exit fullscreen mode
PLAY [localhost] ************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [localhost]

TASK [Print list of hosts in inventory] *************************************************************************************************************************************
ok: [localhost] => (item=host-01) => {
    "msg": "host-01"
}
ok: [localhost] => (item=host-02) => {
    "msg": "host-02"
}

TASK [Add host to inventory file] *******************************************************************************************************************************************
changed: [localhost]

TASK [Print list of hosts in inventory] *************************************************************************************************************************************
ok: [localhost] => (item=host-01) => {
    "msg": "host-01"
}
ok: [localhost] => (item=host-02) => {
    "msg": "host-02"
}
ok: [localhost] => (item=host-03) => {
    "msg": "host-03"
}

PLAY RECAP ******************************************************************************************************************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Enter fullscreen mode Exit fullscreen mode

 Conclusão

Neste breve artigo nós vimos como o Ansible lê seu inventário, e como podemos adicionar novos hosts durante sua execucão para novas tasks e roles, este conhecimento sendo aplicável tanto para inventários dinâmicos quanto estáticos (ou quando nós queremos manipular o nosso arquivo hosts).

Espero que tenham curtido!

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (1)

Collapse
 
welkson profile image
Welkson Renny de Medeiros • Edited

Excelente post @stefanomartins !

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more