Filtering_data manipulation

While collecting the inventory from a dynamic source , I am able to filter the hostname and print them as below as expected.

servera
serverb
serverc
serverd

when set to facts with set_fact also fine and print in the order one below the other.
However when I try to write into a file with copy module ,

  • name: Write to the file
    ansible.builtin.copy:
    content: “{{ result[‘json’][‘value’] |map(attribute=‘hostname’) }}”
    dest: “{{my_inv}}”

the format collapses as below.

‘servera’, ‘serverb’, ‘serverc’, ‘serverd’

How can I write the output in the list format(line by line) as this file will be used to read as an inventory for other tasks .

What does your “result” look like?

it looks like
‘servera’, ‘serverb’, ‘serverc’, ‘serverd’

and I want result to be like …
$cat /tmp/my_inv
servera
serverb
serverc
serverd

I mean, what does the output of

  • name: Dump result
    ansible.builtin.debug:
    msg: “{{ result }}”

look like? It presumably has a ‘json’ field? Which itself contains a ‘value’?
Without a reasonable approximation of your input, I can’t possibly suggest how to create expected output from it.

Here it is

TASK [debug] **************************************************************************************************************************
ok: [localhost] => {
“msg”: [
“servera”,
“serverb”,
“serverc”,
“serverd”,
“centos8-latest”
]
}

TASK [debug] **************************************************************************************************************************
ok: [localhost] => {
“msg”: “The List of VMs is [‘servera’, ‘serverb’, ‘serverc’, ‘serverd’, ‘centos8-latest’]”
}

TASK [write the server list to the file /tmp/output.txt] ******************************************************************************
ok: [localhost]

PLAY RECAP ****************************************************************************************************************************
localhost : ok=9 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

$ cat /tmp/output.txt
[“servera”, “serverb”, “serverc”, “serverd”, “centos8-latest”]

Use template module


---
- hosts: localhost
gather_facts: no
vars:
servers:
- servera
- serverb
- serverc
tasks:
- template:
src: server.j2
dest: output.txt

server.j2

{% for server in servers %}
{{ server }}
{% endfor %}

cat output.txt

servera
serverb
serverc

Yes. Or if you feel like ignoring the warnings* about using variables in copy’s “content”:

    - name: Write to the file 
      ansible.builtin.copy:
        content: |
          {% for server in servers %}
          {{ server }}
          {% endfor %}
        dest: "{{my_inv}}" 

* I do it quite often, looking for cases where the promised unexpected surprises happen, but I haven’t found them yet. It’ll probably happen some day when it least convenient. :slight_smile:

Hi,

Yes. Or if you feel like ignoring the warnings^* about using
variables in copy's "content":

 \- name: Write to the file
   ansible\.builtin\.copy:
     content: |

           {% for server in servers %}
           {{ server }}
           {% endfor %}
dest: "{{my_inv}}"

^* I do it quite often, looking for cases where the promised
unexpected surprises happen, but I haven't found them yet. It'll
probably happen some day when it least convenient. :slight_smile:

I got bitten by this somewhen in the past when the input for `content`
turned out to be valid JSON. Ansible parsed it and converted it to the
Python representation of the dictionary, which wasn't valid JSON
anymore (`"` converted to `'`).

But that's something rather special, for many simple templates such as
yours it's no problem at all (and I also use `content` for that).

Cheers,
Felix

Thanks all …
I am able to get the desired output with templates …