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.
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).
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
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.
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)?
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.
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.