Specifying a variable from command line for a specific host

Hello,

Is it possible to set a variable from the command line (using the -e parameter of ansible-playbook) only for a specific host?

Petros Moisiadis wrote:

Hello,

Is it possible to set a variable from the command line (using the -e
parameter of ansible-playbook) only for a *specific* host?

No, extra-vars is global and (will soon) override everything.

Daniel

I'd like to understand your use case, but maybe you are ok with not
doing it on the command line?

Easiest way would be to create a file in host_vars/<hostname>.

You can't do it from the command line, of course, just you could
create a shell script wrapper around something like this.

There is one central ansible inventory on, let’s say, ‘inventory_host’. There are two (or more) hosts, let’s say ‘host1’ and ‘host2’, that can run ansible-based deployments, using vars from the central ansible inventory directory (mounted via sshfs from ‘inventory_host’). Some playbooks have local actions that use a variable named ‘some_variable’ for ‘localhost’, the value of which should be different for ‘host1’ and ‘host2’. Since there is a common, central ansible inventory (and only one ‘localhost’ section in the inventory), there is no way to use one value for ‘some_variable’ when deploying local actions with ‘host1’ being the local machine, and a different value for that variable when deploying local actions with ‘host2’ being the local machine. This would not be a problem if you could override ‘some_variable’ for ‘localhost’ host in the command line. A good example of such a variable, which is actually the one that I would like to set it explicitly in the command line, is the variable ‘ansible_python_interpreter’. If ‘host1’ is an Archlinux-based machine, and ‘host2’ a Debian-based machine, local actions of playbooks deployed from ‘host1’ should use ansible_python_interpreter=/usr/bin/python2 in contrast with playbooks deployed from ‘host2’. So it would be nice if you could do something like the following when deploying from ‘host1’: I have thought of other solutions to the problem, such as using something like unionfs to create a combination of the central inventory with a local host_vars/localhost file, but I would prefer a less complicated setup. Also, the ability to pass vars for a specific host in the command line may apply not only to ‘localhost’ vars, but to other cases too (e.g in case you need to quickly test something for a specific host).

A simple and (imho) elegant solution that I came up with and I would like to share here, is creating on the central inventory host a symlink from ‘/etc/ansible/host_vars/localhost’ to ‘/usr/local/etc/ansible/host_vars/localhost’. So, in each machine I need specific to that machine variables for ‘localhost’ (in local actions), I put them in a local to that machine ‘/usr/local/etc/ansible/host_vars/localhost’ file. However, the ability to override vars for specific hosts in the command line may still be useful for other cases (perhaps on some corner-case scenarios when ansible is being called from other scripts that produce dynamic data).

Another use case for setting host-specific variables on the command line is when you use ansible to launch a cluster job with specific parameters for each host, and you want to do a parameter sweep by wrapping ansible in a bash script that calculates and sets the host-specific parameter values for each loop.

Currently it looks like the only way to do this is to have the bash script indirectly set host-specific parameter settings by writing a group_vars/ file for each with the correct parameter settings before using ansible to launch the job on the cluster.

I don’t understand this.

group_vars/ and host_vars/ files are in fact loaded if the host comes from inventory.

Consider just using

ansible -m …

or

ansible-playbook site.yml --limit hostname

If I’m understanding you correctly, then using the method you suggested to do the job would look something like:

ansible-playbook simulation.yml -limit server1 --extra-vars “parameter1=5 parameter2=42 … parameterM=9” &
ansible-playbook simulation.yml -limit server2 --extra-vars “parameter1=3 parameter2=36 … parameterM=8” &


ansible-playbook simulation.yml -limit serverN --extra-vars “parameter1=6 parameter2=13 … parameterM=7” &

?

In that sort of configuration, I’d find pretty hackish and just go ahead and write the inventory file.

You can keep the variables in the inventory file itself if you like, or use hostvars/ files.