Variable substitution in uri module

Hi all,

Similar to https://groups.google.com/forum/#!topic/ansible-project/ba5PPAgYGXc but slightly different.

I am trying to use variable substitution like so, putting the variable my_var in the body parameter, which should be a json string:

vars:
my_var: hello_world

tasks:

  • uri:
    url: https://localhost/api/v1/
    method: POST
    body: ‘{ “name”: “test”, “var”: “{{ my_var }}”, “location”: “usa” }’
    HEADER_Content-Type: “application/json”
    status_code: 201
    validate_certs: no
    user: admin
    password: password

I get this error (stacktrace with a TypeError: unhashable type):

TASK: [uri ] ******************************************************************
failed: [localhost] => {“failed”: true, “parsed”: false}
Traceback (most recent call last):
File “/Users/mzb/.ansible/tmp/ansible-tmp-1443729077.78-98124067847188/uri”, line 2067, in
main()
File “/Users/mzb/.ansible/tmp/ansible-tmp-1443729077.78-98124067847188/uri”, line 419, in main
resp, content, dest = uri(module, url, dest, user, password, body, method, dict_headers, redirects, socket_timeout, validate_certs)
File “/Users/mzb/.ansible/tmp/ansible-tmp-1443729077.78-98124067847188/uri”, line 312, in uri
resp, content = h.request(url, method=method, body=body, headers=headers)
File “/Library/Python/2.7/site-packages/httplib2/init.py”, line 1609, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File “/Library/Python/2.7/site-packages/httplib2/init.py”, line 1351, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File “/Library/Python/2.7/site-packages/httplib2/init.py”, line 1273, in _conn_request
conn.request(method, request_uri, body, headers)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py”, line 973, in request
self._send_request(method, url, body, headers)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py”, line 1007, in _send_request
self.endheaders(body)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py”, line 969, in endheaders
self._send_output(message_body)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py”, line 833, in _send_output
self.send(message_body)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py”, line 805, in send
self.sock.sendall(data)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py”, line 229, in sendall
v = self.send(data[count:])
TypeError: unhashable type

If I don’t use quotes around the variable substition, like this:

vars:
my_var: hello_world

tasks:

  • uri:
    url: https://localhost/api/v1/
    method: POST
    body: ‘{ “name”: “test”, “var”: {{ my_var }}, “location”: “usa” }’
    HEADER_Content-Type: “application/json”
    status_code: 201
    validate_certs: no
    user: admin
    password: password

then, I get this error (No JSON type could be decoded):

failed: [localhost] => {“allow”: “GET, POST, HEAD, OPTIONS”, “connection”: “close”, “content”: “{"detail": "JSON parse error - No JSON object could be decoded"}”, “content_type”: “application/json”, “date”: “Thu, 01 Oct 2015 19:50:56 GMT”, “failed”: true, “json”: {“detail”: “JSON parse error - No JSON object could be decoded”}, “redirected”: false, “server”: “Apache/2.4.7 (Ubuntu)”, “status”: 400, “transfer_encoding”: “chunked”, “vary”: “Accept,Cookie”, “x_api_time”: “0.001s”}
msg: Status code was not [201]

Any ideas? Thanks in advance!

I solved the problem after a lot of digging. In case it’s of use to anyone else: https://github.com/ansible/ansible/issues/7005

HI, I am facing the same problem. I went through the link which you’ve posted but couldn’t find the exact solution. Could you please post the solution which you’ve tried?

Hi Sharwari,

This is the key fix, changing from colon syntax to equal sign syntax:

    - name: Create an instance
      ec2: >
        state=present
        image="{{ ami_base_image_id }}"
        instance_type=t1.micro
        group="{{ instance_security_groups }}"
        key_name="{{ environment_public_ssh_key_name }}"
        vpc_subnet_id="{{ environment_vpc_public_subnet_az1_id }}"
        user_data="{{ lookup('template', '../templates/user_data.json') }}"
        assign_public_ip=yes
        wait=yes
        wait_timeout=600
        region="{{ vpc_region }}"
        aws_access_key="{{ aws_access_key }}"
        aws_secret_key="{{ aws_secret_key }}"
      register: new_instance
      when: environment_instance is not defined

Hi,
I’d explain my problem clearly, I have a same type of example as yours.

vars:
my_var: hello_world

tasks:

  • uri:
    url: https://localhost/api/v1/
    method: POST
    body: jsoncode=‘{ “name”: “test”, “var”: “{{ my_var }}”, “location”: “usa” }’
    HEADER_Content-Type: “application/json”
    status_code: 201
    validate_certs: no
    user: admin
    password: password

Here, I replaced : with = and provided “” to the my_var variable. It’s not giving any error but when I redirect the output of the request to a file. It gives the following error message:

{
“error_code” : 220,
“module_name” : “common-services”,
“error_message” : "Could not read JSON: Unrecognized token ‘jsoncode’: was expecting ‘null’, ‘true’, ‘false’ or NaN\n at [Source: org.apache.catalina.connector.CoyoteInputStream@29d4dd6e; line: 1, column: 7]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token ‘jsoncode’: was expecting ‘null’, ‘true’, ‘false’ or NaN\n at [Source: org.apache.catalina.connector.CoyoteInputStream@29d4dd6e; line: 1, column: 7

Correct me if I am going wrong. Thanks in advance.