<p>The <a href="https://docs.ansible.com/ansible/latest/collections/ansible/builtin/add_host_module.html" rel="nofollow noreferrer">add_host</a> task works as expected. For example (simplified a bit), given the list of the groups</p>
<pre class="lang-yaml prettyprint-override"><code>  my_groups: [cloned_group]
</code></pre>
<pre class="lang-yaml prettyprint-override"><code>    - add_host:
        name: &quot;{{ item }}&quot;
        groups: &quot;{{ my_groups }}&quot;
      loop: [cm_1, cm_2, cm_3]
</code></pre>
<p>will create the inventory group <em>cloned_group</em>. Let's take a look</p>
<pre class="lang-yaml prettyprint-override"><code>    - debug:
        var: groups.cloned_group
</code></pre>
<p>gives as expected</p>
<pre class="lang-yaml prettyprint-override"><code>  groups.cloned_group:
  - cm_1
  - cm_2
  - cm_3
</code></pre>
<p>See the special variable <a href="https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html#term-groups" rel="nofollow noreferrer">group</a>. Quoting:</p>
<blockquote>
<p>A dictionary/map with all the groups in inventory and each group has the list of hosts that belong to it</p>
</blockquote>
<hr>
<sup>
<p>Example of a complete playbook for testing</p>
<pre class="lang-yaml prettyprint-override"><code>- hosts: localhost

  vars:

    my_groups: [cloned_group]

  tasks:

    - add_host:
        name: &quot;{{ item }}&quot;
        groups: &quot;{{ my_groups }}&quot;
      loop: [cm_1, cm_2, cm_3]

    - debug:
        var: groups.cloned_group
</code></pre>
</sup>
<hr>
<p>Q: <em><strong>&quot;No hosts added to the cloned_group in the inventory.&quot;</strong></em></p>
<p>A: If you by &quot;in the inventory&quot; mean &quot;in the inventory file&quot; then this is correct. No hosts will be added to an inventory file.</p>
<p>For example, given the below inventory file</p>
<pre class="lang-ini prettyprint-override"><code>shell&gt; cat hosts
[test]
test_01
test_02
test_03

[test:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl
</code></pre>
<p>If you want to update the inventory file:</p>
<ul>
<li>Get the path to the file. See the special variable <a href="https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html#term-ansible_inventory_sources" rel="nofollow noreferrer">ansible_inventory_sources</a>. There might be more files in the list, hence take the first one</li>
</ul>
<pre class="lang-yaml prettyprint-override"><code>  my_file: &quot;{{ ansible_inventory_sources.0 }}&quot;
</code></pre>
<p>gives</p>
<pre class="lang-yaml prettyprint-override"><code>  my_file: /scratch/tmp1/test-024/hosts
</code></pre>
<ul>
<li>Create the block with your group(s)</li>
</ul>
<pre class="lang-yaml prettyprint-override"><code>  my_inventory: |
    {% for group in my_groups %}
    [{{ group }}]
    {% for host in groups[group] %}
    {{ host }}
    {% endfor %}
    {% endfor %}
</code></pre>
<p>gives</p>
<pre class="lang-yaml prettyprint-override"><code>  my_inventory: |-
    [cloned_group]
    cm_1
    cm_2
    cm_3
</code></pre>
<ul>
<li>Backup the inventory file</li>
</ul>
<pre class="lang-yaml prettyprint-override"><code>    - command:
        cmd: &quot;cp {{ my_file }} {{ my_file }}.backup&quot;
        creates: &quot;{{ my_file }}.backup&quot;
</code></pre>
<ul>
<li>Update the inventory file</li>
</ul>
<pre class="lang-yaml prettyprint-override"><code>    - blockinfile:
        path: &quot;{{ my_file }}&quot;
        block: &quot;{{ my_inventory }}&quot;
</code></pre>
<p>gives what you (probably) want</p>
<pre class="lang-ini prettyprint-override"><code>shell&gt; cat hosts
[test]
test_01
test_02
test_03

[test:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl
# BEGIN ANSIBLE MANAGED BLOCK
[cloned_group]
cm_1
cm_2
cm_3
# END ANSIBLE MANAGED BLOCK
</code></pre>
<hr>
<sup>
<p>Example of a complete playbook for testing</p>
<pre class="lang-yaml prettyprint-override"><code>- hosts: localhost

  vars:

    my_file: &quot;{{ ansible_inventory_sources.0 }}&quot;
    my_groups: [cloned_group]
    my_inventory: |
      {% for group in my_groups %}
      [{{ group }}]
      {% for host in groups[group] %}
      {{ host }}
      {% endfor %}
      {% endfor %}

  tasks:

    - add_host:
        name: &quot;{{ item }}&quot;
        groups: &quot;{{ my_groups }}&quot;
      loop: [cm_1, cm_2, cm_3]

    - debug:
        var: groups.cloned_group

    - debug:
        var: ansible_inventory_sources
    - debug:
        var: my_file
    - debug:
        var: my_inventory

    - command:
        cmd: &quot;cp {{ my_file }} {{ my_file }}.backup&quot;
        creates: &quot;{{ my_file }}.backup&quot;

    - blockinfile:
        path: &quot;{{ my_file }}&quot;
        block: &quot;{{ my_inventory }}&quot;
</code></pre>
</sup>

CC BY-SA 4.0
2024-01-10T14:08:54.667Z
it gives me the same output but still no hosts added to the  cloned_group in the inventory .what does this output indicates ?
Kavisha Abeynayaka
CC BY-SA 4.0
2024-01-10T14:54:35.387Z
The module *add_host* does not change the inventory file. The module will "Add a host (and alternatively a group) to the ansible-playbook in-memory inventory". The hosts are added to the inventory "for use in later plays of the same playbook". These hosts and the groups are not in the inventory anymore after the playbook terminates.
Vladimir Botka
CC BY-SA 4.0
2024-01-10T15:34:25.890Z
I added an example of how to update the inventory file.
Vladimir Botka
CC BY-SA 4.0
2024-01-16T08:44:06.620Z
Can I  run the necessary steps to clone the a vm after updating the inventory  like above in the same playbook
Kavisha Abeynayaka
CC BY-SA 4.0
2024-01-10T12:17:11.007Z
2024-01-10T15:33:48.440Z
2024-01-10T15:33:48.440Z
Vladimir Botka
<p>I am trying to  dynamically populate an inventory group called cloned_group in my current inventory . I passed the hostnames through the survey by the following names clone_machine_1, clone_machine_2, clone_machine_3. I used the ansible module add_host.The tasks were executed successfully but I did not see the expected hostnames in my inventory.</p>
<pre><code>---
- name: Stage source vm
  hosts: localhost
  gather_facts: false
  vars_files: 
    - common-vars.yml
  vars: 
    localusername: testlocal

  tasks:
    - name: Add host to the cloned group from the survey list 
      ansible.builtin.add_host:
        name: &quot;{{ item }}&quot;
        groups: cloned_group
      with_items:
        - &quot;{{ clone_machine_1 }}&quot;
        - &quot;{{ clone_machine_2 }}&quot;
        - &quot;{{ clone_machine_3 }}&quot;
</code></pre>
<p>and the output takes the below pattern</p>
<pre><code>changed: [localhost] =&gt; (item=x.y.s) =&gt; {
    &quot;add_host&quot;: {
        &quot;groups&quot;: [
            &quot;cloned_group&quot;
        ],
        &quot;host_name&quot;: &quot;x.y.s&quot;,
        &quot;host_vars&quot;: {}
    },
    &quot;ansible_loop_var&quot;: &quot;item&quot;,
    &quot;changed&quot;: true,
    &quot;item&quot;: &quot;x.y.s&quot;
}
</code></pre>

<ansible>
How can I put some set of machines to a group in an ansible inventory dynamically using the add_host ansible module?
Kavisha Abeynayaka
# How can I put some set of machines to a group in an ansible inventory dynamically using the add_host ansible module?

(Asked by: username_0 on 2024-01-10)

I am trying to  dynamically populate an inventory group called cloned_group in my current inventory . I passed the hostnames through the survey by the following names clone_machine_1, clone_machine_2, clone_machine_3. I used the ansible module add_host.The tasks were executed successfully but I did not see the expected hostnames in my inventory.
---
- name: Stage source vm
  hosts: localhost
  gather_facts: false
  vars_files: 
    - common-vars.yml
  vars: 
    localusername: testlocal

  tasks:
    - name: Add host to the cloned group from the survey list 
      ansible.builtin.add_host:
        name: "{{ item }}"
        groups: cloned_group
      with_items:
        - "{{ clone_machine_1 }}"
        - "{{ clone_machine_2 }}"
        - "{{ clone_machine_3 }}"

and the output takes the below pattern
changed: [localhost] => (item=x.y.s) => {
    "add_host": {
        "groups": [
            "cloned_group"
        ],
        "host_name": "x.y.s",
        "host_vars": {}
    },
    "ansible_loop_var": "item",
    "changed": true,
    "item": "x.y.s"
}

**Tags:** ansible


---

## 1 answers

### Answer by username_1 on 2024-01-10. Score: 2

The add_host task works as expected. For example (simplified a bit), given the list of the groups
  my_groups: [cloned_group]

    - add_host:
        name: "{{ item }}"
        groups: "{{ my_groups }}"
      loop: [cm_1, cm_2, cm_3]

will create the inventory group cloned_group. Let's take a look
    - debug:
        var: groups.cloned_group

gives as expected
  groups.cloned_group:
  - cm_1
  - cm_2
  - cm_3

See the special variable group. Quoting:

A dictionary/map with all the groups in inventory and each group has the list of hosts that belong to it



Example of a complete playbook for testing
- hosts: localhost

  vars:

    my_groups: [cloned_group]

  tasks:

    - add_host:
        name: "{{ item }}"
        groups: "{{ my_groups }}"
      loop: [cm_1, cm_2, cm_3]

    - debug:
        var: groups.cloned_group



Q: "No hosts added to the cloned_group in the inventory."
A: If you by "in the inventory" mean "in the inventory file" then this is correct. No hosts will be added to an inventory file.
For example, given the below inventory file
shell> cat hosts
[test]
test_01
test_02
test_03

[test:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl

If you want to update the inventory file:

Get the path to the file. See the special variable ansible_inventory_sources. There might be more files in the list, hence take the first one

  my_file: "{{ ansible_inventory_sources.0 }}"

gives
  my_file: /scratch/tmp1/test-024/hosts


Create the block with your group(s)

  my_inventory: |
    {% for group in my_groups %}
    [{{ group }}]
    {% for host in groups[group] %}
    {{ host }}
    {% endfor %}
    {% endfor %}

gives
  my_inventory: |-
    [cloned_group]
    cm_1
    cm_2
    cm_3


Backup the inventory file

    - command:
        cmd: "cp {{ my_file }} {{ my_file }}.backup"
        creates: "{{ my_file }}.backup"


Update the inventory file

    - blockinfile:
        path: "{{ my_file }}"
        block: "{{ my_inventory }}"

gives what you (probably) want
shell> cat hosts
[test]
test_01
test_02
test_03

[test:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl
# BEGIN ANSIBLE MANAGED BLOCK
[cloned_group]
cm_1
cm_2
cm_3
# END ANSIBLE MANAGED BLOCK



Example of a complete playbook for testing
- hosts: localhost

  vars:

    my_file: "{{ ansible_inventory_sources.0 }}"
    my_groups: [cloned_group]
    my_inventory: |
      {% for group in my_groups %}
      [{{ group }}]
      {% for host in groups[group] %}
      {{ host }}
      {% endfor %}
      {% endfor %}

  tasks:

    - add_host:
        name: "{{ item }}"
        groups: "{{ my_groups }}"
      loop: [cm_1, cm_2, cm_3]

    - debug:
        var: groups.cloned_group

    - debug:
        var: ansible_inventory_sources
    - debug:
        var: my_file
    - debug:
        var: my_inventory

    - command:
        cmd: "cp {{ my_file }} {{ my_file }}.backup"
        creates: "{{ my_file }}.backup"

    - blockinfile:
        path: "{{ my_file }}"
        block: "{{ my_inventory }}"

> **Comments:**
> **username_0**: it gives me the same output but still no hosts added to the  cloned_group in the inventory .what does this output indicates ?  
> **username_1**: The module *add_host* does not change the inventory file. The module will "Add a host (and alternatively a group) to the ansible-playbook in-memory inventory". The hosts are added to the inventory "for use in later plays of the same playbook". These hosts and the groups are not in the inventory anymore after the playbook terminates.  
> **username_1**: I added an example of how to update the inventory file.  
> **username_0**: Can I  run the necessary steps to clone the a vm after updating the inventory  like above in the same playbook  

---

