Search code examples
ansibleansible-template

Ansible blockinfile replace everything except a block


I am trying to replace everything except a special block using Ansible blockinfile. It would be safe to assume that this special block to be at the beginning of the file.

File content before ansible run:

# BEGIN SPECIAL
blah
# END OF SPECIAL
... bunch of configs

Expected file content after ansible run:

# BEGIN SPECIAL
blah
# END OF SPECIAL
[MY REPLACED CONFIGS]

There are two problems with using blockinfile marker.

  1. marker_start and marker_end do not support regex
  2. Cannot specify EOF as marker_end

My ansible task:

- name: testing replacing file
  blockinfile:
    path: /tmp/testfile
    marker: "{mark}"
    marker_begin: "# END OF SPECIAL" 
    marker_end: EOF
    block: "[MY REPLACED CONFIGS]"
    state: present

This does not seem to do the trick. Is there a way to achieve this with blockinfile?


Solution

  • Q: "Is there a way to achieve this with blockinfile?"

    A: No. The module blockinfile can't change content outside the block. Instead, a simple template would do the job. For example, given the variables

        begin: "# BEGIN SPECIAL"
        end: "# END OF SPECIAL"
        block2: "[MY REPLACED CONFIGS]"
    

    Read the block

        - command: "sed -n '/{{ begin }}/,/{{ end }}/p' tmp/testfile"
          register: result
        - set_fact:
            block1: "{{ result.stdout_lines[1:-1]|join('\n') }}"
    

    gives

      block1: blah
    

    Now, put all elements together

        - copy:
            dest: tmp/testfile
            content: |
              {{ begin }}
              {{ block1 }}
              {{ end }}
              {{ block2 }}
    

    gives

    shell> cat tmp/testfile
    # BEGIN SPECIAL
    blah
    # END OF SPECIAL
    [MY REPLACED CONFIGS]