This should automatically updat the ansing ansible_hostname I am thinking but it is not.
name: rename host
ansible.windows.win_hostname:
name: “{{ comp_name }}”
register: res
This should automatically updat the ansing ansible_hostname I am thinking but it is not.
name: rename host
ansible.windows.win_hostname:
name: “{{ comp_name }}”
register: res
Hello @ekim1975 welcome to the Ansible Community Forum!
With the little information you did provide is hard to guess what you’re trying to achieve, but I’ll give it a try.
Should we understand that you do want to use your ansible inventory hostnames to rename a set of Windows target hosts?
If that’ so, instead of using ansible_hostname
, I believe you need to use inventory_hostname
instead (I’m blindly supposing you already parsed ansible_hostname
into comp_name
from the remote node’s facts in a prior task on your playbook, which btw will result in no chages at all, since you will be assigning the very same hostname that node had during fact gathering).
That is because in Ansible (provided you did enable the gather_facts
keyword on your play) ansible_hostname is a fact obtained from the remote node itself. On the other hand, inventory_hostname is what we know as a magic variable - One that in this particular case gets the current inventory hostname value for each instance of a playbook task.
So, maybe you should be trying something like this instead?
- name: rename host
ansible.windows.win_hostname:
name: “{{ inventory_hostname }}”
register: res
Hi Jordi!
It is a pleasure to have joined this Ansible forum. I look forward to interacting with this community. I have been using Ansible for about a year so I am still somewhat of a novice.
In regards to my question.
I do set the {{ comp_name }} in my playbook (ex: DARTH-VADER) of what i want to change the name to… I am just dealing with a single node, which is an AWS ec2 instance.
I tried to use “inventory_host”, that you mention above but that returns the IP address. ansible_host also returns the IP address. This is good because I had a heck of a time finding a method of returning JUST the ip address without the single quotes and brackets. I was using this: {{ ansible_all_ipv4_addresses | regex_replace(“[']”,“”) }} I can use it in some places in my playbook and roles, but in other places Ansible complains.
Ah yes of course, you should build your inventory accordingly in order to set the inventory hostname instead of the IP. For example, you may use the names of the hosts as an alias in your inventory, and then assign an IP address to the ansible_host
host_var, like this:
---
kvm_guests:
hosts:
win10-vm:
ansible_host: 192.168.30.30
Then you will be able to use the inventory_hostname
magic var to dynamically assign it’s host name to the remote nodes.
Anyway, now that I got more information in regards of your original question, I believe I understand better what you wanted to achieve
Did you reboot your windows node AFTER renaming it? Be aware that the hostname change will not be effective until you reboot the node (as noted on the ansible.windows.win_hostname module docs), so if you gather facts without rebooting, you won’t notice the change on them…
Here is an example to illustrate better what I just said:
---
- name: "Ansible.windows.win_hostname: does not update the Ansible environment"
hosts: all
gather_facts: true
vars:
comp_name: new-win10-vm
tasks:
- name: Rename host
ansible.windows.win_hostname:
name: "{{ comp_name }}"
- name: Get host facts before rebooting
ansible.builtin.setup:
register: pre_facts
- name: Show facts for the current host BEFORE rebooting -> {{ inventory_hostname }}
ansible.builtin.debug:
var: pre_facts.ansible_facts.ansible_hostname
- name: Reboot windows node
ansible.windows.win_reboot:
- name: Get host facts after rebooting
ansible.builtin.setup:
register: post_facts
- name: Show updated facts for the current host AFTER rebooting -> {{ inventory_hostname }}
ansible.builtin.debug:
var: post_facts.ansible_facts.ansible_hostname
...
Now, if you check the gathered facts before and after rebooting:
PLAY [Ansible.windows.win_hostname: does not update the Ansible environment] ***************************************************************************************************
TASK [Rename host] *************************************************************************************************************************************************************
changed: [win10-vm]
TASK [Get host facts before rebooting] *****************************************************************************************************************************************
ok: [win10-vm]
TASK [Show facts for the current host BEFORE rebooting -> win10-vm] ************************************************************************************************************
ok: [win10-vm] => {
"pre_facts.ansible_facts.ansible_hostname": "win10-vm"
}
TASK [Reboot windows node] *****************************************************************************************************************************************************
changed: [win10-vm]
TASK [Get host facts after rebooting] ******************************************************************************************************************************************
ok: [win10-vm]
TASK [Show updated facts for the current host AFTER rebooting -> win10-vm] *****************************************************************************************************
ok: [win10-vm] => {
"post_facts.ansible_facts.ansible_hostname": "new-win10-vm"
}
PLAY RECAP *********************************************************************************************************************************************************************
win10-vm : ok=6 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Hope it helps!
Now, for the same price I can answer this one also
I’d suggest you using the regex plugins as a last resort resource. To get the IPv4 address from the ansible_facts
dict, you can do it in different ways:
If you know for sure that the remote node has only one IP address, you can get it directly from the list of ip_addresses
, as it will be always its first element:
- name: get host IP address
ansible.builtin.debug:
var: ansible_facts.ip_addresses | first
However, if you got several nic’s on the remote node, you might want to filter by interface name, or whatever suits you better. For that the selectattr
jinja2 filter comes super handy:
- name: Get host IP address using interface name
ansible.builtin.debug:
var: interface[0].ipv4.address
vars:
interface: "{{ ansible_facts.interfaces | selectattr('interface_name', 'eq', 'Intel(R) 82574L Gigabit Network Connection #2') }}"
(On the second case, notice that interface
will always be a list of only one element after filtering with selectattr
, so we get the first element with [0])
cheers
The host name thing worked:
post_facts.ansible_facts.ansible_hostname
But the IP did not not: ansible_facts.ip_addresses
note that it still returned the single quotes and brackets [‘1234:567:890:12345’, ‘10.11.12.13’]
That is because what you got there is a list. In short, on Ansible we have different data structures; variables, lists and dictionaries. Vars can store one, and only one element / value (a string, integer, etc). A list is a collection of indexed elements, which can be of different types. Dicts are collections of key:value elements - That is, elements that can be referenced by a key.
Let’s focus on lists, since that’s what we got on ansible_facts.ip_addresses. A list can be set using different formats, which are equivalent:
raw
my_list: ["element_1","element_2","element_N"]
yaml
my_list:
- element_1
element_2
element_N
Now, if you wanted to show the first element of this list, you should use its index to do so, like:
- name: get host IP address
ansible.builtin.debug:
var: ansible_facts.ip_addresses[0]
For the second element:
- name: get host IP address
ansible.builtin.debug:
var: ansible_facts.ip_addresses[1]
etc.
You can also use jinja filters to get the first or last element of the list instead of indexes, which adds readibility to our code:
- name: get host IP address
ansible.builtin.debug:
var: ansible_facts.ip_addresses | first
Summing- up, if you wanted to show the IP address on the list you did provide, you should be using either [1] index, or the last
jinja filter, like this:
- name: get host IP address
ansible.builtin.debug:
var: ansible_facts.ip_addresses[1]
- name: get host IP address
ansible.builtin.debug:
var: ansible_facts.ip_addresses | last
PS: In your list → ["1234:567:890:12345", "10.11.12.13"]
the element with index [0]
doesn’t look as an IPv4, so I’m using the [1]
index to illustrate it better. On my first example I’ve used the index [0] or the first
filter because what I do get from my windows node facts is just an IP address, so its a list of only one element. Anyway, I hope that with this explanation you got the point. If you did not, feel free to ask
That makes sense now. Thanks!