I have an ansible playbook that calls an API. I have a delegate_to: localhost.
I want to run my playbook "against" every host in a group Linux.
I want the API call to do 2 things.
I want it to run once for every host in the Linux group
For every run, it should have a different host IP/hostname as the input
linux looks like:
[linux]
10.234.0.13
10.234.0.12
I run my like this: ansible-playbook -i linux my_playbook
How do I make the inventory group an input?
when ansible executes on the remote host it collects some meta data of the hosts. One of the meta data is ip address. The meta data is called ansible facts. There is an ansible fact to get the ip address
ansible_default_ipv4.address
Related
I am trying to play a yml on other host than configured, using -l option.. but skipping: no hosts matched .
The scenario is where a host associated playbook is needed to be exceptionally used for some other host. (and for safety reasons, the playbook cannot have hosts:all and be left to the admin to limit the target(s))
What is the correct way to do this (if there is any)?
L.E. So, in the end, the answer of #mdaniel gave me the idea o a bash wrapper that creates a temp yml where the host: field is replaced with the argument.. it's not pretty but it works. (same works for a dynamical generation of a playbook from a series of tasks)
and the proper ansible way to do it i just found it here:
https://stackoverflow.com/a/18195217/624734
What is the correct way to do this?
Use all as the target of the playbook, and then constrain the hosts it applies to via the inventory, or the --limit that you mentioned
- hosts: all
# and now the rest of your playbook
You can try the below approach if you want to restrict hosts:all in your ansible script.
- hosts: "{{ host_group }}"
# Rest of your playbook
And you can have a specific group in your hosts file which you can use for testing.
For example,
[test]
192.168.1.1 # Test host
# Rest of your inventory file
And trigger the ansible playbook in the following order,
ansible-playbook -i hosts main.yml -e host_group="test"
The hosts which I address in the Playbook maint-change.yml belong to two Groups (instancegroup1 & instancegroup2 with sveral hosts in each group) like this:
- hosts: "{{ server | default('instancegroup1 instancegroup2') }}"
So if I just want to run the Playbook against one host I will limit with (-e EXTRA_VARS) the variable server and the hostname from the instance:
ansible-playbook maint-change.yml -e server=test.instance2
In that Case the "test.instance2" is listet in the inventory file of instancegroup2 and the playbook will only run against the host "test.instance2" successfully.
But how is is that possible with awx? If I have created the template with the same Playbook "maint-change.yml" which is using the variable server as I mentioned above, it's not possible to paste the "server=test.instance2" in the EXTRA VARIABLES field of the Template. Is there any Solution to set the specific variable server from the Playbook in the EXTRA VARIABLES field from awx's Template?
I believe you are using AWX Job templates. You can use the limit check option in your templates. Here's a screenshot of that -
I'm writing a role thats creates virtual machines & configures them. I need to perform a few tasks on the VM's before their DNS entries are created.
How can I get the task to connect to a known IP address instead of the usual ansible_host variable (FQDN)? I can't set it in the inventory file since the IP is not known when it is created.
TIA
The inventory file can use IP addresses. See the jumper example in https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html.
The way you typically handle this is to use Ansible's add_host module, which lets you create inventory entries dynamically during your playbook run. A task looks something like:
- name: add host to inventory
add_host:
name: my_new_host
ansible_host: "{{ new_host_ipaddr }}"
groups: [webservers]
You can see an example of this in action here (just search for add_host).
I'm using the vmware_guest module to create a bunch of vms.
Is there anyway to use a pattern for both the hostname and IP address?
For example I want to create 5 master vms with hostname/IP like:
master1 10.123.0.1
master2 10.123.0.2
master3 10.123.0.3
etc.
So an inventory yaml with something like the following:
all:
children:
Elvis:
children:
masterNodes:
hosts:
master[1-5]:
ansible_host: 10.123.0.[1-5]
slaveNodes:
hosts:
slave[1-10]:
ansible_host: 10.124.0.[1-10]
Also, is there a way to run a playbook for a specific parent:child group?
How can I run a play for Elvis:masterNodes only? If for instance, the same inventory yaml has another parent child group Bono:masterNodes
Is there anyway to use a pattern for both the hostname and IP address?
No. Instead, Ansible allows running a script to generate an inventory - it is trivial to implement a loop populating inventory-hostname along with IP address in Python (apparently it was made clear as early as in July 2013, although in the same thread someone suggested a workaround).
Also, is there a way to run a playbook for a specific parent:child group?
No. There is no hierarchy in Ansible inventory; the namespace is flat; there are no child groups; Ansible operates on host/group sets.
In effect, you can't have distinct (sub)groups bearing the same name. The contents of those (sub)groups will be merged. So if Elvis contains a group masterNodes and you execute a play with hosts:Elvis declaration, it will run on all hosts defined for masterNodes anywhere (including in Bono:masterNodes).
I'm running an ansible playbook on a list of hosts with a host file:
[consul]
${HOST1} ansible_ssh_host=${HOST1} ansible_ssh_user=devops ansible_ssh_pass=blabla
${HOST2} ansible_ssh_host=${HOST2} ansible_ssh_user=devops ansible_ssh_pass=blabla
.......so on...
The thing is that I need to pass a different variable for each host.
I know of the flag -e that allows me to send a variable with the ansible-playbook command but it's not for each of the hosts.
I'm running the playbook with this:
ansible-playbook -vvvv site.yml
How can I pass a different var for each host?
Thanks!
Note: I'm using ansible 1.7.1
Two ways you should be able to do this:
1) Include the variable in your host file:
[consul]
${HOST1} ansible_ssh_host=${HOST1} .... myvar=x
${HOST2} ansible_ssh_host=${HOST2} .... myvar=y
2) Or use the include_vars task to load a file based on the host name
include_vars: "{{ ansible_ssh_host }}.yml"
The second method is good if you have a lot of variables to load for a host.
For more complex cases the lookups module might help:
http://docs.ansible.com/ansible/playbooks_lookups.html