How can add content line-by-line in ansible? - ansible

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

Related

Line break with lineinfile in ansible

The only way that I find to respect regex line break \n is concatenating everything in one line with double quote.
---
- name: Custom prompt output
lineinfile:
path: ~/.zshrc
line: "\n# Custom Prompt\nlocal user=\"%{$fg[yellow]%}%n%{$fg[white]%}#%{$fg[green]%}%m%{$reset_color%}\"\nPROMPT=\"${user} ${PROMPT}\""
state: present
The result is correctly as I expected, but is so ugly. Have a way to better this?
An option would be to use blockinfile
- name: Custom prompt output
blockinfile:
path: ~/.zshrc
create: yes
block: |
# Custom Prompt
local user="%{$fg[yellow]%}%n%{$fg[white]%}#%{$fg[green]%}%m%{$reset_color%}"
PROMPT="${user} ${PROMPT}"

Replacing a word in a file with Ansible

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.

How to uncomment line with Ansible replace module?

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.

Ansible lineinfile - modify a line

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.

Quotes in ansible lineinfile

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 %}

Resources