Ansible: execute role only for some hosts

tvs picture tvs · Oct 13, 2016 · Viewed 13.8k times · Source

Let's say I have a single playbook with some roles for the installation of an appserver and I like to apply the same playbook on both production and testing servers.

Both production and testing servers have the same list of roles, with the exception of one, that only should be applied on production servers.

Is it possible to specify somehow that this role will only be applied to production servers using the same playbook?

For example, if the playbook is:

---
- hosts: appserver
  roles:
    - { role: mail, tags: ["mail"] }
    - { role: firewall, tags: ["firewall"] }
    - { role: webserver, tags: ["webserver"] }
    - { role: cache, tags: ["cache"] }

and I have two inventories: one for production and one for testing.

When I run the playbook using the testing inventory, I don't want the role 'firewall' to be executed.

My idea is do something like setting a variable in the 'production' inventory and use something like 'if <var> is set, then execute role 'firewall'' ... I don't know if this is possible, and if it is, how to do it?

Answer

techraf picture techraf · Oct 13, 2016

You can define a variable, for example production_environment, in your inventory files, assign true or false value and use a when conditional in the playbook:

---
- hosts: appserver
  roles:
    - { role: mail, tags: ["mail"] }
    - { role: firewall, tags: ["firewall"], when: production_environment }
    - { role: webserver, tags: ["webserver"] }
    - { role: cache, tags: ["cache"] }

Or you can access inventory_file variable directly. For example if you use -i production:

---
- hosts: appserver
  roles:
    - { role: mail, tags: ["mail"] }
    - { role: firewall, tags: ["firewall"], when: inventory_file == "production" }
    - { role: webserver, tags: ["webserver"] }
    - { role: cache, tags: ["cache"] }

Which way you go is an administrative decision. The second method uses less steps, but requires the inventory file name to be "hardcoded" in the playbook.