Suppose I have a host that is, among other things, a web server, where the related Ansible role installs nginx, performs some essential configuration in /etc/nginx, and opens up ports 80 and 443 in the firewall.

At some point I want that particular host to not be a web server any more, because for some reason I moved that service elsewhere. Just removing the server from [webservers] in the inventory would leave garbage in the server. Ideally, I'd like to uninstall nginx, remove the /etc/nginx directory (and some other directories), and close up ports 80 and 443 in the firewall.

In Puppet I can do this. A host that is a web server will have something like this in its configuration:

class { 'nginx':
  ensure => present,

and all I have to do is to replace "present" with "absent". If the nginx class is well-written, it will undo the changes it has made. (Typically an administrator will replace "present" with "absent", and later, when he's certain that all affected hosts have undone the configuration, he will remove the item from the manifest.)

What's more, I think that the Puppet firewall module automatically removes firewall rules that can't be found in the manifest any more; so I think that, for the firewall, you don't even need to do that "absent" thing above, the firewall will automatically close up anyway.

How can I achieve these things with Ansible?

  • 1
    Hypothetical questions are not really on topic here I think, although your question itself is not without merit. Instead of "let's pretend ..." rephrase and say for instance "In puppet I can change a server role and uninstall nginx which was installed previously by changing ensure => present to ensure => absent which will also... How to do the same with ansible" etc. Ideally with an example of anything you have already tried. – HBruijn Jul 11 '14 at 20:34
  • 2
    I would argue Ansible isn't really designed for this sort of thing. It's targeted at reproducible, disposable servers. If you don't want a machine being a webserver any more, you just wipe it (or terminate it if it's a cloud instance) rather than repurposing it. – ceejayoz Jul 11 '14 at 21:29
  • @ceejayoz the most I've read about Ansibles is in Orson Scott Card Card's Ender's Game & sequals but what you say makes a lot of sense in cloud orchestration – HBruijn Jul 11 '14 at 22:48
  • @ceejayoz: I currently don't use Ansible for multi-server setup, but to configure small autonomous servers. I think this is a valid use. So a server can have nginx+django+PostgreSQL. If later I decide to put nginx or nginx+django elsewhere, wiping out the whole server and needing to bring back PostgreSQL from the backup would seem suboptimal (not to mention the downtime). – Antonis Christofides Jul 12 '14 at 8:28

With Ansible, you wouldn't really do this any differently from how you would do it with Puppet.

In your example where you would set

class { 'nginx':
  ensure => absent,

you are relying on the author of that puppet module having written the necessary code to deal with removing everything. Not every puppet module has this.

Similarly, with Ansible, you might have roles that have both the necessary steps to install it as well as to remove it. The difference is only in how to invoke the two.

One approach could be one where the role in question exposes a variable to toggle the behaviour. For example, that nginx role might take a variable nginx_state which takes the values installed and absent.

In the role's tasks/main.yml, the role author might have something along the lines of..

- include: install.yml
  when: nginx_state|default('present') == "present"

- include: uninstall.yml
  when: nginx_state|default('present') == "absent"

..with the respective install/uninstall logic being split up between those two conditionally-included files.

Ansible roles can also be nested. As another way to do the same, a role author might for example provide a role nginx with another role inside of it, called uninstalled. You could then do:

- name: Uninstall nginx
  hosts: some_group
    - nginx/uninstalled

Ansible, when compared to Puppet, arguably has fewer rules and guidelines about how things should be done so practices vary a bit more out in the wild, but the same concepts apply.

  • 1
    While technically you can also pass arguments straight into the roles, I would recommend using the nested role. I would find it really strange seeing in a playbook some role, that will actually get uninstalled on playbook execution since in the variables it's defined as such. Having it explicit via the nested role seems so much cleaner. Technically it's possible to pass arguments to the role (- { role: nginx, state: absent }) but it seems to me extremely verbose. The only drawback to the nested role that I've seen was that I needed to link the default vars from the parent. – bogdan.mustiata Mar 29 '17 at 9:39
  • What do you need to do for something like roles: -nginx/uninstalled to work? I've looked all over the place, but can't find any documentation on nesting roles in a way that would allow me to do that. – aggregate1166877 Mar 28 at 3:00

Since you have your configuration/provisioning in Ansible, you can simply blow away the whole server, reinstall/provision a fresh one and have a nice clean known state to work it.

If you actually want to "reconfigure" it for other purposes then you'd need to create a new playbook that performs the necessary clean up tasks.

As far as I'm aware, all Ansible packaging modules support state=absent to ensure that a given package is not installed on your server. Additionally, apt module has purge=yes parameter which will clean up any remaining customized config files.

You could also create tasks to confirm that port 80 is firewalled. However, since you won't have any processes running on that port, firewalling it won't make any difference to the security of your server.

  • To add to this, I'm betting most of the plays in that role could have state=absent added. There's a good chance that would delete or undo a good majority of the configuration changes you've made. Depending on how big the role is, this might be a real PITA to test. – Christopher Karel Jul 12 '14 at 14:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.