I've got a playbook that includes and tags various roles:
- name: base
hosts: "{{ host | default('localhost') }}"
roles:
- { role: apt, tags: [ 'base', 'apt', 'ubuntu']}
- { role: homebrew, tags: [ 'base', 'homebrew', osx' ]}
- { role: base16, tags: [ 'base', 'base16', 'osx' ]}
- { role: nodejs, tags: [ 'base', 'nodejs' ]}
- { role: tmux, tags: [ 'base', 'tmux' ]}
- { role: vim, tags: [ 'base', 'vim' ]}
- { role: virtualenv, tags: [ 'base', virtualenv', 'python' ]}
- { role: homebrew_cask, tags: [ 'desktop', 'homebrew_cask', osx' ]}
- { role: gnome_terminator, tags: [ 'desktop', 'gnome_terminator', ubuntu' ]}
Most of the tasks are using when clauses to determine which OS they should run on, for example:
- name: install base packages
when: ansible_distribution == 'MacOSX'
sudo: no
homebrew:
name: "{{ item.name }}"
state: latest
install_options: "{{ item.install_options|default() }}"
with_items: homebrew_packages
If I run ansible-playbook base.yml
without specifying any tags, all the tasks run. If I specify a tag, for example ansible-playbook base.yml --tags='base'
, only the roles tagged with base run
.
By default (if no tags are specified), I'd only like to run the roles tagged with 'base'
, and not the roles tagged with 'desktop'
.
It would also be really nice to set a default 'os' tag, based on the current operating system, to avoid including all the tasks for the ubuntu when I'm running the playbook on OSX (and vice-versa).
Any ideas if this is possible, and how I might do it?
Tags are metadata that you can attach to the tasks in an Ansible playbook. They allow you to selectively target certain tasks at runtime, telling Ansible to run (or not run) certain tasks.
If you assign the always tag to a task or play, Ansible will always run that task or play, unless you specifically skip it ( --skip-tags always ). Fact gathering is tagged with 'always' by default. It is only skipped if you apply a tag and then use a different tag in --tags or the same tag in --skip-tags .
To define a variable in a playbook, simply use the keyword vars before writing your variables with indentation. To access the value of the variable, place it between the double curly braces enclosed with quotation marks. In the above playbook, the greeting variable is substituted by the value Hello world!
The default location for the inventory file is /etc/ansible/hosts. You can also create project-specific inventory files in alternate locations. The inventory file can list individual hosts or user-defined groups of hosts.
Since Ansible 2.5 there is a new feature which solves these kinds of situations.
Another special tag is never, which will prevent a task from running unless a tag is specifically requested.
Example:
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
So your problem should be addressed like this:
- name: base
hosts: "{{ host | default('localhost') }}"
roles:
- { role: apt, tags: [ 'base', 'apt', 'ubuntu']}
- { role: homebrew, tags: [ 'base', 'homebrew', osx' ]}
- { role: base16, tags: [ 'base', 'base16', 'osx' ]}
- { role: nodejs, tags: [ 'base', 'nodejs' ]}
- { role: tmux, tags: [ 'base', 'tmux' ]}
- { role: vim, tags: [ 'base', 'vim' ]}
- { role: virtualenv, tags: [ 'base', virtualenv', 'python' ]}
- { role: homebrew_cask, tags: [ 'never','desktop', 'homebrew_cask', osx' ]}
- { role: gnome_terminator, tags: [ 'never','desktop', 'gnome_terminator', ubuntu' ]}
Unfortunately there is no such feature. Tag handling in Ansible currently is very limited. You can not set default tags and you can not exclude tags by default.
There are some threads on the Google user group and feature requests on github regarding this. But no outcome yet. The common answer so far is, you should create a shell script and place it in front of your playbook. This script then can set the --tags
and --skip-tags
accordingly to your needs. Very unpleasant but as far as I know the only option right now.
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