问题
I have two files where these file contains server names
and server IP's
, I want to change/replace some specific server names
and IP addressees
in both the files based on the requirement.
This is related to This Post <-- as it was asked to open a new post.
My scenario:
In the Below example files(file & file2
) i need to do follows..
1 - In file1 and fil2 i have to replace fostrain01.example.com
with dbfostrain01.example.com
.
2 - Where in another line i have to replace 171.20.20.18
with 172.20.20.18
in both the files as well.
# cat /etc/file1
fostrain01.example.com
fostrain02.example.com
ServerIPS 171.20.20.16 171.20.20.17 171.20.20.18 171.20.20.19 171.20.20.20
# cat /etc/fil2
fostrain01.example.com
fostrain02.example.com
ServerIPS 171.20.20.16 171.20.20.17 171.20.20.18 171.20.20.19 171.20.20.20
My Playbook:
---
- name: Replace file contents
hosts: all
gather_facts: false
vars:
files:
- /etc/file1
- /etc/file2
from_str: "fostrain01.example.com"
to_str: "dbfoxtrain01.example.com"
from_ip: "^(.*)171\\.20\\.20\\.18(.*)$"
to_ip: "\\g<1>172.20.20.18\\g<2>"
tasks:
- name: Replace elements in file
replace:
path: "{{ item.path }}"
regexp: "{{ item.From }}"
replace: "{{ item.To }}"
backup: yes
loop:
# Replace the desired string
- { path: "{{ item }}", From: "{{ from_str }}", To: "{{ to_str }}" }
# Replace the desired ip
- { path: "{{ item }}", From: "{{ from_ip }}", To: "{{ to_ip }}" }
In the above playbook, i have defined the variables for each sections as you can see.
What I'm Missing and Would Like to Know:
I am missing to understand about How i can use or reference files variable
in the path
section of replace module in my playbook
above while using loop
.
Just to clarify, i'm talking about below one..
files:
- /etc/file1
- /etc/file2
I am looking this to be fitted within the approach in the above playbook, as i know the other way around of doing it.
I am sorry, if i could not make it more clear.
回答1:
So file is a list of variable, as any list of varibales, the items are accessible via a 0-indexed key.
So in you case, the first element of the
files
list, containing/etc/file1
is accessible either viafiles.0
Or
files[0]
The second, containing
/etc/file1
is accessible either viafiles.1
Or
files[1]
And so on, and so forth.
But there is a lot of other ways to do this:
- you could use product to merge your two lists
- you could use the
loop_control
parameter index_var to create your own index - you could use the extended parameter of
loop_control
, that provides the extended variableansible_loop.index0
All this said, to make it a little bit more generic, if I were you, I would use the product filter and go with a more simpler:
- name: Replace elements in file
replace:
path: "{{ item.0 }}"
regexp: "{{ item.1.from }}"
replace: "{{ item.1.to }}"
backup: yes
vars:
paths:
- /etc/file1
- /etc/file2
replaces:
- from: "fostrain01.example.com"
to: "dbfoxtrain01.example.com"
- from: "^(.*)171\\.20\\.20\\.18(.*)$"
to: "\\g<1>172.20.20.18\\g<2>"
loop: "{{ paths | product(replaces) | list }}"
Because, then there is no reason to transform your list, it is already has it should for your replace
task.
Mind that variables can be defined both at play or task level, if you need the replaces
variable in other tasks, just bring it back up to the play level.
回答2:
You are almost there with your solution, Just you have to use files
variable as an index key to the file selection as nicely illustrated by @β.εηοιτ.βε in his answer section.
So, to complete your code to make it working, it should be working as follows..
---
- name: Replace file contents
hosts: all
gather_facts: false
vars:
files:
- /etc/file1
- /etc/file2
from_str: "fostrain01.example.com"
to_str: "dbfoxtrain01.example.com"
from_ip: "^(.*)171\\.20\\.20\\.18(.*)$"
to_ip: "\\g<1>172.20.20.18\\g<2>"
tasks:
- name: Replace elements in file
replace:
path: "{{ item.path }}"
regexp: "{{ item.From }}"
replace: "{{ item.To }}"
backup: yes
loop:
# Replace the desired string
- { path: "{{ files[0] }}", From: "{{ from_str }}", To: "{{ to_str }}" }
- { path: "{{ files[0] }}", From: "{{ from_ip }}", To: "{{ to_ip }}" }
# Replace the desired ip
- { path: "{{ files[1] }}", From: "{{ from_str }}", To: "{{ to_str }}" }
- { path: "{{ files[1] }}", From: "{{ from_ip }}", To: "{{ to_ip }}" }
来源:https://stackoverflow.com/questions/62875869/how-we-can-call-a-variable-in-ansible-playbook-while-using-loops