TransWikia.com

Ansible - copying and editing a remote file at the same time?

Server Fault Asked by Kevin Keane on November 4, 2021

In an Ansible role, I’m looking for a way to copy a remote file to a different location, while also replacing the first two lines of the file.

I’m open to other approaches, but my solution involves using slurp to retrieve the file, somehow convert it into a list of individual lines, and then write it back using a template.

I’m stuck at the step of splitting the string returned by slurp into lines.

Ansible 2.9, both the controller and the remote hosts are running RHEL 7.8.

The input file is already on the remote host as /etc/sample/inputfile.txt

Line1 something
Line2 something
Line3 stays untouched
Line4 stays untouched

Desired output in /etc/sample/outputfile.txt

Line1 has changed
Line2 has also changed
Line3 stays untouched
Line4 stays untouched

The effect I want to replicate is what the following sequence would produce, but idempotently without making three changes to outputfile.txt on every run.

- copy:
    src: /etc/sample/inputfile.txt
    dest: /etc/sample/outputfile.txt
    remote_src: True

- lineinfile:
    path: /etc/sample/outputfile.txt
    regexp: '^Line1'
    line: 'Line1 has changed'

- lineinfile:
    path: /etc/sample/outputfile.txt
    regexp: '^Line2'
    line: 'Line2 has also changed'

To make this idempotent, my current idea is to use slurp to retrieve inputfile.txt, then (somehow) strip the first two lines of that variable, and create outputfile.txt using a template.

- slurp:
    src: /etc/sample/inputfile.txt
  register: r_input
- set_fact:
    intermediate_var: '{{ r_input.content | b64decode }}'
- ??? How would I convert intermediate_var into a list of lines?
- template:
  vars:
    line1: 'Line1 has changed'
    line2: 'Line2 has also changed'
    body:  '??? intermediate_var without the first two lines'

However, I haven’t figured out a way to strip the first two lines off the slurped variable. I’m aware of the lookup plugin "lines" but have not figured out how to apply it in this scenario.

One Answer

The answer turned out to be easier than I thought.

- name: Retrieve service.txt file
  become: True
  shell: "cat /etc/sample/inputfile.txt"
  register: r_inputfile
  changed_when: False

This will give me the file nicely split in lines in the r_inputfile.stdout_lines variable.

I'm still looking for an improvement because I try to avoid the shell module when possible.

Answered by Kevin Keane on November 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP