Ansible: define variables specific to a role AND inventory file?




|



Let’s say I have a nginx config file created from a template, which I use to configure certain hosts to redirect a server name from http to https:



<br>server {<br> listen 80;<br> server_name {{ server_name }};<br> rewrite ^ https://$server_name$request_uri? permanent;<br>}<br> <br>



Say I have two web sites, each its own Ansible role, hosted on the same machine:

- webvan.com

- pets.com



each has its own server name and each needs the redirection above. At the same time let’s say I have at least two separate deployment configurations, each represented by its own inventory file and its group_vars/ folder, for example:

- local onebox
- production


each using a different server name. So now I have 2 roles * 2 inventories = 4 separate {{server_name}} variable values:

- petsonebox.com
- webvanonebox.com
- pets.com
- webvan.com
I can’t define those variables in the inventory group_vars/ or the inventory file itself, since the inventory doesn’t know about roles, so I’d only have 2 values.
I can’t define those variables under roles/vars since the roles are not aware of what inventory is currently being used.

One possible solution is to define a variable in the inventory like deployment: production, and have each role do a set_fact with a when to define the template’s variable that way. Still feels hacky though, and I’m hoping there might be a more elegant solution.

Any suggestions would be appreciated.


|

Ok, perhaps I am misunderstanding, but why could you not have the following?

  • hosts: pets_servers
    roles:

  • { role: pets_com, some_parameter: 42 }

  • hosts: webvan_servers
    roles:

  • { role: webvan_com, some_other_parameter: “moo” }

Also consider you can seperate the inventory files for pets.com and webvan with “-i” and that’s not a bad thing to do.

I’m not sure either why you say the role isn’t aware of what inventory is being used.

If a server is in group x or group y, the server can use variables from that group easily, within the role, within the template, etc.

Michael,

sorry for taking a while to get back to you, appreciate taking the time to look at this. I think the solution you proposed would work, but I think I totally botched the description of my use case, and so it’s not directly applicable.

Let me give this another shot with more detail. For the sake of the previous example, let’s say I have an api component and a web (a user portal) component, for the same product. This is the part I failed to clarify last time with my example, it sounded like they were two different products that didn’t depend on each other. In my case it’s one product sharing one inventory. My folder structure is as this:

site.yml # links to both api and web hosts.
api.yml
web.yml
inventories/
inventories/localhost/ # localhost deployment
inventories/localhost/hosts # file with all hosts and groups for this environment
inventories/localhost/group_vars/
inventories/production/ # production deployment
inventories/production/hosts # file with all hosts and groups for this environment
inventories/production/groups_vars/
roles/nginx/[…]
roles/user_portal/[…] # for web group
roles/api/[…] # for api group
[more roles]

The way I would deploy would be either:

ansible-plabook -i inventories/localhost/hosts site.yml

or

ansible-plabook -i inventories/production/hosts site.yml

The problem I’m having is that both user_portal and api roles want to use the same exact template for some configuration they want to do, passing 2 different values. Ok that’s easy, you could set a parameter at role level, now each role gets its own parameter. The problem however is that those 2 different values have to depend on inventory as well, they can’t be the same for every environment. So in the http → https web server rule example I made in the first post, the values would be:

I don’t know if the way I organized the ansible project somehow precludes me from getting the solution above, but I can’t immediately see a way of creating this 2x2 matrix of possible values for that 1 template variable. Would appreciate any tip.

Thanks again!

Use parameters to the role for this.

I didn’t quite get what you meant there initially, but I figured out a solution with role parameters as you suggested. I needed to pull out that single nginx rule into its own role and pass different parameters to it.

Thanks, Michael!