Reputation: 529
I wrote a playbook with the purpose of changing the last bit of the default gateway ip of all the hosts in my inventory.ini
So far I am able to change the last bit through this command :
cat /etc/network/interfaces | grep -i default | awk -F'.' -vOFS='.' '{$NF=6}1;' > /etc/network/interfaces
But the problem is that I still cannot figure out how to replace only the last line of the interfaces file without overwriting the whole content of the file.
Here's how my playbook look like :
---
- name: test connectivity
hosts: all
tasks:
- name: ping
ping:
- name: change default gateway address
command: cat /etc/network/interfaces | grep -i default | awk -F'.' -vOFS='.' '{$NF=6}1;' > /etc/network/interfaces
- name: restart networking service
command: systemctl restart networking
- name: check ip configuration
command: netstat -rn
...
All hint and tips are more than welcome.
Upvotes: 3
Views: 660
Reputation: 529
Well after many tries and after taking the advice of using ansible modules in account I came out with this gem of a playbook that helped me reach my goal :
---
- name: test connectivity
hosts: all
tasks:
- name: ping
ping:
- name: change default gateway address
replace:
path: /etc/network/interfaces
regexp: '(up route add default gw [\d]*\.[\d]*.[\d]*)\.[\d]*$'
replace: '\1.6'
backup: yes
when: (ansible_facts['distribution'] == "Debian")
- name: restart networking serviice
service:
name: networking
state: restarted
when: (ansible_facts['distribution'] == "Debian")
- name: change default gateway address on Redhat
replace:
path: /etc/sysconfig/network-scripts/ifcfg-eth0
regexp: '(GATEWAY=[\d]*\.[\d]*.[\d]*)\.[\d]*$'
replace: '\1.6'
backup: yes
when: (ansible_facts['distribution'] == "RedHat")
- name: restart networking service for Redhat
service:
name: network
state: restarted
when: (ansible_facts['distribution'] == "RedHat")
...
It is working just as expected and of course it can be enhanced for other context. Thank you all for your advices and help
Upvotes: 1
Reputation: 68034
Q: "Ansible replacing the last line of file"
A: Given a file
shell> cat test.txt
l1
l2
l3
the playbook
- hosts: localhost
vars:
replace_line: last line replacement
tasks:
- command: cat test.txt
register: result
- copy:
dest: test.txt
content: |
{% for line in result.stdout_lines[:-1] %}
{{ line }}
{% endfor %}
{{ replace_line }}
gives
shell> cat test.txt
l1
l2
last line replacement
The playbook is idempotent.
Upvotes: 2
Reputation: 133518
Have your playbook of Ansible in this way. This is completely based on your shown samples. I couldn't test it since I don't have Ansible with me, though command should work.
---
- name: test connectivity
hosts: all
tasks:
- name: ping
ping:
- name: change default gateway address
command: tac /etc/network/interfaces | awk -F'.' -v IGNORECASE="1" -v OFS="." '/default/{if(FNR==1){$NF=6};print}' | tac > temp && mv temp /etc/network/interfaces
- name: restart networking service
command: systemctl restart networking
- name: check ip configuration
command: netstat -rn
# ...
Fixes done in OP's attempt:
I have also taken care of your overwriting issue, where you are overwriting your same Input_file without inplace option OR without using a temp output file. Because if try to update an Input_file while awk
program is reading it, it gets empty because we are not using inplace option to perform same(which creates temp file in backend and saves output into it and then renames that file to Input_file).
Removed grep
command since awk
can take care of by itself, so attached the logic of grep into awk
code itself.
Upvotes: 3