I have a role wp-vhost
that has one role it depends on:
// roles/wp-vhost/meta/main.yml
---
dependencies:
- { role: nginx }
Each time I run wp-vhost
, the nginx
role will also run. I understand that this is fine and it's a desired behavior.
However, during my local development, time is unnecessarily lost on running the nginx
role, when I want to run only the tasks defined in wp-vhosts
since I know that nginx
had run before and set-up the necessary environment for wp-vhost
.
Is there a way to execute a playbook with roles, without executing roles' dependencies?
Meta tasks are a special kind of task which can influence Ansible internal execution or state. Prior to Ansible 2.0, the only meta option available was flush_handlers . As of 2.2, there are five meta tasks which can be used. Meta tasks can be used anywhere within your playbook.
There is no way to directly execute a role. Roles have no explicit setting for which host the role will apply to. Top-level playbooks are the bridge holding the hosts from your inventory file to roles that should be applied to those hosts.
You can do this with Ansible tags. Using tags to execute or skip selected tasks is a two-step process: Add tags to your tasks, either individually or with tag inheritance from a block, play, role, or import. Select or skip tags when you run your playbook.
yml exists, Ansible adds the variables in that file to the play. If roles/x/meta/main. yml exists, Ansible adds any role dependencies in that file to the list of roles.
The way I would do this is to use Ansible tags and apply them to your "wp-vhost" specific code.
Assuming your wp-vhost
role's main playbook is in main.yml
, a good pattern is to spin out the actual tasks into a sub-playbook called something like wp-vhost.yml
, included from main.yml, so the non-nginx code gets a tag that doesn't get applied to the nginx role. In this case:
- include: wp-vhost.yml
tags: wp-vhost
In order to use a tag for every chunk of Ansible code (whether an included tasks file or a role), try writing every role mentioned in dependencies
like this:
- role: nginx
tags: nginx
When in testing mode, you can run just the wp-vhost specific parts like this:
$ ansible-playbook --tags wp-vhost main.yml
Or you can run the whole playbook including any dependencies like this - default is to run everything ignoring tags:
$ ansible-playbook main.yml
This makes it easy to quickly run just parts of a complex set of cascading roles and include files when testing, and also use the wp-vhost role normally in other roles' dependencies.
Impact on role structure
Careful use of tags doesn't affect role structure or use at all, and you would typically use tags only for testing.
For more complex roles, it's common to structure the tasks into separate files in any case, keeping the main.yml simple, like this:
- name: Set up base OS
include: base_os.yml
tags: base_os
- name: Ensure logs are rotated
include: logrotate.yml
tags: logrotate
- name: Create users and groups
include: users_groups.yml
tags: users_groups
Solution without include files
If you don't want to change the wp-vhosts use of include files, you would need to use blocks in the playbook (Ansible 2.0+):
- hosts: all
roles:
- role: nginx
tags: nginx
tasks:
- block:
- debug: msg=hello
- someaction: ...
tags: wp-vhosts
Note that the final tags:
is aligned with the block:
so applies to all tasks in that block. This is cleaner than splitting the playbook into multiple plays.
Non-tag alternative
You can use a when:
condition on the role invocation in the wp-vhost role dependencies, and define a variable such as debug_mode
to control this. However, such debug/test logic will clutter your codebase compared to defining a tag per role invocation or task file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With