On Wednesday, August 27, 2014 10:45:14 PM UTC+1, Michael DeHaan wrote:

 

> I think it would be better to step back and see what you are trying to 
> model, to understand you use case about the apps you are deploying, and 
> then to suggest the way most people are modelling it in terms of current 
> best practices.
>

Well, what I have is a service we deploy as a website for some customers, 
as an api for other customers (the website using the api internally). It is 
composed by parts outside the system (e.g. db), and parts inside the system 
(e.g. a redis server). We also host the same website in white-label version 
for providers who customize it and have their own customers. A host may run 
more than one whitelabel and there could be some services shared across 
whitelabels (e.g. a single redis for all the whitelabels on the same host). 
Bigger websites may get separate hosts for different services, tiers can be 
sharded etc. That's the picture.

So, how I'm organizing the thing: I'm trying to have a single playbook, 
"site.yml", for the deploy of any configuration. An inventory file would 
represent instead a single whitelabel with the description of what host it 
should run on (red.inv, blue.inv, for development I'd have vm.inv, 
localhost.inv etc). So, for instance, if Green and Blue are two small 
websites which can run on the same box while Red is so big that it needs 
web and api separated on two machines we could have:

    green.inv
        [web]
        host1
        [api]
        host1

    blue.inv
        [web]
        host1
        [api]
        host1

    red.inv
        [web]
        host2
        [api]
        host3

And only one playbook to rule them all:

    site.yml
        - hosts: web
          roles:
            - role: web

        - hosts: api
          roles:
            - role: api

Let's say normally the api serves on port 4000. It is usually fine but on a 
host running many of them it may need configuration. With the idea of a 
role being self-describing I think it's normal to define api_port=4000 
somewhere inside the role. If the role is used in a playbook it is 
conceivable that tasks in other roles may want to refer to that variable. 
If the default is fine then it's ok for both the provider and the receiver; 
if it's not the inventory/group may decide to override it; so I'd have:

    roles/
        api/
            default/main.yml
                api_port: 4000

    group_vars/
        green
            info_email: [email protected]
        blue
            info_email: [email protected]
            api_port: 4001

As things stand now I cannot provide a self-contained api role that defines 
its own default port. If I put it in the vars it can be included but cannot 
be overridden. If I put it in group_vars/all it is no more self contained: 
the idea of modularized roles that can be (re)used at leisure in different 
playbooks breaks because they can only be used *if* sensible variables are 
provided in "all", the inventory or somewhere else: I would have thought 
that the role itself is the most sensible provider of defaults for such 
variables.

A different organization may see a different playbook for each whitelabel, 
and add vars_files to each of them, but this seems much worse to maintain: 
if I add a new piece to the system, let's say now it needs rabbitmq too to 
run, I have to add the rule to every playbook, instead of just to site.yml 
and then configure only the groups where its port is non-standard (which 
may be none of them). The idea I have in mind is the playbook describing 
how a system is composed and the inventory describing where the system 
should run; I may be wrong but in my playing around different 
interpretations have led to harder to maintain configurations.

Are you sure that being able to write "http_port: 80" inside 
roles/apache/defaults/main.yml would be bad design? I would have thought it 
is well encapsulated, provided it is exposed in such way that some 
role/firewall may read it. It serves as role interface indeed. As things 
stand now I'm experiencing "a migration of defaults": first I define 
http_port inside apache defaults, because I think it belongs there and I 
just need to write the apache config file. Then I add the firewall 
configuration to the site and... oops: I need to know where apache wants to 
listen: another variable flying into groups_vars/all just because two roles 
need it (while 10 other roles don't really care, but now I have to be more 
careful to scope everybody's variables because they have become more global 
than what was needed).

If there is a better way to organize my work I'd be happy to follow 
suggestions. As it is now I'm following the advice to put everything inside 
"all", but I don't find it optimal and I'm wondering if it can be improved.

Thank you

-- Daniele

-- 
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/f7558d64-6120-4515-9723-a4ac214b7e03%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to