Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible: execute role only for some hosts

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?

like image 840
tvs Avatar asked Oct 13 '16 00:10

tvs


3 Answers

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.

like image 164
techraf Avatar answered Oct 31 '22 03:10

techraf


Why don't you just use inventory groups? Make two inventories:

testing:

[application]
my-dev-server

production:

[application]
company-prod-server

[firewall]
company-prod-server

And change your playbook as follows:

---
- hosts: firewall
  roles:
    - { role: firewall, tags: ["firewall"] }

- hosts: application
  roles:
    - { role: mail, tags: ["mail"] }
    - { role: webserver, tags: ["webserver"] }
    - { role: cache, tags: ["cache"] }
like image 7
Konstantin Suvorov Avatar answered Oct 31 '22 04:10

Konstantin Suvorov


- { role: firewall, tags: ["firewall"], when: MyVar }

See Applying ‘when’ to roles and includes.

like image 3
gile Avatar answered Oct 31 '22 03:10

gile