Roles install/uninstall process best practices

3,972 views
Skip to first unread message

Trevor G

unread,
Sep 10, 2014, 7:48:59 PM9/10/14
to ansible...@googlegroups.com
It's great that I can easily pull in different roles into my playbooks.  By default, anything under tasks/main will get run (usually as an installation process).  I was wondering if there were any best practices for packaging a list of uninstall tasks within the role as well to undo any changes that were done in the installation process.

One thought was to have my main task file in my role to have something like:

---
- include: install.yml
  when: install == "y"

- include: uninstall.yml
  when: install != "y"


and by default, the install variable would be set to "y".  Then when I run the playbook, I'd use --extra-vars to set the "install" variable to "n" if I wanted to uninstall software.  The downside is that the conditional task include will dump out that the tasks that are being skipped.  This ends up cluttering the output and making things confusing, especially when there's a lot of installation and uninstall tasks.

Another option would be to create a new role for uninstalling the software, but that is cumbersome and then requires someone to pull down two different roles and makes tasks that should be closely related much more separated and harder to manage.

Is this the best practice for handling this use case?  Is there some sort of "include_task" type feature that would allow one to include a bunch of tasks without applying the condition to every individual task?

Thanks,
  Trevor




Michael DeHaan

unread,
Sep 11, 2014, 10:27:04 AM9/11/14
to ansible...@googlegroups.com
Generally uninstalls aren't frequent.

The reason for this is you don't know what software someone *manually* installed that you don't want present.

One method might be to have a list of packages in something like group_vars/<groupname> called "uninstall_packages"

and then just:

- yum: name={{item}} state=absent
  with_items: uninstall_packages

Which would be a reasonable solution.  

We do somewhat similar things in our Tower install playbooks when we no longer use a particular subcomponent.



--
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.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/3b723b8f-87ff-4b6e-b640-b95c92611a28%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Trevor G

unread,
Sep 11, 2014, 5:42:50 PM9/11/14
to ansible...@googlegroups.com
Ok, thanks for the suggestion.  I've gone through a few different iterations of ideas and I think I'm just going to punt on the problem and assume we're going to be using phoenix servers most of the time.  It would have helped to be able to include a role and be able to pass the tagged tasks to run or to skip.  For example:

roles:
  - { role: myrole,      run_tags: service_restart  skip_tags: datastore }
  - { role: anotherrole, run_tags: install_configs,service_restart }
  - { role: finalrole,   skip_tags: service_restart }


That way, you can just run the playbook as is, but don't have to pass a whole lot of flags in from the command line which may conflict across roles anyways.

 Thanks,
  Trevor

Michael DeHaan

unread,
Sep 11, 2014, 8:37:41 PM9/11/14
to ansible...@googlegroups.com
Roles do not have a "run_tags" or a "skip_tags" -- the "tags" on a role will apply the tag to anything in the role, as it should.

--tags and --skip-tags are arguments to ansible-playbook.

I wouldn't teach a role to uninstall itself in most cases.

In most cases, you want to be able to rebuild that system from scratch, so if you had to undo something of that severity, you would use ansible to rebuild the box.

For simpler things, just maintain a list of packages to remove, that should be sufficient.  And maybe users.



Trevor G

unread,
Sep 19, 2014, 7:06:05 PM9/19/14
to ansible...@googlegroups.com
Yeah, I agree.  I'm finding the use case for uninstalling software to be rare and much harder than just building a new machine from scratch.

I am finding, though, that it would be helpful to be able to choose what tags to be run or skipped for a role, though, by specifying it when writing a playbook, rather than via the command line.

For instance, I could write a role for a piece of software that allows it to be installed for apache or nginx.  The different configs should be with the role, but at playbook writing time, it would be very useful to be able to choose what tagged tasks to run for that group of hosts.  For instance:

--- inventory.ini ---
[groupA]
apache01
apache02

[groupN]
nginx01
nginx02


--- deploy_mysoftware.yml ---
- hosts:  groupA
  roles:
    - { role: mysoftware, run_tasks: install,config_apache }
    - { role: apache, run_tasks: restart_service }

- hosts: groupN
  roles:
    - { role: mysoftware, run_tasks: install,config_nginx }
    - { role: nginx, run_tasks: restart_service }


With this playbook, I could easy write ansible-playbook deploy_mysoftware.yml -i myinventory to deploy my software and restart the appropriate services depending on the server group.  This is nice and compact.  In addition, if something gets changed in the software's interaction with the webserver software, I can just update the mysoftware role config templates and everything is good.  This allows roles to be more rich in the set of tasks they need to accomplish, yet gives the flexibility to run only a portion of those tasks.

I think one solution would be probably to create a mysoftware role, plus a mysoftware_nginx and mysoftware_apache role, which then begins to disassociate code and configs that should probably be more closely coupled together.  Also the restarting of the service task could not be singled out from the installation of it.  I think one would probably have to create a separate role for just restarting the service, or would have to duplicate those tasks across playbooks.

An alternate solution would be to pass --tags and --skip-tags via the command line, but then I have to make sure I don't accidentally mistype something, or I write a two liner script that just calls ansible-playbook with the right arguments (requiring yet another file).  That wouldn't solve the problem, though, if two roles end up using the same tags, such as 'install', which is very common.  The playbook without run_tasks would be:

--- deploy_mysoftware.yml ---
- hosts: groupA
  roles:
    - { role: mysoftware }
    - { role: apache }

- hosts: groupN
  roles:
    - { role: mysoftware }
    - { role: nginx }



In the above example, I wouldn't be able to write ansible-playbook deploy_mysoftware.yml -i myinventory --tags=install,config_apache,config_nginx,restart_service because the config_apache,config_nginx would end up getting applied to both groupA and groupN and install would get applied to apache and nginx, which is not the desired outcome of that particular playbook.

Thanks,
  Trevor
Reply all
Reply to author
Forward
0 new messages