问题
I have a task in my Ansible playbook that I'm wanting iterate over each host in the group that I have and for each host I would like to assign a name from the hostname list that I've created in the vars folder.
I'm familiar with looping through inventory already by writing loop: "{{ groups['mygroup'] }}" and I have a list of hostnames I would like to assign each IP in 'mygroup' within the host file.
# In tasks file - roles/company/tasks/main.yml
- name: change hostname
win_hostname:
name: "{{ item }}"
loop: "{{ hostname }}"
register: res
# In the Inventory file
[company]
10.0.10.128
10.0.10.166
10.0.10.200
# In vars - roles/company/vars/main.yml
hostname:
- GL-WKS-18
- GL-WKS-19
- GL-WKS-20
# site.yml file located under /etc/ansible
- hosts: company
roles:
- common
- company #This is where the loop exists mentioned above.
# Command to run playbook
ansible-playbook -i hosts company.yml
I seem to have the individual pieces down or know about it, but how can I combine iterating over hosts from an inventory group and assign names that I have in an already created list (in roles vars folder) already?
UPDATE the task mentioned above has been updated to reflect changes mentioned in answer:
- name: change hostname
win_hostname:
name: "{{ item.1 }}"
loop: {{ groups.company|zip(hostname)|list }}"
register: res
However the output I'm getting is incorrect, this should not run 9 times rather only three times, once per IP in the [company] group in the inventory. Also there are only three hostnames in a list that need to be assigned to each of the hosts in the inventory sheet.
changed: [10.0.10.128] => (item=[u'10.0.10.128', u'GL-WKS-18'])
changed: [10.0.10.166] => (item=[u'10.0.10.128', u'GL-WKS-18'])
changed: [10.0.10.200] => (item=[u'10.0.10.128', u'GL-WKS-18'])
changed: [10.0.10.128] => (item=[u'10.0.10.166', u'GL-WKS-19'])
changed: [10.0.10.166] => (item=[u'10.0.10.166', u'GL-WKS-19'])
changed: [10.0.10.200] => (item=[u'10.0.10.166', u'GL-WKS-19'])
ok: [10.0.10.128] => (item=[u'10.0.10.200', u'GL-WKS-20'])
ok: [10.0.10.166] => (item=[u'10.0.10.200', u'GL-WKS-20'])
ok: [10.0.10.200] => (item=[u'10.0.10.200', u'GL-WKS-20'])
回答1:
Whenever I have a question about looping in Ansible I also go visit the Loops documentation. It sounds like you want to iterate over two lists in parallel, pairing an item from the list of hosts in your inventory with an item from the list of hostnames. In previous versions of Ansible that would suggest using the with_together
loop, while with more recent versions of Ansible that suggests the zip
filter (there's an example in the docs here).
To demonstrate this for your use case, I started with an inventory file that has three hosts:
[mygroup]
hostA ansible_host=localhost
hostB ansible_host=localhost
hostC ansible_host=localhost
And the following playbook:
---
- hosts: all
- hosts: localhost
gather_facts: false
vars:
hostnames:
- hostname01
- hostname02
- hostname03
tasks:
- name: change hostname
debug:
msg:
win_hostname:
name: "{{ item }}"
loop: "{{ groups.mygroup|zip(hostnames)|list }}"
Here I'm using a debug
task instead of actually running the win_hostname
task. The output of running:
ansible-playbook -i hosts playbook.yml
Looks like:
TASK [change hostname] ********************************************************************************************************************************
ok: [localhost] => (item=[u'hostA', u'hostname01']) => {
"msg": {
"win_hostname": {
"name": [
"hostA",
"hostname01"
]
}
}
}
ok: [localhost] => (item=[u'hostB', u'hostname02']) => {
"msg": {
"win_hostname": {
"name": [
"hostB",
"hostname02"
]
}
}
}
ok: [localhost] => (item=[u'hostC', u'hostname03']) => {
"msg": {
"win_hostname": {
"name": [
"hostC",
"hostname03"
]
}
}
}
As you can see, it's paired each host from the inventory with a hostname from the hostnames
list.
Update
Based on the additional information you've provided, I think what you actually want is this:
- name: change hostname
win_hostname:
name: "{{ hostnames[group.company.index(inventory_hostname) }}"
This will assign one value from hostname
to each host in your
inventory. We're looking up the position of the current
inventory_hostname
in your group, and then using that to index into
the hostnames
list.
来源:https://stackoverflow.com/questions/53860671/how-to-loop-through-inventory-and-assign-value-in-ansible