I get my network inventory for ansible dynamicly from the netbox plugin and I want to use this data to edit the /etc/hosts file and run a script on a special host (librenms) to add all the network devices there.
Has anyone an idea how to run a playbook only on the librenms host with the data of the netbox inventory plugin?
Here my inventory (the librenms host is not part of it)
plugin: netbox
api_endpoint: https://netbox.mydomain.com
token: abcdefghijklmopqrstuvwxyz
validate_certs: False
config_context: True
group_by:
- device_roles
query_filters:
- role: test-switch
- has_primary_ip: True
Many, many thanks in advance!
If the host you want to run the playbook on is not part of your dynamic inventory and at the same time you want to use variables defined in the dynamic inventory in a play for that host, you have to construct an "hybrid" inventory containing both your dynamic inventory ans other static entries.
This is covered in the documentation on inventories: Using multiple inventory sources.
Very basically you have two solutions:
Use two different inventories on the command line:
ansible-playbook -i dynamic_inventory -i static_inventory your_playbook.yml
Create a compound inventory with different sources in a directory. See chapter "Aggregating inventory sources with a directory" in the above documentation.
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"
I have a hierarchy of inventories like this:
inventories
foo
foo1/hosts
foo2/hosts
bar
bar1/hosts
bar2/hosts
Normally, I invoke ansible with explicit full path:
ansible -i inventories/bar/bar1 ....
However, some of the playbooks can run on the combined inventories:
ansible -i inventories/bar ....
This joins the multiple hosts files together, just as I want. However, I do not see a way for the tasks and templates to discern, which particular sub-inventory(ies) the host belongs to.
Is there a way to know about this? Ideally, a host would belong to group(s) based on the inventory file(s) it is listed in...
Yes, it is accessible. Ansible 2.3+ has the following two new magic variables:
inventory_file
inventory_dir
I am trying to set up Ansible to be able to run a playbook according to what inventory group the host is in. For example, in the inventory, we have:
[group1]
host1.sub.domain.tld ansible_host=10.0.0.2
...
[group1:vars]
whatsmyplaybook=build-server.yml
Then we want to make a simple playbook that will more or less redirect to the playbook that is in the inventory:
---
- name: Load Playbook from inventory
include: "{{hostvars[server].whatsmyplaybook}}"
Where the "server" variable would be the host's FQDN, passed in from the command line:
ansible-playbook whatsmyplaybook.yml -e "server=host1.sub.domain.tld"
Our reasoning for this would be to have a server bootstrap itself from a fresh installation (PXE boot), where it will only really know its FQDN, then have a firstboot script SSH to our Ansible host and kick off the above command. However, when we do this, we get the below error:
ERROR! 'hostvars' is undefined
This suggests that the inventory is not parsed until a host list is provided, which sucks a lot. Is there another way to accomplish this?
A bit strange workflow, honestly.
Your setup doesn't work, because most of variables are not defined during playbook parse time.
You may be more lucky with defining single playbook with different plays for different groups (no need to set group var, just use correct host pattern (group name in my example)) and execute it limiting to specific host:
site.yml:
---
- hosts: group1
tasks:
- include: build-web-server-tasks.yml
- hosts: group2
tasks:
- include: build-db-server-tasks2.yml
command to provision specific server:
ansible-playbook -l host1.sub.domain.tld site.yml
You can develop your own dynamic inventory file so that all machines which needs to be bootstrapped will automatically added into your inventory and group respectively with out an manual entry in to the inventory file.
For developing dynamic inventory you can follow the below link:
http://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html
You can include multiple playbooks targeted to different groups as follows.
---
- hosts: all
tasks:
- include: build-web-server-tasks.yml
where: inventory_hostname in groups['group1']
- include: build-db-server-tasks2.yml
where: inventory_hostname in groups['group2']
inventory_hostname is the name of the hostname as configured in Ansible’s inventory host file. This can be useful for when you don’t want to rely on the discovered hostname ansible_hostname or for other mysterious reasons. If you have a long FQDN, inventory_hostname_short also contains the part up to the first period, without the rest of the domain.
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
I am using ec2.py and specific tag on ec2 instances to get my hosts, the results are shown as list of IP addresses, for example:
The results from ec2.py:
"tag_test_staging": [
"10_80_20_47"
],
I define the tag in my playbook - hosts: tag_Name_test and it is run on all the instances with tag_Name_test.
Is there a way to define the hosts/tag in the hosts file under the inventory/ folder and the playbook will take the hosts from there instead of specify the ec2 tag directly on the playbook like now ?
Any suggestions would be appreciated.
You already go to the right direction.
Suppose you got dynamic inventory by ec2.py and it is tag_test_staging. So you can build inventory folder and files as below
inventory
staging
hosts
group_vars
all.yml
tag_test_staging.yml
tag_Name_test.yml
You add the variable define in each YAML file. the variable in tag_test_staging.yml will be only applied to the instance with that tag.
So now you can apply your playbook as:
ansible-playbook -i inventory/staging your_playbook.yml
There is a best practices document on how to use dynamic inventory with clouds, please take a look as well.