Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ansible supply extra-vars as nested json

I'm trying to use ansible for a parameterised docker deployment. I want to be able to specify image, version and various different environment variables via the command line.

Image, Version and so on can be specified directly but the env parameter of the docker module requires a dictionary. Here is a shortened playbook example:

-name: some deployment
docker:
   [..]
   name: myname
   [..]
   env:
      FOO: bar
      ANOTHERFOO: anotherbar

The environment variables are choosen during runtime, so it is not possible to define them directly in the supplied extra vars. The playbook looks like this at the moment:

-name: some deployment
docker:
   [..]
   name: "{{ name }}"
   [..]
   env: "{{ env }}"

Since env is a nested dictionary we need to supply the --extra-vars as nested json. I would expected the following to work:

./ansible-playbook [..] --extra-vars '{"name":"myname", "env":{"FOO":"bar", "ANOTHERFOO":"anotherbar"}}' [..]

After the container is running, the values of env are not there. Supplying the json directly in the playbook for testing purposes works.

I tried the following different json with no working results:

{"name":"myname", "env":{"FOO":"bar", "ANOTHERFOO":"anotherbar"}}

{"name":"myname", "env":[{"FOO":"bar"}, {"ANOTHERFOO":"anotherbar"}]}

How do you supply and use a nested dictionary via command line or is this a limitation of the Jinja2 template engine.

like image 274
echox Avatar asked Sep 28 '22 06:09

echox


2 Answers

The right structure to use if you need a dict in your YAML/ansible playbook is a nested json supplied with --extra-vars like in the questions example:

./ansible-playbook [..] --extra-vars '{"name":"myname", "env":{"FOO":"bar", "ANOTHERFOO":"anotherbar"}}' [..]

and

-name: some deployment
docker:
   [..]
   name: "{{ name }}"
   [..]
   env: "{{ env }}"

For testing purposes I did use environment on my system which I shortened to env as an example. The problem is environment is a reserved variable and always gets overridden.

like image 66
echox Avatar answered Oct 18 '22 00:10

echox


Try like the following way :

test.json

{"name":"myname", "env":{"FOO":"bar", "ANOTHERFOO":"anotherbar"}}

test.yml

---
 - hosts: localhost
   connection: local
   gather_facts: false

   tasks:
   - name: Print nested json input
     debug:
        msg: "name : {{ name }} || env.foo : {{ env.FOO }} || env.anotherfoo : {{  env.ANOTHERFOO }}"

Ansible Output

[root@localhost test]$ ansible-playbook test.yml -e "@test.json"
 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available

 [WARNING]: Found variable using reserved name: name


PLAY [localhost] ********************************************************************************************************************

TASK [Print nested json input] ******************************************************************************************************
ok: [localhost] => {
    "msg": "name : myname || env.foo : bar || env.anotherfoo : anotherbar"
}

PLAY RECAP **************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0

[root@localhost test]$
like image 28
S.K. Venkat Avatar answered Oct 18 '22 00:10

S.K. Venkat