Fix failure when powering on/off EC2 instances by tag only. (#4767)

If you apply `wait=yes` and use `instance_tags` as your filter for
stopping/starting EC2 instances, this stack trace happens:

```
An exception occurred during task execution. The full traceback is:                                                                          │~
Traceback (most recent call last):                                                                                                           │~
  File "/tmp/ryansb/ansible_FwE8VR/ansible_module_ec2.py", line 1540, in <module>                                                            │~
    main()                                                                                                                                   │~
  File "/tmp/ryansb/ansible_FwE8VR/ansible_module_ec2.py", line 1514, in main                                                                │~
    (changed, instance_dict_array, new_instance_ids) = startstop_instances(module, ec2, instance_ids, state, instance_tags)                  │~
  File "/tmp/ryansb/ansible_FwE8VR/ansible_module_ec2.py", line 1343, in startstop_instances                                                 │~
    if len(matched_instances) < len(instance_ids):                                                                                           │~
TypeError: object of type 'NoneType' has no len()                                                                                            │~
                                                                                                                                             │~
fatal: [localhost -> localhost]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_name": "ec2"}, "module_stderr": "Traceb│~
ack (most recent call last):\n  File \"/tmp/ryansb/ansible_FwE8VR/ansible_module_ec2.py\", line 1540, in <module>\n    main()\n  File \"/tmp/│~
ryansb/ansible_FwE8VR/ansible_module_ec2.py\", line 1514, in main\n    (changed, instance_dict_array, new_instance_ids) = startstop_instances│~
(module, ec2, instance_ids, state, instance_tags)\n  File \"/tmp/ryansb/ansible_FwE8VR/ansible_module_ec2.py\", line 1343, in startstop_insta│~
nces\n    if len(matched_instances) < len(instance_ids):\nTypeError: object of type 'NoneType' has no len()\n", "module_stdout": "", "msg": "│~
MODULE FAILURE", "parsed": false}
```

That's because the `instance_ids` variable is None if not supplied
in the task. That means the instances that result from the instance_tags
query aren't going to be included in the wait loop. To fix this, a list
needs to be kept of instances with matching tags and that list needs to
be added to `instance_ids` before the wait loop.
This commit is contained in:
Ryan Brown 2016-09-09 19:38:05 -04:00 committed by Matt Clay
parent 976d876e55
commit 6ae4e50e47

View file

@ -1302,7 +1302,7 @@ def startstop_instances(module, ec2, instance_ids, state, instance_tags):
# Check that our instances are not in the state we want to take
# Check (and eventually change) instances attributes and instances state
running_instances_array = []
existing_instances_array = []
for res in ec2.get_all_instances(instance_ids, filters=filters):
for inst in res.instances:
@ -1327,7 +1327,9 @@ def startstop_instances(module, ec2, instance_ids, state, instance_tags):
except EC2ResponseError as e:
module.fail_json(msg='Unable to change state for instance {0}, error: {1}'.format(inst.id, e))
changed = True
existing_instances_array.append(inst.id)
instance_ids = list(set(existing_instances_array + (instance_ids or [])))
## Wait for all the instances to finish starting or stopping
wait_timeout = time.time() + wait_timeout
while wait and wait_timeout > time.time():