Skip to content
This repository was archived by the owner on Mar 23, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion container/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ def set_env(self, env):
dev_overrides = service_config.pop('dev_overrides', {})
if env == 'dev':
service_config.update(dev_overrides)
if 'environment' in service_config:
# Expand environment variables from the shell
updated_envvars = []
for var in service_config['environment']:
updated_envvars.append(path.expandvars(var))
service_config['environment'] = updated_envvars
if 'volumes' in service_config:
# Expand ~, ${HOME}, ${PWD}, etc. found in the volume src path
updated_volumes = []
Expand Down Expand Up @@ -173,6 +179,7 @@ def _resolve_defaults(self, config):
# convert config['defaults'] to an ordereddict()
tmp_defaults = yaml.compat.ordereddict()
tmp_defaults.update(copy.deepcopy(config['defaults']), relax=True)
tmp_defaults = self._dict_expand_envvars(tmp_defaults)
config['defaults'] = tmp_defaults
defaults = config.setdefault('defaults', yaml.compat.ordereddict())

Expand Down Expand Up @@ -205,6 +212,21 @@ def _get_environment_variables():
logger.debug(u'Read environment variables', env_vars=env_vars)
return env_vars

def _dict_expand_envvars(self, dict):
"""
Takes a dict and expands environmental variables in all keys, recursively.

:return: dict
"""
ordered_dict = yaml.compat.ordereddict()
for key, val in dict.iteritems():
if isinstance(val, Mapping):
ordered_dict[key] = _dict_expand_envvars(dict.get(key, {}))
else:
if isinstance(dict[key], str):
ordered_dict[key] = path.expandvars(dict[key])
return ordered_dict

def _get_variables_from_file(self, var_file):
"""
Looks for file relative to base_path. If not found, checks relative to base_path/ansible.
Expand All @@ -222,7 +244,8 @@ def _get_variables_from_file(self, var_file):

if path.splitext(abspath)[-1].lower().endswith(('yml', 'yaml')):
try:
config = yaml.round_trip_load(open(abspath))
tmp_config = yaml.round_trip_load(open(abspath))
config = self._dict_expand_envvars(tmp_config)
except yaml.YAMLError as exc:
raise AnsibleContainerConfigException(u"YAML exception: %s" % unicode(exc))
else:
Expand Down
20 changes: 20 additions & 0 deletions docs/rst/container_yml/template.rst
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,26 @@ Ansible Container will detect the environment variable, remove ``AC_`` from the
and send the result to Jinja. Thus ``AC_WEB_IMAGE`` becomes ``web_image`` and gets transposed in ``container.yml`` to
``centos:7``.

It is often necessary to manage variables outside the project (e.g. in a CI/CD context, build/dev environment, etc).
Environmental variables from the shell/parent process can be expanded inside the following sections.

* A service's ``environment`` section, making them available to the container process.
* Values inside ``vars-files`` and the ``defaults`` section, making them available to roles and playbooks in the
``ansible-container`` workflow.

.. code-block:: yaml

defaults:
env: '$CI_ENVIRONMENT_NAME' # Default 'env' here from the environment
# unless set in a 'var-file'

services:
web:
environment:
- ENV_NAME={{ env }} # Set the ENV_NAME docker ENV variable for the container
- HTTP_PROXY=$HTTP_PROXY # Allow container process(es) to use the same proxy
- HTTPS_PROXY=$HTTP_PROXY # settings as those of a build/CI environment
- POSTGRES_DB_NAME=$CI_ENV-foo # Expand to 'dev-foo', 'test-foo', 'prod-foo', etc

Providing defaults
------------------
Expand Down