Group multiple ansible tasks under a single conditional
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:
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.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)
You can add
when
clauses to each of your tasks individually.You can use parameters for the
shell
and other modules likecreates
orremoves
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.
Comments
-
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 over 8 yearsthanks 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 over 7 yearsIt is possible with ansible<=1.9, using include