Ansible: specify inventory file inside playbook - ansible

So from what I gather, we can use ansible.cfg to set the default inventory file that ansible looks for when running a playbook.
We can also override that inventory by using the -i parameter when running an ansible playbook via the command line.
Is there a way for me to specify a specific special inventory file inside a playbook without using the command line or changing the ansible.cfg file?

You can form a dynamic inventory from inside your playbook using add_host module.
But you will have to write some inventory files parsers to feed correct parameters to add_host.
In general this is the wrong way to go. You should have playbooks and inventories separated.

Related

Ansible overwrites which variable? Inventory parameter or extra parameters at runtime?

I have a parameter pkg for all hosts of an envrionment specific inventory.
[atlanta]
host1
host2
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
pkg=123
Now if I use the same variable pkg while executing an ansible playbook ex. ansible-playbook xyzzy.yml -e "pkg=123" with some different value. Which one will be picked by Ansible ? The value that is associated with pkg at Inventory level or the one given at runtime in command ?
Extra variable (i.e. vars given at runtime) override all other variables. Inventory variables will be overriden by extra variable given at runtime. In detail, precedence is such as:
Here is the order of precedence from least to greatest (the last listed variables winning prioritization):
...
inventory file or script group vars
inventory group_vars/all
playbook group_vars/all
inventory group_vars/*
playbook group_vars/*
inventory file or script host vars
inventory host_vars/*
playbook host_vars/*
...
extra vars (always win precedence)
The doc is indeed a bit confusing. For clarification:
inventory file or script group vars are variables associated to groups in your inventory files. In your case, everything under atlanta:vars are inventory file group vars
[atlanta:vars]
pkg=123
inventory file or script host vars are variables associated to a specific host and would have higher precedence other inventory file or script group vars, for example:
[atlanta]
host1 pkg=override-123
host2
inventory group_vars/all|* are variables defined under inventories group_vars/ folder such as $PLAYBOOK_DIR/inventories/my-inventory/group_vars/atlanta/main.yml
playbook group_vars/all|* are variables defined under playbook group_vars/ folder such as $PLAYBOOK_DIR/group_vars/atlanta/main.yml
inventory host_vars/* are variables under inventories host_vars/ folder such as $PLAYBOOK_DIR/inventories/my-inventory/host_vars/somehostname.yml
playbook host_vars/* are variables under playbook host_vars/ folder such as $PLAYBOOK_DIR/host_vars/somehostname.yml
See Ansible doc on variable precedence.
You may also want to check out Directory Layout and Alternative Directory Layout for a better understand regarding all these directories and files.

How to use Ansible inventory file created by a playbook?

I have a playbook that reads in a custom config file and creates a valid Ansible inventory in YAML then continues with other Ansible roles. The problem is when I specify the not-yet-created hosts file in my ansible.cfg, it only reads the file in the beginning so when I want to continue with my tasks, I get a "provided hosts list is empty" warning. Is there a way I can get the inventory file to "reload"? I attempted a dynamic inventory script in python, but the syntax is more complicated then the simple static YAML or INI configuration.
Use a meta task:
- meta: refresh_inventory
Docs:
https://docs.ansible.com/ansible/latest/modules/meta_module.html

Ansible: Read variables from properties file

I am trying to translate some shell scripts to ansible playbooks.
In the shell scripts there are a lot of variables that are read from a separate properties file in which these variables are defined.
Is there some module or some other way that I can do this. For example,
if in the properties file I have
$WORKDIR=/opt/app defined and in the ansible playbook I want to call some module for example,
copy:
src: /tmp/app
dest: $WORKDIR/
Is there a way to do this?
Thanks
Use lookup (doc)
Example:
{{ lookup('ini', 'user.name type=properties file=user.properties') }}
user.name, property key you want to read
user.properties, property file you want to read from
Yes, in ansible the inventory is the file where we define the hostname or ips along with variables.
Whenever we execute ansible playbook we pass a file using --inventory inventory ----> this is the default way of passing an inventory file
The playbook will source this file and all the variables defined inside it can be used.
In ansible the variable substitution happens using {{ WORKDIR }}
There are other ways of passing variable to playbook.
Such as
-- include_vars
-- using roles
-- defining vars inside playbook.
-- extra vars

Is path of the inventory file accessible to playbooks?

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

ansible - define hosts/tag from dynamic inventory in the host file

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.

Resources