Schedule Meeting

a

How to skip an Ansible task by default

by | Feb 2, 2021 | Database Automation, MariaDB

Ansible has a well-known mechanism to only run a certain list of tasks: tags. When we call ansible-playbook with the --tags parameter, we only execute tasks that have one of the specified tasks. There is also a --skip-tags option, which runs all tasks except those with the specified tags. But when we don’t specify any of them, all tasks are run. So we occasionally need a feature that is the opposite of a tag: skipping a set of tasks unless we specify that we want to execute it.

We can use environment variables to skip a task by default. This article shows how to do it, and an example use case.

Skipping Ansible tasks by default
Blixy is skipping some Ansible tasks

Skipping a task by default

It makes sense to have a task that removes MariaDB data directory:

- Create a file
  file:
    path: /tmp/TASK_HAD_RUN
    state: present
  when: create_file is defined and create_file == '1'

The task shouldn’t need any explanation, except for the when property:

  • It only runs the task if a create_file exists and is set to 1;
  • By default it doesn’t exist and the task won’t run;
  • We need to check if it exists first because, if it doesn’t, the second condition would fail with an error;
  • create_file can be an environment variable.

To pass Ansible an environment variable:

ansible-playbook -i production-mariadb -l mariadb-main -e 'create_file=1' production-mariadb.yml

Example: deleting MariaDB data directory

Solving this kind of theoretical problems is cool, but there are also very practical reasons to skip a task by default.

...

- Destroy MariaDB datadir
  file:
    path: "{{ mariadb_datadir }}"
    state: absent
  when: init_db is defined and init_db == '1'

- Create MariaDB datadir
  file:
    path: "{{ mariadb_datadir }}"
    state: directory

# install MariaDB...

...

Ansible is generally idempotent. The second task will be run if the data directory is not there, and will not be run if it is there. In other words, if the data directory exists it will remain unchanged, and it it doesn’t it will be created. Then MariaDB installation can continue. So in theory there is no problem.

But sometimes we may want to destroy the data directory and start again with an empty one. This could happen, for example, if data is corrupted and we need to restore a backup taken from another replica.

However, destroying the datadir is a potential disaster. Most of the times we call Ansible, we don’t want to do such a thing. Maybe we just want to change some configuration variable, or change the MariaDB version – but data should definitely not be erased.

The when property in the snippet allows us to achieve this purpose. The datadir will only be destroyed if we specify init_db=1.

Conclusions

We discussed how to write an Ansible task that is not executed by default. As an example, we discussed that this technique allows to create a rarely used task to destroy MariaDB data directory.

Federico Razzoli

If you need expert help at automating your database infrastructure, consider our Database Automation service.

Did you like this article?

All content in this blog is distributed under the CreativeCommons Attribution-ShareAlike 4.0 International license. You can use it for your needs and even modify it, but please refer to Vettabase and the author of the original post. Read more about the terms and conditions: https://creativecommons.org/licenses/by-sa/4.0/

About Federico Razzoli
Federico Razzoli is a database professional, with a preference for open source databases, who has been working with DBMSs since year 2000. In the past 20+ years, he served in a number of companies as a DBA, Database Engineer, Database Consultant and Software Developer. In 2016, Federico summarized his extensive experience with MariaDB in the “Mastering MariaDB” book published by Packt. Being an experienced database events speaker, Federico speaks at professional conferences and meetups and conducts database trainings. He is also a supporter and advocate of open source software. As the Director of Vettabase, Federico does business worldwide but prefers to do it from Scotland where he lives.

Recent Posts

MariaDB Catalogs: some use cases

MariaDB Catalogs: some use cases

This month I attended Monty’s talk about Catalogs at MariaDB Server Fest 2023 in Helsinki. He described this nice feature, which is still under development, and how it will work. But when he talked about the use cases, I was under the impression that catalogs have...

MariaDB/MySQL: working with storage engines

MariaDB/MySQL: working with storage engines

MariaDB and MySQL support several storage engines. See MariaDB and MySQL storage engines: an overview for a discussion about existing MariaDB and MySQL storage engines. Here we'll see how to work with them. We'll see how to obtain information about storage engines,...

MariaDB and MySQL storage engines: an overview

MariaDB and MySQL storage engines: an overview

MySQL was the first DBMS to introduce the concept of storage engines in the early 2000s. This was one of its main features. Later, MariaDB extended the storage engine API and included some storage engine maintained by third parties as part of its official...

Services

2 Comments

  1. Faustin

    Hi Federico!
    That’s indeed a very good practice to skip tasks, I would suggest a different approach that simplify drastically the `when` (in an ansible role context).

    1/ in `roles/defaults/main.yml`, define the variable at false, see
    https://github.com/fauust/ansible-role-mariadb/blob/master/defaults/main.yml#L4

    2/ use `when: my_variable` in the role playbook task, see https://github.com/fauust/ansible-role-mariadb/blob/master/tasks/setup.yml#L9

    Also, this way, the `defaults/main.yml` is a “way” to document your roles.

    Cheers!

    Reply
    • Federico Razzoli

      Hi Faustin!
      I agree, it is a good idea to set a default and then avoid checking if the variable is defined.

      Cheers,
      Federico

      Reply

Submit a Comment

Your email address will not be published. Required fields are marked *