per-environment variables

I'm developing an ansible playbook in Vagrant and then
applying it to a customer environment. Getting pretty far
by using a single playbook (site.yml) and setting per-environment
variables in different inventory files.

dev_hosts = my dev. VMs
live_hosts = customer VM stack

then i can run

ansible-playbook -i (pick one) site.yml

and things by and large work great.

One problem I keep hitting is the 'live' environment needs everything
to go via a proxy. live_hosts has:

....
[all:vars]
http_proxy=http://custproxy:8080
....

and that's absent from dev_hosts.

I use that to template /etc/profile.d/proxy.sh,
so curl etc. are pre-set to use it. I'ts easy to do conditional
logic in that template.

I'd like all the Ansible tasks that support an environment: field
(git / get_url / etc) to only have one set if that var is populated.

I can't just blindly set it or the tasks end up running with a proxy
of nil/null/'' .

But I can't just add this to the inventory:

....
[all:vars]
http_proxy=http://custproxy:8080
proxy_env:
  http_proxy: {{http_proxy}}
....

because it just allows key=var style definitions.

Where's the earliest I can set this up?

Dnia czw, 1 maj 2014, 11:40:22 Dick Davies pisze:

I'm developing an ansible playbook in Vagrant and then
applying it to a customer environment. Getting pretty far
by using a single playbook (site.yml) and setting per-environment
variables in different inventory files.

Sounds like a bit of abuse of the inventory - I think it's only meant for listing hosts and connection details.

dev_hosts = my dev. VMs
live_hosts = customer VM stack

then i can run

ansible-playbook -i (pick one) site.yml

and things by and large work great.

One problem I keep hitting is the 'live' environment needs everything
to go via a proxy. live_hosts has:

....
[all:vars]
http_proxy=http://custproxy:8080
....

and that's absent from dev_hosts.

I use that to template /etc/profile.d/proxy.sh,
so curl etc. are pre-set to use it. I'ts easy to do conditional
logic in that template.

I'd like all the Ansible tasks that support an environment: field
(git / get_url / etc) to only have one set if that var is populated.

I can't just blindly set it or the tasks end up running with a proxy
of nil/null/'' .

But I can't just add this to the inventory:

....
[all:vars]
http_proxy=http://custproxy:8080
proxy_env:
   http_proxy: {{http_proxy}}
....

because it just allows key=var style definitions.

Where's the earliest I can set this up?

I'm not sure if that's the right way, but for environment-specific variables I'm using play's vars_files.
vagrant_inventory:
[all:vars]
environment_name=vagrant

site.yml:
- hosts: some_group
   vars_files:
     - vars/{{ environment_name }}.yml

This way I have less clutter in inventory, and I can easily see the environment's global settings.
It's also pretty handy for usage with Vault, by adding "- secrets/{{ environment_name }}.yml" there (and as secrets for Vagrant aren't that secret, that gives you an index of required secrets too :-))

“Sounds like a bit of abuse of the inventory - I think it’s only meant for listing hosts and connection details.”

I strongly disagree.

Group based variables are quite useful and having a group_vars/production and group_vars/stage can be a great way to organize things.

In fairness, I probably am Doing It Wrong in some respects -
I don't have prod/dev groups in this case, we're using a different
inventory for prod and dev.

The alternative would be to have [prod_mongos] , [prod_mongors], [dev_mongos]
etc. etc. in the inventory which seems a bit cut n pasty to me.

With the 2 inventory approach, I can have the same groups across environments
that differ only in FQDNs and number of members, and then an [all:vars] to hold
environment-wide 'globals' (NTP settings, proxy, ansible_ssh* settings etc).

For the record :

I got this working cleanly (to my mind at least ) thanks to @drybjed
on IRC pointing
out set_fact.

I have a roles/proxyenv/tasks/main.yml applied to all hosts
that mpopulates a proxy_env var using set_fact + when
and then all our yum/get_url/gem etc. always have an environment:
proxy_env tacked onto them.

Environments that don't need to use a proxy simply don't set one in
their inventory, and
so that proxy_env dict is empty for them.