I have the following problem:
I'm writing playbook for setting IP address on the command line in Ansible. Lets say 10.10.10.x. I need to get the last part of my public IP lets say x.x.x.15 and assign it to the private: 10.10.10.15. Is there a variable for this? Can i capture some? I've tried to use something like:
shell: "ip addr show | grep inet ...."
register: host_ip
But it is not what i need. It works, but only for a limited number of servers.
The whole thing should be like that:
"shell: /dir/script --options 10.10.10.{{ var }}"
and {{ var }} should be the host part of the public IP.
Edit:
Thank you! Here's my final solution:
- name: Get the host part of the IP
shell: host {{ ansible_fqdn }} | awk '{print $4}'
register: host_ip
And
{{ host_ip.stdout.split('.')[3] }}
For using it later in the playbook.
As mentioned by jarv this can be obtained by using facts.
This can be done in the following ways:
For a list of all ipv4 addresses:
{{ ansible_all_ipv4_addresses }}
For the default ipv4 address:
{{ ansible_default_ipv4.address }}
If you know the ip address is on the eth0 interface:
{{ ansible_eth0.ipv4.address }}
You can then append the .split('.')[3] method to the variable to get the appropriate output, for example {{ ansible_default_ipv4.address.split('.')[3] }}
Instead of using a system utility you can use ansible facts though you will find that interface names will vary from server to server.
You specifically mentioned the last part of my public IP
If you really mean your public IP you will need to use an external service to get it since your server may behind a NAT. Here is one option
shell: wget -qO- http://ipecho.net/plain ; echo
register: host_ip
That will give your public IP, next to get the last octet you could do something like:
{{ host_ip.stdout.split('.')[3] }}
This is an similar way to get it:
- name: Get the local IP
local_action:
module: uri
url: http://checkip.amazonaws.com/
return_content: yes
register: ip_lookup
- set_fact:
local_ip: "{{ ip_lookup.content | regex_replace('\n','') }}"
- debug: var=local_ip
Related
I am trying to get the inventory_hostname from a hosts group I created.
What I am really trying to achieve is copying a file with a new name to a remote server, while its new name will be other remote servers hostname.
{{ inventory_hostname }} gives IP address and {{ ansible_hostname }} returns hostname as default variables but while doing this, I am stuck:
- name: Copy File
hosts: nagios
become: yes
tasks:
- shell: cp /home/xxx/test.txt /home/xxx/{{ item }}.txt
with_items: "{{ groups['dbs'] }}"
{{ item }} returns the IP address but I want the hostname, not the IP for this one. Any help would be appreciated.
I would like to use getent wrapper module in order to parse the contents of /etc/hosts and save the ip address in a variable for later use. I do not manage to isolate the IP if found on /etc/hosts
we are doing this in order to check that the /etc/hosts on the server farm are up to dated we will use this variable to verify against the dns and if the two address do not match then correct /etc/hosts. I also tried slurp but without much success
---
- hosts: all
tasks:
- name: getent hosts
getent:
database: hosts
key: "{{ansible_hostname}}"
register: results
- name: print result
debug:
msg="{{results}}"
- set_fact:
a_host_ip={{ getent_hosts[ansible_default_ipv4.address] }}
- debug: var=a_host_ip
I would like to have the ip address in the varilable a_host_ip but the actual contents are the hostnames corresponding to the ip address. How can I save the IP address in a variable.
To get a list of IPs:
{{ getent_hosts.keys() }}
To get a single element:
{{ getent_hosts.keys() | first }}
I have a playbook that contains roles for localhost and roles for remote hosts.
In one of the localhost roles I set a fact called git_tag.
I want to use this fact in a template for the remote hosts.
I tried:
- name: Read Version
set_fact:
git_tag: "{{ package_json.stdout | from_json | json_query('version')}}"
delegate_to: "test-server"
But when Ansible reaches the role that reads the template that has {{ git_tag }} it says that git_tag is undefined.
I'm sure I'm doing something wrong. How can I do it?
You should use a hostvars magic variable:
{{ hostvars['localhost']['git_tag'] }}
you can use this
{{ hostvars['test-server']['git_tag'] }}
I have a host file that looks roughly like this:
[kibanamaster]
efk host_ip host user passwd
[elasticnode]
esnode host_ip user passwd
and I am trying something in the style of
- name: get ip address node1
debug: var=hostvars[inventory_host]['esnode']['ansible_default_ipv4']['address']
register: es_node1
But I get variable not defined. Anyone outthere able to help?
EDIT:
If I do
debug: var=hostvars[LOG1]['esnode']['ansible_default_ipv4']['address']
register: node_1
I get
{"hostvars[LOG1]['ansible_default_ipv4']['address']": "VARIABLE IS NOT DEFINED!"}
hostvars magic variable is a dictionary with keys named after hosts in your inventory.
So you may want to try:
hostvars['esnode']['ansible_default_ipv4']['address']
to get ip address of esnode host.
You can use pre-loaded ansible variable to get values for both ipv4, ipv6 & hostname
IPV4 --> {{ ansible_eth0.ipv4.address }}
IPV6 --> {{ ansible_eth0.ipv6.address }}
Hostname --> {{ ansible_hostname }
I need to save two 2 IPs to a variable in a vars_file when launching ec2_instances, which are used later during deployment.
This is how I am saving a single server ip:
- name: Save server public IP to vars file
lineinfile: line="server_public_ip{{':'}} {{ item.public_ip }}"
dest="{{ansible_env.HOME}}/dynamic_ips_{{ec2_environment}}"
with_items: server.instances #server is registered in previous task
The output I have in dynamic_ips file is server_public_ip: xxx.xxx.xx.x
Now I have 2 servers launched and registered as servers.
I need to save this as server_public_ips: xxx.xx.x.xx , xxx.x.xx.x
I tried to declare an empty string and append ips to it, something like this, but I am getting errors.
set_fact:
ips: ""
set_fact:
ips: " {{ ips }} + {{ item.public_ip}} "
with_items: servers.instances #servers is registered in previous task
lineinfile: line="server_public_ips{{':'}} {{ ips }}"
dest="{{ansible_env.HOME}}/dynamic_ips_{{ec2_environment}}"
I think it can be done using lineinfile insertafter and regex.
Finally, I need this to do this in a different server,
- name: Restrict access to outside world
command: iptables INPUT {{ item }} ACCEPT
with_items: {{ server_public_ips }}.split(,) #grant access for each ip
command: iptables INPUT DROP
set_fact:
ips: " {{servers.instances | join(',') }} "
should actually work when servers.instances is a list.