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
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.