user4889345
user4889345

Reputation:

Ansible - Write multiple line output to file

I am using ansible to gather information from remote nodes and will then use this information to update relevant RPMs.

The issue I am having is collection version number of various applications and writing them to a file.

Playbook:

---
  - name: Check Application Versions
    hosts: kubernetes
    tasks:
       - name: Check K8S version.
         shell: kubectl --version
         register: k8s_version

       - debug: msg="{{ k8s_version.stdout }}"

Inventory file:

[kubernetes]
172.29.219.102 
172.29.219.105 
172.29.219.104 
172.29.219.103 

Output:

TASK [debug] *******************************************************************
ok: [172.29.219.102] => {
    "msg": "Kubernetes v1.4.0"
}
ok: [172.29.219.103] => {
    "msg": "Kubernetes v1.4.0"
}
ok: [172.29.219.105] => {
    "msg": "Kubernetes v1.4.0"
}
ok: [172.29.219.104] => {
    "msg": "Kubernetes v1.4.0"
}

The above portion is simple and works. Now I want to write the output to file.

Now im trying to write this information to a file.I want something like:

Kubernetes v1.4.0 Kubernetes v1.4.0 Kubernetes v1.4.0 Kubernetes v1.4.0

So I added the below line:

- local_action: copy content={{ k8s_version.stdout_lines }} dest=/tmp/test

My /tmp/test looks like :

# cat /tmp/test 
["Kubernetes v1.4.0"]

There is only one value here.

I tried to do something different then.

- local_action: lineinfile dest=/tmp/foo line="{{ k8s_version.stdout }}" insertafter=EOF

This resulted in:

# cat  /tmp/foo 
Kubernetes v1.4.0

Im trying to figure out why I only see one value whereas I should see the versions of every node in my inventory file. What am I doing wrong?

Upvotes: 5

Views: 29747

Answers (2)

techraf
techraf

Reputation: 68459

What am I doing wrong ?

lineinfile module does not perform the action "add a line to a file", instead it ensures a given line is present in the file. If all your target nodes have the same version, it won't add the same line multiple times.

On the other hand, copy module was overwriting the file.


If you need to register values for all hosts, you can for example create a template which will loop over hosts in the kubernetes group:

- copy:
    content: "{% for host in groups.kubernetes %}{{ hostvars[host].k8s_version }}\n{% endfor %}"
    dest: /tmp/test
  delegate_to: localhost
  run_once: true

Another way would be to extract the values with map from hostvars, but given you want the values from kubernetes host group only, I'm not sure it would be prettier. And having a for in the template allows you to easily add host names.

Upvotes: 6

ProfHase85
ProfHase85

Reputation: 12173

According to this post

Ansible register result of multiple commands

your desired variable is in k8s_version.results To access it you need to work with a template where you just iterate over it:

- local_action: template src=my_nodes.j2 dest=/tmp/test

And the template templates/my_nodes.j2 :

 {% for res in k8s_version.results %}
     {{ res.stdout }}
 {% endfor %}

The complete playbook would then be:

---
  - name: Check Application Versions
    hosts: kubernetes
    tasks:
       - name: Check K8S version.
         shell: kubectl --version
         register: k8s_version

       - local_action: template src=my_nodes.j2 dest=/tmp/test

Upvotes: 3

Related Questions