Proper way to rollback an action if failed

3,475 views
Skip to first unread message

PePe Amengual

unread,
Apr 30, 2013, 5:45:43 PM4/30/13
to ansible...@googlegroups.com
Hi.

I have been thinking to replace a webistrano deployment since is really slow and I don't want to learn or ruby or capistrano so I was thinking to do all the deployment with ansible.

One nice thing that webistrano/capistrano does is the roll back but I have to say that is shitty roll back since you could run some db updates and then if one of your task is simply creating a dir after the db update the code could be rolled back but db changes were made already ( easy to fix with a temporary deployment db but it is slow)  so I will like to do a better version of it.

so my questions are :

is there a way to catch an error while running a playbook ( like trap in bash) ?

Can I use the exit code on only_if to run a a rollback playbook ?

Basically for now I just want to be able to re-link a release if one of the commands failed.

Thanks.

Brian Coca

unread,
Apr 30, 2013, 5:50:09 PM4/30/13
to ansible...@googlegroups.com
register: variable, gets you the return codes

ignore_errors, lets you continue a play and deal with the errors yourself (normally ansible will stop the run for that host).

--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno
Message has been deleted

Brian Coca

unread,
Apr 30, 2013, 7:51:51 PM4/30/13
to ansible...@googlegroups.com
I'm not sure I understand what you want to do, maybe drop by irc to have a quick chat and figure out a solution.
(por cierto, hablo Espanyol si te es mas facil).


On Tue, Apr 30, 2013 at 6:44 PM, Pepe (Jose) Amengual <jose.a...@gmail.com> wrote:

So I guess now the question is that if is possible to catch and error on an action because if I use ignore errors I could get pretty ugly.

Register: is a possibility but the I gain if I use for example the file module to create a link and it fails then that will not be in a register so I will have to use command instead ?

Thanks.

--
You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/nWtHpwJ9eCI/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Message has been deleted

Brian Coca

unread,
Apr 30, 2013, 8:01:07 PM4/30/13
to ansible...@googlegroups.com
to use register add ignore errors, just to that task, that means, task fails but playbook continues. so if file link fails, the next task can do something about it

PePe Amengual

unread,
Apr 30, 2013, 8:03:35 PM4/30/13
to ansible...@googlegroups.com
Sorry My phone and the stupid autocorrection.

here is a better version of my message.

So I guess now the question is that if is possible to catch and error on an action because if I use ignore errors I could get pretty ugly.

Register is a possibility but then gain if I use it for example with the file module to create a link and it fails creating the link then that will just exit and I will not be able to do any further action, so to use a register I will have to use the command or shell module that is not that ideal.

It will be awesome to have something like if_fail or undo_if or something like that.

 Thanks.

Brian Coca

unread,
Apr 30, 2013, 8:16:35 PM4/30/13
to ansible...@googlegroups.com
Let me explain with example:

- hosts: 127.0.0.1                                                               
  connection: local                                                              
  gather_facts: False                                                            
  tasks:                                                                         
   - file: path=/var/tmp src=/tmp state=link                                     
     register: file_result                                                       
     ignore_errors: True                                                         
                                                                                 
   - debug: msg="file failed, should do something here!"                         
     when_failed: $file_result   

PePe Amengual

unread,
Apr 30, 2013, 8:24:23 PM4/30/13
to ansible...@googlegroups.com
Ohh I see that will work perfectly.

Gracias Brian.

PePe Amengual

unread,
Apr 30, 2013, 8:29:41 PM4/30/13
to ansible...@googlegroups.com
mmm now I have another question.

What If I have an action with ignore_errors: True and then I have a when_failed that will revert back the last action but at that point I want the playbook to stop.

can I use when_failed to stop the playbook ?( sounds hacky, it's like a brake and I don't like it )

Can I use only_if for all the rest of the tasks to check against the register variable ( of the failed action)?

Thanks.


Brian Coca

unread,
Apr 30, 2013, 8:30:58 PM4/30/13
to ansible...@googlegroups.com
add 

- fail: msg="aborting now that i tried to rollback"
   when_failed: $file_result

Michael DeHaan

unread,
Apr 30, 2013, 9:09:26 PM4/30/13
to ansible...@googlegroups.com
It's pretty common creed in the DevOps community that rollbacks are a lie :)

Always fail forward, fix the issue, and so on.

This is why using Ansible to work with load balancers is great... if the node fails, it fails while it is out of rotation, and your rolling update slice is smaller than your total node pool count, so you never hit outage.

Deploying the playbook to say "be at this version" is fine, but yes, database updates are always a level of complexity.

If you are using 1.2, the "when_failed" stuff is the legacy form, it is actually a little simpler now:

when: file_result.failed

You may wish to use "any_errors_fatal: True" (a 1.2 feature) in your playbook to say that the first error stops the breaks, but I think a serial update window is more appropriate.




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Pepe (Jose) Amengual

unread,
May 1, 2013, 1:57:09 AM5/1/13
to ansible...@googlegroups.com
Thanks guys, this is what I need.

I will build the playbook and test it tomorrow.


--
You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/nWtHpwJ9eCI/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.

Siarhei

unread,
Jul 3, 2014, 4:46:05 PM7/3/14
to ansible...@googlegroups.com
Sorry, but I don't think it's a good approach.
I will explain why with the example.
I have to install some "heavy environment" on cloud. In the beginning of the playbook I'm creating an instance of OracleDB (another host), and will use it for the main application which I'm installing in this playbook.
So, if it's "heavy environment" i will have hundreds tasks, and if something fails, I need to terminate OracleDB box as well. But how??? If I will use your suggestion I will have to set ignore_errors after each task (!!!! of hundreds), and I will duplicate the same code of termination my Oracle box after every task. It will work, but it will be the ugliest playbook.

Or bit better way  (for this example): to use 2 playbooks in one shell script. If first fails second will be running for rollback actions. 

But and this is not a good solution. As I see Ansible needs some tasks (like handlers) that will be executed if something breaks. 

среда, 1 мая 2013 г., 3:16:35 UTC+3 пользователь Brian Coca написал:

Michael DeHaan

unread,
Jul 3, 2014, 6:04:52 PM7/3/14
to ansible...@googlegroups.com
We intend to add a facility for a try/except type handler in the near future.




Reply all
Reply to author
Forward
0 new messages