It sounds like you want one NFS role that can do both NFS server and NFS client tasks. Were I designing such a role I think I would use a variable or tag to identify which “persona” you want the role to configure, and use that in the tasks/main.yml to source two different task files. One task file would do the work for an NFS server persona. One task file would do the work for an NFS client persona.
I adapted the configuration to your proposal, however it doesn’t work
First all tasks were execetuted on host cmp an then all tasks were again exectuted on the the other machine except cmp.
Regarding to your solution would be necessary to tag both tasks
name: Ensure the appropriate tasks file is imported
include_tasks: “{{ rsyslogd_type }}.yml”
This then includes either tasks/client.yml or tasks/server.yml.
The playbook uses the role like this:
name: Include rsyslogd role
include_role:
name: ansible_role_rsyslogd
args:
apply:
tags: rsyslogd
tags: always
So by default (i.e. for all hosts in the play) the rsyslog client is configured.
The one or two rsyslog servers have set this host_var:
rsyslog_type: server
It’s more or less the same, except that I use a variable to denote the type of deployment, rather than tags, as I find tags more cumbersome to work with.
i once again exactly followed your instruction by copying your published config into the files, because your methon seems comprehensive to me.
However the problem is that the tags are not used which means that both tasks are executed completely twice - first for cmp machine and then for the other machines.
Do you’ve an idea why this happens.
Hi,
I don’t exactly understand your method although it nearly seems to be similar than the version from Walter. Could you probably post more excerpts from the various scripts. Maybe this could help to better get an idea about the context.
Thanks
Te be honest, I’ve never seen the tags keyword applied to at the play level, although https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html clearly says it can be. I suspect the functionality it provides is not what you’re after though, as you seem to be using it in a way that would normally be done with the tags command line parameter. The above mentioned docs says this about tags on a play:
Tags applied to the task or included tasks, this allows selecting subsets of tasks from the command line.
The way I read that is, it’s as if you had put these tags on each task, or had used include_tasks with apply tags […]. You still have to use the command line tags parameter to do any task selection based on tags.
I ran a simple test on tagging plays and it does seem to work as one might assume. I have two simple plays. Each prints a debug message stating what play they are executing. When no tags both plays execute. With a tag only the tagged play executes.
As one more sanity check I ran the sample playbook with a tag not used in the playbook and none of the plays executed. Note the empty Play Recap output
% ansible-playbook -i localhost, foo.yml -t play3
PLAY [play 1 tagged play1] *********************************************************************************************
PLAY [play 2 tagged play2] *********************************************************************************************
PLAY RECAP *************************************************************************************************************
hi, my intention is to migrate various playbooks to absible roles, setting up a system consisting of various machines. i would like to start the new ansible role playbook once doing the whole stuff. one item will be configuring nfs on server and clients. is it a good idea to use one role for this nfs-task and how could i realize it? until now i don’t or whether it works with tags or any other solution or is it in general usual and easier in this case to build two roles one for server and one for client?
There is a unique behavior with plays and roles and tags to be aware of. If you tag a play that calls a role, all tasks in that role are executed if that tag is provided even if there are tasks inside that role that have an alternate tag.
AFTER running the tests below, I edited my sample role to include two debug statements. Each had play1 or play2 as the tag. When I executed the foo.yml playbook with -t play1 then both debug messages are display in play1, but only the play1 debug message is display for play2. It seems to parse the role for play2 to determine if any tasks have the play1 tag (including the roles) and will run them if they exist. It is easier to show than to describe.
I don’t know if this is the expected behavior with ansible. I was surprised by this. I expected the entire play to be skipped if the tag for that play was not specified.
AFTER running the tests IN THE PRIOR MESSAGE, I edited my sample role to include two debug statements. Each had play1 or play2 as the tag. When I executed the foo.yml playbook with -t play1 then both debug messages are display in play1, but only the play1 debug message is display for play2. It seems to parse the role for play2 to determine if any tasks have the play1 tag (including the roles) and will run them if they exist. It is easier to show than to describe.
hi,
and where/how does your solution differ to mine? why did you place the tasks in the playbook and not in the role-tasks? how does your my_role task look like?
I was using your original playbook as my starting point. It had tags in the plays. If you remove the tags in the plays and leave the tags in the role tasks it behaves as expected. Each play runs the role, and only the tasks with the named tag execute.
hi,
would it be possible to post the relevant content of all these necessary files (excerpt in one of my previous posts) for installing nfs on server and client using one ansible role. That allows me to understand and reproduce it.
I think it makes sense to put both the client and server tasks in the same role, especially if you have some hosts which are both nfs clients and nfs servers.
However, I would recommend that you not use the tags keyword at the play level. It’s a short cut way to add a tag or tags to every task involved in the play. While there must be some problem for which that is a solution, you don’t have such a problem, at least not in my opinion.
A more straightforward approach would be to use host groups. Let’s say you have host groups rg_nfs_clients and rg_nfs_servers. Then in your nfs/tasks/main.yml you have something like
---
# my_playbook.yml
- name: Configure NFS
hosts: all # <-- or any subset of "all"
become: true
roles:
- nfs
Whatever hosts you throw at it, it’s only going to put nfs server configs on hosts in your rg_nfs_servers group, and likewise it will only configure your rg_nfs_clients members as nfs clients. For hosts that are in neither group, it will do nothing.
The “tags: always” on those ansible.builtin.includes are so that, if you ever do put tags on the included task files tasks, you can still make use of those tags from the command line. It ensures the include tasks happen even when faced with otherwise task-limiting command line tags.