tom_nb_ny
tom_nb_ny

Reputation: 180

Performing multiple ansible.builtin.blockinfile tasks on the same file?

I have found that if you have multiple ansible.builtin.blockinfile tasks for a single file, the last blockinfile task will overwrite the contents of a single # BEGIN ANSIBLE MANAGED BLOCK {mark} # END ANSIBLE MANAGED BLOCK. I was expecting it to work like lineinfile, which can perform multiple replacements in multiple areas of a file.

Is there a way around this?

Initial file:

ini.foo=bar

ini.bar=foo

Task file:

- blockinfile:
   path: /my/file
   block: |
    block1
    block1
    block1
   insertbefore: '^ini.foo=bar'

- blockinfile:
   path: /my/file
   block: |
    block2
    block2
    block2
   insertbefore: '^ini.bar=foo'

Expected result:

# BEGIN ANSIBLE MANAGED BLOCK
    block1
    block1
    block1
# END ANSIBLE MANAGED BLOCK
ini.foo=bar

# BEGIN ANSIBLE MANAGED BLOCK
    block2
    block2
    block2
# END ANSIBLE MANAGED BLOCK
ini.bar=foo

Actual result:

# BEGIN ANSIBLE MANAGED BLOCK
    block2
    block2
    block2
# END ANSIBLE MANAGED BLOCK
ini.foo=bar

ini.bar=foo

Note how the second task replaces the content of the first replacement, and doesn't respect its own insertbefore parameter.

Any help appreciated.

Upvotes: 6

Views: 3788

Answers (1)

amir hashemi
amir hashemi

Reputation: 71

You can use marker to separate block messages. Your code should be something like this:

- blockinfile:
   path: /my/file
   marker: "# {mark} block1"
   block: |
    block1
    block1
    block1
   insertbefore: '^ini.foo=bar'

- blockinfile:
   path: /my/file
   marker: "# {mark} block2"
   block: |
    block2
    block2
    block2
   insertbefore: '^ini.bar=foo'

Note: The marker should be a comment line. Based on the question, a ‘#’ is required in the marker string.

Upvotes: 7

Related Questions