Group multiple ansible tasks under a single conditional

12,415

Solution 1

This is not valid:

- name: getting solr
  when: solr_script.stat.exists == False
  shell: mkdir -p "path to download dir"
  get_url: url="download url" dest= "path to download dir"
  shell: tar zxvf "path to download dir/tgz file" -C "path to solr home"
  shell: rm -rf "path to download dir"

A task consists of a name (optional), one task/module, and modifiers like when, with, etc. You can't have more than one task (in this case shell & get_url) in a task. So you'll need to break this down into multiple tasks:

- name: make solr directory
  file: path=/path/to/download/dir"
        state=directory

- name: download solr
  get_url: url=<url> dest=/path/to/download/dir

- name: unpack solr
  shell: tar xvzf ...

And so on...

To conditionally perform a series of tasks you can do a number of things:

  1. You can use the include statement as you mentioned in your question, which will let you apply a conditional to all the tasks within that include file.

  2. You can create a role that performs all the tasks and again use a conditional to invoke it (or just apply the role to the hosts, etc. that you desire to have the role applied to)

  3. You can add when clauses to each of your tasks individually.

  4. You can use parameters for the shell and other modules like creates or removes which will look for the presence or absence of a file with which to determine whether or not to perform a task.

Solution 2

In Ansible 2.0 it's possible like this:

- block:
    - shell: mkdir -p "path to download dir"
    - get_url: url="download url" dest= "path to download dir"
    - shell: tar zxvf "path to download dir/tgz file" -C "path to solr home"
    - shell: rm -rf "path to download dir"
  when: solr_script.stat.exists == False

Hope this will help you.

Share:
12,415
Zack
Author by

Zack

hello world!

Updated on June 04, 2022

Comments

  • Zack
    Zack almost 2 years

    I am using ansible as a system orchestration tool. First of all, let me describe my eventual goal.

    I want to create a playbook or two that will go grab solr from the web, set itself up, and then start an index based on some configuration. If any of this so far sounds suspect, please stop me here.

    Now, I don't want to grab the solr tarball if I don't have to, so I've currently got a task/play that looks like this.

    - stat: path="path to solr home/solr/bin/init script"
      register: solr_script
    
    - name: getting solr
      when: solr_script.stat.exists == False
      shell: mkdir -p "path to download dir"
      get_url: url="download url" dest= "path to download dir"
      shell: tar zxvf "path to download dir/tgz file" -C "path to solr home"
      shell: rm -rf "path to download dir"
    
    - name: start solr
      shell: "path to solr home/solr/bin/solr init script" start
      sudo: yes
    

    I attempting to check if the solr init script has already been downloaded before going and grabbing it.

    When I ran this script as is, I get the error,

    multiple actions specified in task: 'shell' and 'getting solr' 
    

    That seems reasonable-ish, maybe the formatting is wrong? I tried this

    - name: getting solr
      when: solr_script.stat.exists == False
          shell: mkdir -p "path to download dir"
          get_url: url="download url" dest= "path to download dir"
          shell: tar zxvf "path to download dir/tgz file" -C "path to solr home"
          shell: rm -rf "path to download dir"
    

    Got a syntax error.

    On the ansible documentation page, I see this bit of information.

    Note that if you have several tasks that all share the same conditional statement, you can affix the conditional to a task include statement as below. All the tasks get evaluated, but the conditional is applied to each and every task:
    

    That seems to be getting to what I need.

    But then they follow up with this example.

    - include: tasks/sometasks.yml
      when: "'reticulating splines' in output"
    

    I don't really understand the "include", and the example doesn't seem to illustrate what I want. So, if my initial assumptions are correct and this is indeed how I would want to go about getting solr, how would I write up an ansible task that will conditionally execute a group of tasks.

  • Zack
    Zack over 8 years
    thanks for the kindly advice. I basically ended up just sticking the same "when" clause on all of my tasks, which felt hacky, but ended up working. I did not know about create/removes though, that seems to do what I want without the additional check to see if the file exists. Accepting your answer, your list should be able to help others.
  • radtek
    radtek over 7 years
    It is possible with ansible<=1.9, using include