Search code examples
ansiblejinja2ansible-2.xansible-template

Pass a variable(value) from the JSON body to the URL in ansible


I would like to pass a particular value as an input to the URI from the JSON body. But i am getting an error as below. Please find below code and expectation is to put the netid = 12345 in the place of netid in the URL as {{ api_uri }}/networks/12345/appliance

Error:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'rules'\n\nThe error appears to be in '/***/firewallrules.yml': line 35, column 10, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n       - name: Firewall rule update\n         ^ here\n"}

URI Task:

- name: Firewall rule update
         uri:
           method: PUT
           url: "{{ api_uri }}/networks/{{ netid(from firewall.json) }}/appliance"
           body: "{{ lookup('file', 'firewall.json') | from_json }}"
           body_format: json
         register: firewallresults
         ignore_errors: yes

Firewall(JSON input to API):

{
    "rules": [
                {
            "comment": "Test1.",
            "destCidr": "x.x.x.x/24",
            "srcCidr": "y.y.y.y/24",
            "netid":"12345"
        },
                        {
            "comment": "Test2",
            "destCidr": "a.a.a.a/24",
            "srcCidr": "b.b.b.b/24",
            "netid":"12345"
        }            ]
}

Solution

  • The error message reports AnsibleUnsafeText object' has no attribute 'rules' ... The error appears to be in '/***/firewallrules.yml' but I cant find anything about .rules or firewallrules.yml in your description.

    In respect to the minimal information

    I would like to pass a particular value as an input to the URI from the JSON body. ... need a solution to get the netid from my input JSON ... which will be used in the API URI

    it seems that your URI task and URL parameter are misconstructed. I've created a debugging task to get a better understanding of the use case.

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      vars:
    
        BODY: "{{ lookup('file', 'firewall.json') | from_json }}"
    
      tasks:
    
      - name: Show BODY
        debug:
          msg: "{{ BODY }}"
    
      - name: Show first 'netid' for URL
        debug:
          var: BODY.rules[0].netid
    
      - name: Show all 'netid's for URL
        debug:
          msg: "{{ item.netid }}"
        loop: "{{ BODY.rules }}"
    

    Resulting into an output of

    TASK [Show first 'netid' for URL] ***
    ok: [localhost] =>
      BODY.rules[0].netid: '12345'
    
    TASK [Show all 'netid's for URL] ***
    ok: [localhost] => (item={u'comment': u'Test1.', u'destCidr': u'x.x.x.x/24', u'netid': u'12345', u'srcCidr': u'y.y.y.y/24'}) =>
      msg: '12345'
    ok: [localhost] => (item={u'comment': u'Test2', u'destCidr': u'a.a.a.a/24', u'netid': u'12345', u'srcCidr': u'b.b.b.b/24'}) =>
      msg: '12345'