23
votes

I have a playbook with multiple hosts section. I would like to define a variable in this playbook.yml file that applies only within the file, for example:

vars:
  my_global_var: 'hello'

- hosts: db
  tasks:
   -shell: echo {{my_global_var}} 

- hosts: web
  tasks:
   -shell: echo {{my_global_var}} 

The example above does not work. I have to either duplicate the variable for each host section (bad) or define it at higher level, for example in my group_vars/all (not what I want, but works). I am also aware that variables files can be included, but this affects readibility. Any suggestion to get it in the right scope (e.g the playbook file itself)?

3
You may be interested in PR #13787 which implements exactly what you're looking for (and also playbook-wide vars_prompt).Thomas Quinot

3 Answers

16
votes

The set_fact module will accomplish this if group_vars don't suit your needs.

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html

This module allows setting new variables. Variables are set on a host-by-host >basis just like facts discovered by the setup module. These variables will >survive between plays during an Ansible run, but will not be saved across >executions even if you use a fact cache.

- hosts: db:web
  tasks:
  - set_fact: my_global_var='hello'

- hosts: db
  tasks:
  -shell: echo {{my_global_var}} 

- hosts: web
  tasks:
  -shell: echo {{my_global_var}} 
5
votes

I prefer to keep global variables in the inventory file, where you keep the groups and names of your hosts.

For example:

my-hosts:

[all:vars]
my_global_var="hello"

[db]
db1
db2
[web]
web1
web2

Run your playbook with:

ansible-playbook -i my-hosts playbook.yml

The variable will now be defined for all hosts.

If you are using ec2.py or some other dynamic inventory, you can put the global variables in the file group_vars/all to achieve the same result.

0
votes

I have something similar, several variables that are dependent on one, possibly user-specified, variable, that is used in most of my plays (referring to a directory where stuff is). This can be done using one file that contains the plays using the var, and another containing a single play that sets the var and includes the play. EG:

- name: Set global vars, import playbook that uses them
  import_playbook: do-stuff.yml
  vars:
    my_var: with_value
    some_var: "{{ my_var}}"

Here, some_var and my_var can be accessed by all plays in the do-stuff.yml, and the user can overwrite my_var if desired.