I'm using a win_lineinfile module and trying to use manual newline characters. It works just fine if the line argument of the module is only on one line but the moment I use multiline it breaks.
I'm trying to do this
- name: Something
win_lineinfile:
path: some_path
line: |
firstline\r\n
secondline
but it doesn't work.
This does but I lose the ability of using multiline string.
- name: Something
win_lineinfile:
path: some_path
line: firstline\r\nsecondline
Related
The yaml file is like this:
settings:
clusterName: dev
dbServer: test.db.com
dcsHostName: dev
overrideDevRepo: "true"
globalSuspend: "true"
sharedConfig: "true"
I want to pass globalSuspend as a toggle variable, update true to false or false to true, but as helm need the quote, so quote are needed, also yaml is format sensitive, the leading spaces must be kept as same. Need a way to do it saltstack simple cmd.run or state playbook. Or at least please help on how to do in bash. But I find my command works in bash does not work in saltstack as : colon is a trouble in salt. thanks.
"toggle the suspend value":
cmd.run:
- name: sed -i '/globalSuspend/!b;c \ \ globalSuspend: "{{suspend}}"' settings.yaml
- runas: vagrant
The above does not work because of the colon and also does not keep the leading spaces.
Colon is a special character in YAML. Use a literal block scalar to treat everything as content:
"toggle the suspend value":
cmd.run:
- name: |-
sed -i '/globalSuspend/!b;c \ \ globalSuspend: "{{suspend}}"' settings.yaml
- runas: vagrant
| starts a literal block scalar. Each following line that is more indented is part of the scalar. The - means that the final line break is not part of the scalar (wich it would otherwise be).
The simplest way to do this is with a file.serialize state.
toggle the suspend value:
file.serialize:
- name: settings.yaml
- dataset:
settings:
globalSuspend: "{{ suspend }}"
- serializer: yaml
- merge_if_exists: true
More specific states are always preferred to a generic cmd.run, as they are state-aware and more efficient to run.
Very difficult to understand ansible behavior. I'm trying to edit my /etc/postfix/master.cf file to turn on the submission block.
I copied the file to /tmp as I'm working on it, so my simple Ansible playbook should be:
- name: Edit the master.cf file
replace:
path: /tmp/master.cf
after: '^#tlsproxy'
before: '^#smtps'
regexp: '^#(.*)$'
replace: '\1'
But this doesn't work. It does work if I make one change, which is taking out the caret ^ in the before and after fields. This makes ... no sense to me at all. What makes even less sense, if I use:
after: '^#'
amazingly, it will do what I expect and uncomment all the lines after the first commented line.
But:
after: '^#t'
suddenly stops matching anything. I've read the Python page on regex and yet I'm baffled by this.
Any ideas? The playbook will work fine without the carets but I want to do this really correctly and match exactly what I want to match.
Thanks!
Ansible's replace module: uses DOTALL, which means the . special character can match newlines.
When you specify after: '^#tlsproxy', that caret is really saying: 'from the beginning of the search string, immediately followed by #tlsproxy', where the caret effectively means from the beginning of the file.
Ansible tries to match this:
"Pattern for before/after params did not match the given file: ^#tlsproxy(?P<subsection>.*?)^#smtps"
With re.DOTALL, if you want to match the patterns from the beginning of a line, use a newline character instead:
- name: Edit the master.cf file
replace:
path: master.cf
after: '\n#tlsproxy'
before: '\n#smtps'
regexp: '^#(.*)$'
replace: '\1'
I'm running an ansible playbook that allows me to (or should allow me to) replace two lines in a configuration file for a remote server. Most of the file replacements are dictionary style entries where neither the key nor the value have quotes. But there is one replacement where the name needs to be quoted. Here is the task from the ansible playbook:
- name: Enable traefikExporter within vars.jsonnet configuration file.
ansible.builtin.replace:
path: /home/bill/cluster-monitoring/vars.jsonnet
regexp: "name: 'traefikExporter',[\n\r].*[\n\r]"
replace: |6
name: 'traefikExporter',
enabled: true,
The error thrown is:
The offending line appears to be
replace: |6
name: 'traefikExporter'
^ here
and it notes that it is a mismatched quote. But I've tried changing the yaml replace parameter to > and using \n for line breaks on a single line as well as the | with quoted lines. They all throw versions of the mismatched quote error.
For reference, the following task, which is immediately above this task, runs correctly without errors:
- name: Enable k3s Monitoring within vars.jsonnet configuration file.
ansible.builtin.replace:
path: /home/bill/cluster-monitoring/vars.jsonnet
regexp: "\ k3s: {[^}]*},"
replace: |2
k3s: {
enabled: true,
master_ip: ['192.168.2.139'],
},
The closest thing I could find is here, but this didn't work. In both cases the regexp covers multiple lines and the replace covers the same lines identified by the regexp. What am I missing?
update
I also tried replacing the replacement text and now believe that the actual formatting issue is in the regexp: "name: 'traefikExporter',[\n\r].*[\n\r]" line. No matter what I place in the replace line it throws the error. I think the quotes in the regexp are the issue.
work around
I came up with a work around but it still isn't right. The following is very close to what I'd like - but a bit frustrated that it isn't exactly what I expected:
- name: Enable traefikExporter within vars.jsonnet configuration file.
ansible.builtin.replace:
path: /home/bill/cluster-monitoring/vars.jsonnet
regexp: "name: 'traefikExporter',[\n\r].*"
replace: >4
name: 'traefikExporter',
enabled: true,
The |6 or >6 was the problem - but not sure why. My expected behavior was to have a 6 space indent. But this is the thing throwing the error. When I put it to 4 there is no quote error. But as you can see - to get the formatting right I have to do some weird spacing (the name: is the correct indentation with the 4, but I have to add 6 actual spaces to get the next line to align. Not part of this question - but neither the | nor the > seems to impact the trailing return in both cases there is an extra line after the replacement.
YAML processes escape sequences in double-quoted scalars, so you should use
regexp: "name: 'traefikExporter',[\\n\\r].*[\\n\\r]"
I suggest however to use a block scalar to avoid escaping hell:
regexp: >-
name: 'traefikExporter',[\n\r].*[\n\r]
Regarding the indentation indicator, this cannot work:
replace: |6
name: 'traefikExporter',
enabled: true,
You are basically saying „the following block scalar has 6 spaces indentation in addition to the indentation of the replace: key“. However, it only has two, which makes the YAML parser immediately drop out of block scalar parsing mode. The following error results from the YAML parser trying to interpret what you intend to be the block scalar's content as part of the YAML structure.
I suggest doing:
replace: |-2
name: 'traefikExporter',
enabled: true,
to give the block scalar 2 space in front of each line (which seems to be what you want) and also to remove the trailing newline (with the -).
I'm trying to add value to a line and getting odd results.
Original line (may change value):
SomeParam=test
Code:
- name: Add info
win_lineinfile:
path: file_path
backrefs: yes
regexp: '(SomeParam=*)'
line: '\1,added info'
Result:
\1,added info
Expected result:
SomeParam=test,added info
There are two issues here.
Firstly, in the Windows version of lineinfile (i.e. win_lineinfile), you need to use $1 instead of \1 as a back reference.
Secondly, your regular expression should be (SomeParam=.*) and not (SomeParam=*) -- the latter will match SomeParam followed by zero or more = signs, whereas the former will match SomeParam= followed by zero or more characters.
Taking into consideration the above, try the following:
- name: Add info
win_lineinfile:
path: file_path
backrefs: yes
regexp: '(SomeParam=.*)'
line: '$1,added info'
While trying to install apache via ansible I am getting the error of libToolt hence my apr-util is not getting configured. I am trying to replace $RM "cfgfile" with $RM -f "cfgfile" in configure by using regexp it is either getting copied at the last or not working.
- name: Replace file
path: file path
regexp: '$RM -f "cfgfile"'
But the value that is going when I am trying to run my YAML file is
$RM\\\"$cfgfile\"
You must escape the $ in your regexp since that character is meaningful to regexp; or, skip the silliness and just use line: instead of regexp: since your text does not contain any variable parts (which is the circumstances under which one would use a regex)