I have the below ansible playbook where i am identifying a string in a file and replacing it with another
---
- name: Ansible Playbook
hosts: webserver1
remote_user: user45
tasks:
- name: Replacing content with other
lineinfile:
path: /home/user45/run.sh
regexp: '^(.*)DEBUG=(.*)$'
line: 'DEBUG=ON'
the above works, but it adds ^M to the end of every other line in that file and every blank line
From what I have read online this normally occurs when you copy and paste from Windows to Linux but i typed this out manually so i am kind of stumped
Playbook is running on Linux Redhat 7
Please verify your script "/home/user45/run.sh".Looks like carriage-return character exist in there.
For whatever reason lineinfile was adding the ^M .. If I change it to use replace module it does not add the ^M bits
---
- name: Ansible Playbook
hosts: webserver1
remote_user: user45
tasks:
- name: Replacing content with other
replace:
dest: /home/user45/run.sh
regexp: 'DEBUG=.*'
line: 'DEBUG=ON'
This problem has been fixed with this solution on ansible 2.9:
---
- name: Ansible Playbook
hosts: webserver1
remote_user: user45
tasks:
- name: Replacing content with other
replace:
path: /home/user45/run.sh
regexp: 'DEBUG=.*'
replace: 'DEBUG=ON'
Enjoy ;)
Related
THi, new to this. . . .
Testing out a Ansible play to update the swappiness setting on a test box.
---
- hosts: "{{ target }}"
become: yes
tasks:
- name: swapness
lineinfile:
path: /etc/sysctl.conf
state: present
regexp: vm.swappiness=*
line: vm.swappiness=6
Currently, it is set to vm.swappiness=4 but running the above does not change that.
the way I read the logic is...
look for a line with "vm.swappiness=" and replace it with "vm.swappiness=6"
I would do in this way:
---
- name: Playbook who modify swapiness.
hosts: "{{ target }}"
become: yes
tasks:
# Set vm.swappiness to 6 in /etc/sysctl.conf
- name: Set swapiness.
sysctl:
name: vm.swappiness
value: '6'
state: present
sysctl_set: yes
reload: yes
The reason for that is that If exists any module for it, you should be doing using that module specific instead a generic one.
Ansible has a sysctl module, so it's better to use it for this.
Note: Please, review the code and set 2 white spaces between them if not already.
Given the file
shell> cat sysctl.conf
vm.swappiness=4
The task below works as expected
- lineinfile:
path: sysctl.conf
regexp: vm.swappiness=*
line: vm.swappiness=6
Running the playbook with the options --check --diff gives abridged
TASK [lineinfile] *****************************************************
--- before: sysctl.conf (content)
+++ after: sysctl.conf (content)
## -1 +1 ##
-vm.swappiness=4
+vm.swappiness=6
Notes
The regexp vm.swappiness=* is probably not what you really want. This regexp matches the string vm.swappiness followed by 0 or mode =. For example, below are strings that match this regexp
vm.swappiness
vm.swappiness=
vm.swappiness==========
Instead, you want a regexp that matches the string vm.swappiness= followed by 0 or more characters. For example vm.swappiness=.*
I am trying to use hostname -f command in variable with ansible-playbook. After I set the variable, I will use it in sed command. When manually execute the commands it works but with Ansible, variable does not work.
When I echo $hostn output is empty.
---
- hosts: test
become: true
become_user: root
tasks:
- name: test
shell: "{{ item }}"
with_items:
- hostn=`hostname -f` <<<<<< not working
- echo $hostn <<<<<< not working
- sed -i "s/test/$hostn/g" /file <<<< manually works
Can you help me?
My advise would be that you should not try to fit all your commands in Ansible shell this way, but rather translate them into the corresponding Ansible modules.
What you are looking to achieve can be done with the replace module — in place of sed — and the Ansible fact ansible_hostname — in place of hostname -f.
This would be the equivalent playbook:
- hosts: test
become: true
become_user: root
tasks:
- replace:
path: /file
regexp: test
replace: "{{ ansible_hostname }}"
I am new to ansible and, I am trying to call my_task.yml from my_plybk.yml.
The content of my_playbk.yml is as follow:
---
- hosts: localhost
gather_facts: no
tasks:
- include my_tasks.yml
The content of my_task.yml is as follow.
- hosts: localhost
tasks:
- name: Run the below script
command: sh myscript.sh
Content of myscript.sh
echo "Hello"
below is the error which I am getting.
ERROR! A malformed block was encountered while loading a block
I guess the problem could be the extra spacing in your my_plybk.yaml file.
It should be arranged like this:
---
- hosts: localhost
gather_facts: no
tasks:
- include: my_tasks.yml
Also, there were missing colon after "include".
Same applicable to the my_tasks.yml file:
- name: Run the below script
command: sh myscript.sh
Also, please note in the text above that your included file should contain only list of tasks, without "hosts" or "tasks" keyword.
Please note that Ansible and yaml-files in general are very sensitive on how you arrange rows and spaces.
Is there a better way to iterate through multiple files on the node machine using Ansible playbook and search n replace a particular line.
I have the following files in my directory and it needs to iterate through these files and check and replace a particular line in the file.
/opt/a1.conf
/opt/a2.con.f
/var/app1/conf/a3.conf
/etc/a5.conf
/etc/a6.conf
/etc/a7.conf
/etc/a8.conf
/etc/a9.conf
My Ansible Playbook can be formatted as follows:
-
name: Install nginx and other binaries using with_item and variables.
gather_facts: yes
hosts: aws1
become_method: sudo
become: yes
tasks:
- name: Modify line to include Timeout
become: yes
become_method: sudo
lineinfile:
path: {{ item }}
regexp: 'http\s+Timeout\s+\='
line: 'http Timeout = 10'
backup: yes
with-items
- /opt/a1.conf
- /opt/a2.con.f
- /var/app1/conf/a3.conf
- /etc/a5.conf
- /etc/a6.conf
- /etc/a7.conf
- /etc/a8.conf
- /etc/a9.conf
This will actually work and help me. I could also create a vars.yaml file and add all these files and use them in "with_items" syntax.
However this is actually making the playbook look to lengthy as the number of files to search are higher
We possibly can achieve the same thing effectively by using the jinja2 template using the "for" loop.
EX: {% for item in vars.yml %}
and that would rather be an effective way to do it and wont make my Ansible playbook clumsy but I'm unable to figure the exact command for looping it.
Is there a jinja command to achieve the same or a better way to iterate through multiple files and not writing each of them into the playbook.
Thank you
You don't need jinja2 for that. Why don't you use a separate file for the file list variable like vars.yml with the following contents:
---
files:
- /opt/a1.conf
- /opt/a2.con.f
- /var/app1/conf/a3.conf
- /etc/a5.conf
- /etc/a6.conf
- /etc/a7.conf
- /etc/a8.conf
- /etc/a9.conf
and include this file in your playbook:
---
- name: Install nginx and other binaries using with_item and variables.
gather_facts: yes
hosts: aws1
become_method: sudo
become: yes
vars_files:
- z.var
tasks:
- name: Modify line to include Timeout
lineinfile:
path: {{ item }}
regexp: 'http\s+Timeout\s+\='
line: 'http Timeout = 10'
backup: yes
loop:
"{{ files }}"
I want to restrict an Ansible play to a specific host
Here's a cut down version of what I want:
- hosts some_host_group
tasks:
- name: Remove existing server files
hosts: 127.0.0.1
file:
dest: /tmp/test_file
state: present
- name: DO some other stuff
file:
...
I want to (as an early task), remove a local directory (I've created a file in the example as it's a more easily observed test). I was under the impression that I could limit a play to a set of hosts with the "hosts" parameter to the task -
but I get this error:
ERROR! 'hosts' is not a valid attribute for a Task
$ansible --version
ansible 2.3.1.0
Thanks.
PS I could wrap the ansible in a shell fragment, but that's ugly.
You should use delegate_to or local_action and tell Ansible to run the task only once (otherwise it will try to delete the directory as many times as target hosts in your play, although it won't be a problem).
You should also use absent not present if you want to remove directory, as you stated.
- name: Remove existing server files
delegate_to: 127.0.0.1
run_once: true
file:
dest: /tmp/test_file
state: absent
There are syntax errors in your playbook, have a look at Ansible Intro, Local Playbooks and Delegation.
- hosts: some_host_group
tasks:
- name: Remove existing server files
- hosts: localhost
tasks:
- file:
dest: /tmp/test_file
state: present
- name: DO some other stuff
file: