I'm new to Ansible and trying to modify a line in /etc/default/grub to enable auditing.
I need to add audit=1 within the quotes somewhere on a line that looks like:
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet net.ifnames=0"
So far I've managed to delete the line and am only left with
net.ifnames=0, audit=1
when I use something like
lineinfile:
state: present
dest: /etc/default/grub
backrefs: yes
regexp: "net.ifnames=0"
line: "\1 audit=1"
Can this be done?
You may try this:
- lineinfile:
state: present
dest: /etc/default/grub
backrefs: yes
regexp: '^(GRUB_CMDLINE_LINUX=(?!.* audit)\"[^\"]+)(\".*)'
line: '\1 audit=1\2'
This will add audit=1 (with a leading space) just before closing double quote. It will not match without double quotes.
And it tries to be idempotent: doesn't match lines that already have audit (with a leading space) after GRUB_CMDLINE_LINUX=.
I'd recommend to use sites like regex101 to test your regular expressions first (there's also a substitution mode there).
When you're satisfied with the result, proceed with the Ansible task.
I wanted to make sure the parameter is also set to the correct value, so I used this replace invocation:
replace:
path: /etc/default/grub
regexp: '^(GRUB_CMDLINE_LINUX=(?:(?![" ]{{ option | regex_escape }}=).)*"?)\s*(?:{{ option | regex_escape }}=\S+\s*)?(.*")$'
replace: '\1 {{ option }}={{ value }}\2'
vars:
option: audit
value: 1
This works if the option wasn't present previously, if it was but had the wrong option (only changes the value then) and if the whole string was empty (but adds a space before the option then). Also, it uses regex_escape to correctly work with option names that contain dots and the likes, and you only have to specify them once.
Related
I am trying to write a playbook to add log forwarder lines to syslog.conf on AIX.
The tasks looks like this:
- set_fact:
log_servers:
- "auth.info\t#10.10.10.100"
- "*.info\t#log.example.com"
- lineinfile:
path: /etc/syslog.conf
regexp: '^{{item}}'
line: '{{item}}'
loop: "{{log_servers}}"
The first line is inserted with no issues, but I get a Python exception when the second line is encountered because of the leading asterisk.
An asterisk can be anywhere else in the line, but not at the start of the line. And escaping with a backslash (\*.info\t#log.example.com) causes a JSON parsing error, and a double backslash (\\*.info\t#log.example.com) just inserts a backslash at the front of the line.
Any advice on how to get around this?
Your issue is coming from the fact that you are trying to use the same string for a regex (where you need to escape the star) and for the line to add (where you don't need to escape the star).
There is a way to resolve this, though, it is to use the builtin regex_escape filter.
And so, your two task should become:
- set_fact:
log_servers:
- "auth.info\t#10.10.10.100"
- "*.info\t#log.example.com"
- lineinfile:
path: /etc/syslog.conf
regexp: '^{{ item | regex_escape() }}'
line: '{{ item }}'
loop: "{{ log_servers }}"
I want to add a few lines in a file as follows
*.file_size=100
*.db_size=1234
So, I just want the same format of the content added into one file along with that special characters through the ansible
You can use the blockinfile ansible module, below is an example for same,
- name: insert/update "Match User" configuration block in /etc/ssh/sshd_config
blockinfile:
path: /root/a.log
block: "*.file_size=100 *.db_size=1234"
marker: ""
You can also refer to the documentation here.
You can use | to do the job. | will add \n at the end of each line. No double quotes are needed here.
- name: insert something
lineinfile:
path: /home/aFile
line: |
*.file_size=100
*.db_size=1234
I was trying to replace one string in a file. For example:
$PASSWORD="oldpassword"
with:
$PASSWORD="newpassword"
Here is the Ansible task which should do this:
- name: change password with lineinfile
lineinfile:
dest: test.txt
regexp: '^$PASSWORD='
line: '^$PASSWORD="newpassword"'
state: present
backrefs: yes
Unfortunately I can't find the reason why it isn't working. I cannot replace it with the new string.
I was also trying without backrefs and the string was added instead of replaced.
Please advise.
Thank you.
From Regular expression operations:
$: Matches the end of the string or just before the newline at the end of
the string
So, escape $ with backslash.
- lineinfile:
dest: /tmp/test.txt
regexp: '^\$PASSWORD='
line: '$PASSWORD="newpassword"'
state: present
Also you don't need to use the backrefs parameter with your example, because your regular expression doesn't have backreferences.
It's very common for vanilla configurations files to have settings commented out in default configuration files. For example
#HEAP_SIZE=2g
How do I remove the comment character, "#" in this case, with the Ansible replace module?
- name: Uncomment out HEAP_SIZE
replace:
dest: //etc/some_path/app.conf
replace="what to put here to remove #???"
regex="#HEAP_SIZE=2g"
Resulting in
HEAP_SIZE=2g
You can use lineinfile for your task:
- name: Uncomment parameters
lineinfile:
dest: app.conf
regexp: (?i)^\s*#\s*({{ item }}.*)
line: \1
backrefs: yes
with_items:
- heap_size
- aNoThEr_setting
Simply:
replace: "HEAP_SIZE=2g"
You'd also want to make sure it's from the beginning of the line.
Generally for this use case lineinfile module fits better.
When I use lineinfile in ansible it is not writing ', " characters
lineinfile: 'dest=/home/xyz state=present line="CACHES="default""'
it is giving CACHES=default
but the desired output is CACHES="default"
How to achieve this?
it appears you can escape the quotes:
- lineinfile: dest=/tmp/xyz state=present line="CACHES=\"default\""
That gives this output:
$ cat /tmp/xyz
CACHES="default"
You don't need to escape single quotes that are inside double quotes:
- lineinfile: dest=/tmp/xyz state=present line="CACHES=\"default\" foo='x'"
cat /tmp/xyz
CACHES="default" foo='x'
source: YAML specification, stackoverflow answer
Ansible 1.9.2 contains a bug (https://github.com/ansible/ansible/issues/10864), which fails to insert escaped double quotes at the beginning or end of the line.
E.g., the following
- name: /home/core/linetest
lineinfile: dest="/home/core/linetest" line="\"ma\"ok\"in\""
will result in missing first and last double-quotes (even though you escaped it).
#/home/core/linetest
ma"ok"in
To compensate for this bug, you could add a PREFIX to the starting and ending double quotes, and subsequently removing it.
- name: PREFIX first and last escaped double quotes with 'KUCF'
lineinfile: dest="/home/core/linetest" line="KUCF\"main\"KUCF"
- name: remove 'KUCF' PREFIX
replace: dest="/home/core/linetest" regexp="KUCF" replace=""
which should give you
#/home/core/linetest
"main"
Make sure that your chosen PREFIX will never be used in the context of the destination file. In general, the longer and more random the PREFIX, the less likely it will clash with existing content in your destination file.
Alternatively, you could upgrade your Ansible to the latest branch.
If the content to be substituted is in a variable higher up in the playbook, it seems that you need to escape the escape characters instead of the quotes, something like this
---
- hosts: tomcat
vars:
classpath: "CLASSPATH=\\\"$CATALINA_HOME/bin/foo.jar\\\""
tasks:
- lineinfile: dest="/tomcat/bin/setenv.sh" line="{{ classpath }}" state=present
ends up with a line like this in the resulting file
CLASSPATH="$CATALINA_HOME/bin/foo.jar"
Just a follow up to this, above examples did not work for me when trying to create a batch file on a windows box using win_lineinfile. The file was being created, the line was being inserted, but the quotes and backslashes were formatted terribly. This was with ansible 2.4. What I finally ended up doing per a co workers suggestion was some inline jinja templating;
- name: insert our batch file contents
win_copy:
dest: C:\QAAutomation\files\posauto.bat
force: yes
content: |
{% raw %}"C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console.exe" "C:\QAAutomation\files\1POS Automation\Application Files\Bin\Automation.dll" > "c:\QAAutomation\results\nunit-console-output.txt" {% endraw %}