ANSIBLE: how to append a string at the end of a file

Hi ,

I am trying to use ansible as a test tool. at the end of each sucess/faiure i want to append a string at the end of a file and this file can be used as a test report.
i Have tried this code but it did not log anything in the file.

- debug: msg="HPQC Create snapshot of a vGPU VM on ESX"
  when: taskresult|succeeded
- debug: msg="HPQC Failed Create snapshot of a vGPU VM on ESX"
  when: taskresult|failed

- shell: echo "HPQC Passed Create snapshot of a vGPU VM on ESX" >> results.txt
  when: taskresult|succeeded
- shell: echo "HPQC Failed Create snapshot of a vGPU VM on ESX" >> results.txt
  when: taskresult|failed

  when i run with -vvvv switch, I get the following output but nothing is appended in the file locataed at /etc/ansible/ directoery( I am running playbook from /etc/ansible directory)

 
changed: [] => {
    "changed": true, 
    "cmd": "echo \"HPQC Passed Create snapshot of a vGPU VM on ESX\" >> results.txt", 
    "delta": "0:00:00.017046", 
    "end": "2017-07-27 00:07:14.100974", 
    "invocation": {
        "module_args": {
            "_raw_params": "echo \"HPQC Passed Create snapshot of a vGPU VM on ESX\" >> results.txt", 
            "_uses_shell": true, 
            "chdir": null, 
            "creates": null, 
            "executable": null, 
            "removes": null, 
            "warn": true
        }
    }, 
    "rc": 0, 
    "start": "2017-07-27 00:07:14.083928", 
    "stderr": "", 
    "stderr_lines": [], 
    "stdout": "", 
    "stdout_lines": []
}

TASK [ESX_VM_SnapRestore : command] ************************************************************************************************************************************************************************
task path: /etc/ansible/roles/ESX_VM_SnapRestore/tasks/main.yml:41
skipping: [1] => {
    "changed": false, 
    "skip_reason": "Conditional result was False", 
    "skipped": true
}

Thanks for your help.

-VM

Hi,

You should use the line in file module, only specify the path and line. This way it will append it to the file.

   I am trying to use ansible as a test tool. at the end of each
sucess/faiure i want to append a string at the end of a file and this file
can be used as a test report.
i Have tried this code but it did not log anything in the file.

- debug: msg="HPQC Create snapshot of a vGPU VM on ESX"
  when: taskresult|succeeded
- debug: msg="HPQC Failed Create snapshot of a vGPU VM on ESX"
  when: taskresult|failed

Debug only writes to the stdout so you only get those on screen.

- shell: echo "HPQC Passed Create snapshot of a vGPU VM on ESX" >> results.txt
  when: taskresult|succeeded
- shell: echo "HPQC Failed Create snapshot of a vGPU VM on ESX" >> results.txt
  when: taskresult|failed

This will store the text in the file results.txt on the remote host, not on the host you are running ansible playbook on.
To write to a file on localhost you need to add delegate_to: localhost

The problem occur if you run against more than one host, you'll have several processes trying to write to the same file at once, this is very error prone.
One solution to overcome that is run_once with a loop.

   - shell: echo "HPQC {{ (hostvars[item].result | succeeded) | ternary('Passed', 'Failed') }} Create snapshot of a vGPU VM on ESX" >>results.txt
     with_items: "{{ ansible_play_hosts }}"
     delegate_to: localhost
     run_once: yes

“I am trying to use ansible as a test tool. at the end of each sucess/faiure i want to append a string at the end of a file and this file can be used as a test report.
i Have tried this code but it did not log anything in the file.”

This sounds like a good use for a callback plugin. A custom callback plugin could append to a file on _ok/_fail callbacks.

I would base it around the python ‘logging’ module, but it could be something simpler.

The ‘junit’ callback might be a good example and could possibly be used directly if a junit.xml file is useful for your test tool.

Thanks kai !

Yes, I don’t know how i missed the localhost part after adding “delegateTo: localhost” I am able to append the line on each test case success/failure.
One more thing i wanted to clarify nomatter what command i se for appending the line( command/sheel/lineinfile) it always fails and outpus sudo; A password is required.
am i missing something>

I have my playbook that contained one role and i declared “become: true” before the role as below

//vcenter_snaprestore.yml

- hosts: esx1
  become: true
  roles:
     - ESX_VM_SnapRestore

Thanks Rick for your help !
I am using lineinfile now and it works partially, only thing is it fails initially and outputs Sudo: a password requied". if i give permission through cmod 777 results.txt and then try to run the playbook it passes.

- lineinfile:
    path: /etc/ansible/results.txt
    line: 'HPQC1 Passed Create snapshot of a vGPU VM on ESX'
    insertafter: EOF
  when: taskresult|succeeded
  delegate_to: localhost

vcenter_snaprestore.yml
***********************************************

- hosts: esx1
  become: true
  roles:
     - ESX_VM_SnapRestore
**********************************

vmisra@ubuntu:/etc/ansible$ ansible-playbook vcenter_snaprestore.yml

Do you see any reason for sudo: a Password required error message.

Thanks,
Vijay

Thanks Adrian ! I would try using callback plugin.

-Vijay

One more thing i wanted to clarify nomatter what command i se for appending
the line( command/sheel/lineinfile) it always fails and outpus sudo; A
password is required.
am i missing something>

You have become: true in your play, so you need to provide a password if do not have passwordless sudo.
become: true on the play means all task will runs with become.

Do esx have sudo?
My installation do not have sudo.

Since your delegate_to: run on a different host it will a problem if the remote host and the localhost does not have the same password.
But in you case the lineinfile does not need sudo i guess so you can set become: false on that task.

- hosts: esx1
  become: true
  roles:
     - ESX_VM_SnapRestore

**********************************************

- lineinfile:
    path: /etc/ansible/results.txt
    line: 'HPQC Passed Create snapshot of a vGPU VM on ESX'
    insertafter: EOF
  when: taskresult|succeeded
  delegate_to: localhost

By the way, when you use lineinfile it will not append to EOF if the text in line: already exist somewhere in the file.

Vijay Misra [28.07.2017 01:23]:

Thanks Rick for your help !
I am using lineinfile now and it works partially, only thing is it fails
initially and outputs Sudo: a password requied".

How does the corresponding line look like in /etc/sudoers? There must be
a "NOPASSWD:" as in

nagios ALL=(ALL) NOPASSWD: /usr/local/bin/dosomething.sh

Thanks kai ! setting become: false worked.

-VM