Skip to content

Instantly share code, notes, and snippets.

@KyleJamesWalker
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KyleJamesWalker/d1d385afae0de4a2fba4 to your computer and use it in GitHub Desktop.
Save KyleJamesWalker/d1d385afae0de4a2fba4 to your computer and use it in GitHub Desktop.
Ansible Docker Environment Lookup Plugin

Quick lookup plugin for ansible. I needed a clean way to pass an unknown amount of local envs via params when creating a docker container, based on the env vars on the CI server.

Run the playbook to test with: ansible-playbook -i localhost, playbook.yml

Note: This was thrown together very quickly, I'll hopfully have some time to expand this plugin with proper documention and error handling.

Note original (non plugin route was) ugly and hacky:

---
- name: Get all local envs for dynamic docker injection
  shell: env | grep ^SEARCH_PREFIX_
  # When nothing found by grep return code is 1, this is fine.
  ignore_errors: yes
  register: app_envs

- name: Build list of docker app params
  shell: |
    echo "{% for x in app_envs.stdout_lines %}
    -e {{ "{}={}".format(x.split('=', 1)[0], x.split('=', 1)[1].replace('\"','\\\"')) }}
    {% endfor %}
    "
  register: docker_env_params
# Kyle James Walker <KyleJamesWalker@gmail.com>
#
# This file is a lookup plugin for Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
import os
import re
from ansible.utils import template
class LookupModule(object):
def __init__(self, basedir=None, **kwargs):
self.basedir = basedir
self.search_string = ''
self.format_envs = '-e {}={}'
self.join_by = ' '
def escape_val(self, val):
quotes = '\'"'
requote = False
try:
if val[0] == val[-1] and val[0] in quotes:
requote = val[0]
val = val[1:-1]
val = val.replace('\\', '\\\\')
if requote is not False:
val = val.replace(requote, "\\{}".format(requote))
else:
for x in quotes:
val = val.replace(x, "\\{}".format(x))
if requote is not False:
val = "{0}{1}{0}".format(requote, val)
except IndexError:
pass
return val
def build_params(self, terms):
''' Expect up to three params passed
1. Regex search string.
2. Optional format string.
3. Optional join by string.
'''
self.search_string = terms[0]
if len(terms) > 1 and terms[1] is not None:
self.format_envs = terms[1]
if len(terms) > 2 and terms[2] is not None:
self.join_by = terms[2]
def build_return(self, results):
build = [self.format_envs.format(n, self.escape_val(v))
for n, v in results]
return [self.join_by.join(build)]
def run(self, terms, inject=None, **kwargs):
results = []
try:
terms = template.template(self.basedir, terms, inject)
except Exception:
pass
if isinstance(terms, basestring):
terms = [terms]
self.build_params(terms)
search_re = re.compile(self.search_string)
for e_name in os.environ.keys():
if search_re.match(e_name):
e_val = os.getenv(e_name)
results.append((e_name, e_val),)
return self.build_return(results)
---
- name: Testing lookup docker_envs
hosts: localhost
connection: local
tasks:
- name: debug
debug: msg="{{lookup('docker_envs', '^DOCKER_.*')}}"
- name: debug
debug: msg="{{lookup('docker_envs', ['^DOCKER_.*', None, '\n'])}}"
- name: debug
debug: msg="{{lookup('docker_envs', ['^DOCKER_.*', '{}="{}"', '\n'])}}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment