Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible - Default/Explicit Tags

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?

like image 256
nfarrar Avatar asked Mar 01 '15 03:03

nfarrar


People also ask

What are the tags in Ansible?

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.

Which tag is executed by default while running a playbook?

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 .

How do you define vars in Ansible?

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!

What is the default location for Ansible?

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.


2 Answers

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' ]}
like image 135
Zdenek R Avatar answered Oct 28 '22 07:10

Zdenek R


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.

like image 20
udondan Avatar answered Oct 28 '22 07:10

udondan