It's not clear to me why this is not working. I can't see a problem. But let me give you some general recommendations, maybe that'll help you too.
Best practice is to have your playbooks on the root level. Have a look at this structure. With that setup, you do not need to specify the path to the roles as Ansible automatically expects roles in the roles
directory relative to the playbook. Then your roles section in the playbook is much cleaner:
roles:
- users
- monitor
Instead of defining global variables to trigger actions inside roles you can use two other approaches.
1. role parameters
Roles can have parameters. If you want to pass parameters you simply have to convert it to a dictionary:
roles:
- users
- role: monitor
sensu_install_client: true
sensu_install_server: true
The variables sensu_install_client
and sensu_install_server
then are available only in the role monitor
. This is a litte more cleaner and also makes it clear to anybody these vars will be used in this role, not in the users
role.
2. tags
Tags actually are the way how to trigger specific parts of a playbook/roles. Tags though are passed from the command line and not by hardcoded variables in the playbook. Imagine your role main.yml
looks like this:
---
# roles/monitor/tasks/main.yaml
- include: common.yml
tags: always
- include: server.yml
tags: server
- include: client.yml
tags: client
The tag always
is special and will run the tagged tasks... well you guessed it... always.
Now you would call your playbook like this:
ansible-playbook monitor.yml --tags server
or
ansible-playbook monitor.yml --tags client
Or if you want to run both you even could do:
ansible-playbook monitor.yml --tags "client,server"
If you use this, don't forget to tag your users role accordingly, or it will not be ran at all.
If you do not specify any --tags
all tasks are executed, if you want to filter specific tags you can use the --skip-tags
option
ansible-playbook monitor.yml --skip-tags "server"
You could even filter the always tag.
ansible-playbook monitor.yml --tags "server" --skip-tags "always"
You could generate your hosts entries from a template. Loop over the list of groups, discard groups like all
and ungrouped
, and then loop over the list of hosts in each group:
{# this loops over the list of groups. inside the loop #}
{# "group" will be the group name and "hosts" will be the #}
{# list of hosts in that group. #}
{% for group,hosts in groups.items() %}
{# skip the "all" and "ungrouped" groups, which presumably #}
{# you don't want in your hosts file #}
{% if group not in ["ungrouped", "all"] %}
{# generate a hosts entry for each host, using the "loop.index" #}
{# variable and the group name to generate a unique hostname. #}
{% for host in hosts %}
{{host}} {{group}}{{loop.index}}
{% endfor %}
{% endif %}
{% endfor %}
The above is using {{host}}
for the ip address, because this lets me tested it out on my system, but you would probably prefer {{hostvars[host]['ansible_default_ipv4']['address']}}
in a real environment, unless you are positive you are always using ip addresses in your inventory.
Best Answer
Host (and group) variables are not stored in the playbook. They are stored separately, in the inventory file itself, or in files in a directory
host_vars
orgroup_vars
relative to the inventory file. These files are named after the host or group for which they contain variables.See Organizing host and group variables in the Ansible documentation for a more complete description of the variable files.