The replace
module by default replaces all occurances of the regexp
found in path
. Quoting from official documentation:
- This module will replace all instances of a pattern within a file.
- It is up to the user to maintain idempotence by ensuring that the same pattern would never match any replacements made.
To limit this, we can use before
and after
.
Now my interpretation of this:
While the documentation doesn’t say anything about whether before
and after
are references in the same line or n lines above and below. In my opinion, for replace
to work reliably the before
and after
expressions should be on the same line.
We can demonstrate this with below example:
Let’s consider a sample.txt
with below contents:
ruby ansible chef
foo ansible baz
python ansible saltstack
Now let’s say I wanted to change ansible
to bar
only on the line foo ansible baz
, then I would have a task like:
- replace:
path: "sample.txt"
regexp: "ansible"
replace: "bar"
after: "foo"
before: "baz"
Now when we run this task:
ruby ansible chef
-foo ansible baz
+foo bar baz
python ansible saltstack
Also there is a bug in Ansible replace mentioned in the Notes And this affects versions lower than 2.7.10.
- As of Ansible 2.7.10, the combined use of before and after works properly. If you were relying on the previous incorrect behavior, you may be need to adjust your tasks. See https://github.com/ansible/ansible/issues/31354 for details.
Now the solution
As I commented on the question, there are better options to achieve your objective. Apart from the lineinfile module, you can use the ini_file module:
- ini_file:
path: '/path/to/grafana_config_template.ini'
section: "server"
option: "{{ item.opt }}"
value: "{{ item.val }}"
with_items:
- { opt: "domain", val: "foo" }
- { opt: "enforced_domain", val: "true" }
CLICK HERE to find out more related problems solutions.