# Rewriting the inventory file using ranges

**URL:** <https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969>\
**Category:** Get Help\
**Tags:** playbook\
**Created:** [July 2, 2024, 12:44pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969 "2024-07-02T12:44:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![badnetmask](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/badnetmask/32/2763_2.png) [@badnetmask](https://forum.ansible.com/u/badnetmask)\
**Post date:** [July 2, 2024, 12:44pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/1 "2024-07-02T12:44:15Z")

</div>

Hi folks,

I would like to figure out a way to rewrite my inventory file after processing. In theory it shouldn’t be hard to simply dump the ansible\_play\_hosts\_all variable, but it won’t produce the results I need.

Consider this inventory file:

```auto
[group_a]
host0[10:50].example.com
[group_a:vars]
this=that
[group_b]
host0[60:90].example.com

```

I want do be able to load this inventory, do the needful, figure out which hosts to exclude, then write the inventory file back. So the end result should be something like that:

```auto
[group_a]
host0[10:21].example.com
host0[29:35].example.com
host0[37:50].example.com
[group_a:vars]
this=that
[group_b]
host0[60:80].example.com

```

The problem with simply dumping ansible\_play\_hosts\_all is that it will miss the file formatting, specially in what regards to the numbers ranges.

Is there a smart way to do that, other that writing a bunch of custom Python? (I’m fine if the inventory needs to be converted to YAML as well.)

---

<div class="post-metadata">

**Author:** ![mikemorency](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mikemorency/32/2672_2.png) [@mikemorency](https://forum.ansible.com/u/mikemorency)\
**Post date:** [July 2, 2024, 1:25pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/2 "2024-07-02T13:25:10Z")

</div>

Ive done this before, but it involved writing custom python. Im not sure theres an existing “thing” out there to do this.

`ansible-inventory -i <inventory> --yaml --export --list` will give you a decompressed yaml inventory. That would be helpful, but passing the hosts in and maintaining group membership might be challenging. Plus decompressed inventories can get long

You could also consider moving the group variables out to dedicated `group_vars/` files so you only need to worry about hosts instead of hosts + vars

---

<div class="post-metadata">

**Author:** ![badnetmask](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/badnetmask/32/2763_2.png) [@badnetmask](https://forum.ansible.com/u/badnetmask)\
**Post date:** [July 2, 2024, 1:38pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/3 "2024-07-02T13:38:40Z")

</div>

Yes, moving the variables to different files did cross my mind, but keeping up with the host list is the challenging part. I’m really trying to not use decompressed host lists.

You showed how you got your decompressed inventory, but did you figure out how to “compress” it back?

---

<div class="post-metadata">

**Author:** ![mikemorency](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mikemorency/32/2672_2.png) [@mikemorency](https://forum.ansible.com/u/mikemorency)\
**Post date:** [July 2, 2024, 2:03pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/4 "2024-07-02T14:03:02Z")

</div>

ive been messing with a playbook. This works, but i think theres room for improvement

```auto
- hosts: all
  gather_facts: false
  tasks:
    - command: ansible-inventory -i {{ inventory_file }} --export --list
      register: _old_inventory_output
      run_once: true
      delegate_to: localhost

    # assuming you do something to change the host list here.
    # im just filtering out hosts in group_a without 2 in the name
    - set_fact:
        _old_inventory: "{{ _old_inventory_output.stdout | from_json }}"
      run_once: true
      delegate_to: localhost
    - set_fact:
        _new_group_a: >-
          {{ _old_inventory['group_a']['hosts'] |
          map('regex_search', '.*\d+2.*') | select('string') |
          zip_longest([], fillvalue={}) | community.general.dict
          }}
        _new_group_b: >-
          {{ _old_inventory['group_b']['hosts'] |
          zip_longest([], fillvalue={}) | community.general.dict
          }}
      run_once: true
      delegate_to: localhost

    # merge the new hosts into a new inventory
    - set_fact:
        _new_inventory:
          all:
            children:
              group_a: {hosts: "{{ _new_group_a }}"}
              group_b: {hosts: "{{ _new_group_b }}"}

      run_once: true
      delegate_to: localhost

    # write out and load the new inventory
    - copy:
        dest: /tmp/new_inv
        content: "{{ _new_inventory | to_nice_yaml }}"
      run_once: true
      delegate_to: localhost
    - command: ansible-inventory -i /tmp/new_inv --export --list
      register: _new_inventory_output
      run_once: true
      delegate_to: localhost
    - debug:
        var: _new_inventory_output.stdout | from_json
      run_once: true
      delegate_to: localhost

```

---

<div class="post-metadata">

**Author:** ![mikemorency](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mikemorency/32/2672_2.png) [@mikemorency](https://forum.ansible.com/u/mikemorency)\
**Post date:** [July 2, 2024, 2:03pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/5 "2024-07-02T14:03:40Z")

</div>

> [@badnetmask](#):
>
> You showed how you got your decompressed inventory, but did you figure out how to “compress” it back?

That is the part that Im not sure how to do

---

<div class="post-metadata">

**Author:** ![Denney-tech](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/denney-tech/32/1556_2.png) [@Denney-tech](https://forum.ansible.com/u/Denney-tech)\
**Post date:** [July 2, 2024, 7:00pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/6 "2024-07-02T19:00:18Z")

</div>

While there’s probably a way to do this, it’s going to be very messy any way you do it.

I would rather ask instead, that if you have so many hosts in such a large range, where do your hosts live? Presumably, they are VM’s running on a enterprise grade virtualization cluster, or on a cloud solution. They might also be part of a management system of some sort. Even if it isn’t “enterprise grade”, if any of these things are true, there’s probably a much easier and more reliable way to dynamically source these hosts and construct their groups ahead of time instead of processing them after the fact.

---

<div class="post-metadata">

**Author:** ![badnetmask](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/badnetmask/32/2763_2.png) [@badnetmask](https://forum.ansible.com/u/badnetmask)\
**Post date:** [July 2, 2024, 7:26pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/7 "2024-07-02T19:26:50Z")

</div>

Sure, I know I could use some kind of dynamic inventory, but that’'s when the hosts already exist. In a situation that I need to regularly provision and de-provision them, I need the hostnames (and the build variables) in a static place, not in a provider API.

---

<div class="post-metadata">

**Author:** ![Denney-tech](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/denney-tech/32/1556_2.png) [@Denney-tech](https://forum.ansible.com/u/Denney-tech)\
**Post date:** [July 2, 2024, 8:01pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/8 "2024-07-02T20:01:19Z")

</div>

Even when the host _doesn’t_ exist in a dynamic inventory, that doesn’t mean it can’t be provisioned dynamically. And the variables you need can still be static and assigned programmatically to the dynamic sources.

That said, if you really want a “static” generated list, you might consider using the [ansible.builtin.script](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/script_inventory.html#script-inventory) inventory plugin. This would let you generate your static inventory in whatever way you wish.

---

<div class="post-metadata">

**Author:** ![badnetmask](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/badnetmask/32/2763_2.png) [@badnetmask](https://forum.ansible.com/u/badnetmask)\
**Post date:** [July 2, 2024, 9:00pm UTC](https://forum.ansible.com/t/rewriting-the-inventory-file-using-ranges/6969/9 "2024-07-02T21:00:57Z")

</div>

The script module is what I am trying to avoid. I wanted something that is “Ansible native”, instead of writing my own.

If there isn’t one, maybe I need to re-think the overall project.

Thanks.
