Home > Software design >  not able to query json structure properly in ansible
not able to query json structure properly in ansible

Time:11-24

I need to loop through a few AWS snapshots in ansible to see if they are completed. This is my code:

- name: Volume Snapshot Statuses
  ec2_snapshot_info:
    aws_access_key: "{{ aws_access_key_id }}"
    aws_secret_key: "{{ aws_secret_key_id }}"
    security_token: "{{ aws_security_token }}"
    region: "{{ aws_region }}"
    snapshot_ids: "{{ item.snapshot_id }}"
  register: snapshots
  loop_control: 
    index_var: loopidx
  until: snapshots.results[loopidx].snapshots[0].state == "completed"
  with_items: "{{ volumesnapshots.results }}"

it fails though with the following error

{
  "msg": "The conditional check 'snapshots.results[loopidx].snapshots[0].state == \"completed\"' failed. The error was: error while evaluating conditional (snapshots.results[loopidx].snapshots[0].state == \"completed\"): 'dict object' has no attribute 'results'",
  "_ansible_no_log": false
}

it basically says that snapshots variable doesn't have results attribute. But it does according to the JSON (it would be too long to show the entire JSON so just the first few lines)

{
  "snapshots": {
    "results": [
      {
        "snapshots": [
          {

Also look at the picture attached in viewer

JSON viewer image also attached

What am I missing here?

CodePudding user response:

Q: 'dict object' has no attribute 'results'

A: The attribute results is collected and added to the registered value after the loop completes. Within the loop, the registered values are not nested in the results. Fix the condition

until: snapshots.snapshots[0].state == "completed"

Let's test it with a simple bash command 'echo $(($RANDOM%2))' that returns either 0 or 1. The play below

- hosts: localhost

  vars:

     attempts: "{{ snapshots.results|json_query('[].[attempts, stdout]') }}"

  tasks:

    - command: bash -c 'echo $(($RANDOM%2))'
      register: snapshots
      until: snapshots.stdout|int != 0
      retries: 10
      delay: 1
      loop: [1, 2, 3]
      
    - debug:
        var: attempts|to_yaml

gives

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

TASK [command] *******************************************************************************
FAILED - RETRYING: [localhost]: command (10 retries left).
changed: [localhost] => (item=1)
FAILED - RETRYING: [localhost]: command (10 retries left).
changed: [localhost] => (item=2)
changed: [localhost] => (item=3)

TASK [debug] *********************************************************************************
ok: [localhost] => 
  attempts|to_yaml: |-
    - [2, '1']
    - [2, '1']
    - [1, '1']

PLAY RECAP ***********************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

You can see the list snapshots.results is available after the loop completes. Within the loop, snapshots.stdout is used.

  • Related