Repository: ansible/ansible

Issue:
Creating EC2 spot requests without waiting for instances to start results in a Python error
_From @kyl191 on September 24, 2015 2:59_

##### Issue Type: Bug Report
##### Component Name: ec2 module
##### Ansible Version: 1.9.3

```
[root@ansible-host ansible]# ansible --version
ansible 1.9.3
  configured module search path = None
```
##### Ansible Configuration:

hostfile was changed
##### Environment:

N/A
##### Summary:

Using the EC2 module, creating a spot but not waiting for the spot request to be fulfilled results in a Python error
##### Steps To Reproduce:
1. Use this role file:

``` yml
    - name: Create spot instance
      local_action:
        module: ec2
        spot_price: 0.24
        spot_wait_timeout: 600
        region: ap-southeast-1
        keypair: EC2 AWS APAC Singapore
        group_id: default
        instance_type: c3.large
        image: ami-ac9481fe
        wait: no
```
1. Run ansible against role file
##### Expected Results:

An AWS spot request is submitted, and the playbook finishes
##### Actual Results:

An AWS spot request is submitted, and Python crashes with an error:

```
    Traceback (most recent call last):
      File "/root/.ansible/tmp/ansible-tmp-1443062264.07-30079051580954/ec2", line 3070, in <module>
        main()
      File "/root/.ansible/tmp/ansible-tmp-1443062264.07-30079051580954/ec2", line 1249, in main
        (instance_dict_array, new_instance_ids, changed) = create_instances(module, ec2, vpc)
      File "/root/.ansible/tmp/ansible-tmp-1443062264.07-30079051580954/ec2", line 982, in create_instances
        while wait_timeout > time.time() and num_running < len(instids):
    UnboundLocalError: local variable 'instids' referenced before assignment
```

`instids` is created inside if/else blocks, and creating a spot instance but not waiting isn't one of the conditions checked. 
Adding an else block to the if block here https://github.com/ansible/ansible-modules-core/blob/devel/cloud/amazon/ec2.py#L1039 should work, something like

``` python
else:
  instids = None
```


_Copied from original issue: ansible/ansible-modules-core#2140_
Creating EC2 spot requests without waiting for instances to start results in a Python error
_From @kyl191 on September 24, 2015 2:59_

##### Issue Type: Bug Report
##### Component Name: ec2 module
##### Ansible Version: 1.9.3

```
[root@ansible-host ansible]# ansible --version
ansible 1.9.3
  configured module search path = None
```
##### Ansible Configuration:

hostfile was changed
##### Environment:

N/A
##### Summary:

Using the EC2 module, creating a spot but not waiting for the spot request to be fulfilled results in a Python error
##### Steps To Reproduce:
1. Use this role file:

``` yml
    - name: Create spot instance
      local_action:
        module: ec2
        spot_price: 0.24
        spot_wait_timeout: 600
        region: ap-southeast-1
        keypair: EC2 AWS APAC Singapore
        group_id: default
        instance_type: c3.large
        image: ami-ac9481fe
        wait: no
```
1. Run ansible against role file
##### Expected Results:

An AWS spot request is submitted, and the playbook finishes
##### Actual Results:

An AWS spot request is submitted, and Python crashes with an error:

```
    Traceback (most recent call last):
      File "/root/.ansible/tmp/ansible-tmp-1443062264.07-30079051580954/ec2", line 3070, in <module>
        main()
      File "/root/.ansible/tmp/ansible-tmp-1443062264.07-30079051580954/ec2", line 1249, in main
        (instance_dict_array, new_instance_ids, changed) = create_instances(module, ec2, vpc)
      File "/root/.ansible/tmp/ansible-tmp-1443062264.07-30079051580954/ec2", line 982, in create_instances
        while wait_timeout > time.time() and num_running < len(instids):
    UnboundLocalError: local variable 'instids' referenced before assignment
```

`instids` is created inside if/else blocks, and creating a spot instance but not waiting isn't one of the conditions checked. 
Adding an else block to the if block here https://github.com/ansible/ansible-modules-core/blob/devel/cloud/amazon/ec2.py#L1039 should work, something like

``` python
else:
  instids = None
```


_Copied from original issue: ansible/ansible-modules-core#2140_


Discussion:
_From @sakaal on October 4, 2015 10:1_

This is not directly related, but pertaining to the same function. The EC2 module should set the Spot Request expiration time and date, based on the spot_wait_timeout.
https://github.com/ansible/ansible-modules-core/issues/2057

_From @kbroughton on November 17, 2015 4:54_

I'm seeing this in 1.9.4 after  pip install --upgrade ansible run today Nov 16, 2015.
fixed by adding 
wait=true
to the creation block

_From @ansibot on August 1, 2016 2:31_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/jctanner/ansibullbot/blob/ISSUE_TRIAGE_CLASS/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on September 12, 2016 19:36_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on October 6, 2016 15:50_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on October 22, 2016 9:19_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on November 6, 2016 10:9_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on November 22, 2016 10:17_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: issue_renotify_maintainer --->
_From @ansibot on December 7, 2016 17:56_

This repository has been locked. All new issues and pull requests should be filed in https://github.com/ansible/ansible

Please read through the <a href="http://docs.ansible.com/ansible/dev_guide/repomerge.html#move-issues-and-prs-to-new-repo">repomerge</a> page in the dev guide. The guide contains links to tools which automatically move your issue or pull request to the ansible/ansible repo.

<!-- boilerplate: repomerge -->
Note: the solution offered by @kyl191 in the first post seems to work -- I've tried it on my own machine. Who is the maintainer of the ec2 module whom I could tag, please?
cc @willthames
@jucor ansible 1.9 is no longer supported. Have you tried to reproduce the error on 2.2+ ?

needs_info
@jctanner Sorry, I didn't realise this bug report was on 1.9. I confirm
that I do use 2.2 and face the same problem.

On Tue, 28 Mar 2017, 15:52 jctanner, <notifications@github.com> wrote:

@jucor <https://github.com/jucor> ansible 1.9 is no longer supported. Have
you tried to reproduce the error on 2.2+ ?

needs_info

—
You are receiving this because you were mentioned.


Reply to this email directly, view it on GitHub
<https://github.com/ansible/ansible/issues/22692#issuecomment-289795668>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAoSRXW1zw8rXyVbAmdcPCZ9iv6alp7oks5rqR62gaJpZM4MfTbh>
.

_From @sakaal on October 4, 2015 10:1_

This is not directly related, but pertaining to the same function. The EC2 module should set the Spot Request expiration time and date, based on the spot_wait_timeout.
https://github.com/ansible/ansible-modules-core/issues/2057

_From @kbroughton on November 17, 2015 4:54_

I'm seeing this in 1.9.4 after  pip install --upgrade ansible run today Nov 16, 2015.
fixed by adding 
wait=true
to the creation block

_From @ansibot on August 1, 2016 2:31_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/jctanner/ansibullbot/blob/ISSUE_TRIAGE_CLASS/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on September 12, 2016 19:36_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on October 6, 2016 15:50_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on October 22, 2016 9:19_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on November 6, 2016 10:9_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->

_From @ansibot on November 22, 2016 10:17_

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: issue_renotify_maintainer --->
_From @ansibot on December 7, 2016 17:56_

This repository has been locked. All new issues and pull requests should be filed in https://github.com/ansible/ansible

Please read through the <a href="http://docs.ansible.com/ansible/dev_guide/repomerge.html#move-issues-and-prs-to-new-repo">repomerge</a> page in the dev guide. The guide contains links to tools which automatically move your issue or pull request to the ansible/ansible repo.

<!-- boilerplate: repomerge -->
Note: the solution offered by @kyl191 in the first post seems to work -- I've tried it on my own machine. Who is the maintainer of the ec2 module whom I could tag, please?
cc @willthames
@jucor ansible 1.9 is no longer supported. Have you tried to reproduce the error on 2.2+ ?

needs_info
@jctanner Sorry, I didn't realise this bug report was on 1.9. I confirm
that I do use 2.2 and face the same problem.

On Tue, 28 Mar 2017, 15:52 jctanner, <notifications@github.com> wrote:

@jucor <https://github.com/jucor> ansible 1.9 is no longer supported. Have
you tried to reproduce the error on 2.2+ ?

needs_info

—
You are receiving this because you were mentioned.


Reply to this email directly, view it on GitHub
<https://github.com/ansible/ansible/issues/22692#issuecomment-289795668>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAoSRXW1zw8rXyVbAmdcPCZ9iv6alp7oks5rqR62gaJpZM4MfTbh>
.


Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/ec2.py b/lib/ansible/modules/cloud/amazon/ec2.py
--- a/lib/ansible/modules/cloud/amazon/ec2.py
+++ b/lib/ansible/modules/cloud/amazon/ec2.py
@@ -1227,12 +1227,15 @@ def create_instances(module, ec2, vpc, override_count=None):
                 # Now we have to do the intermediate waiting
                 if wait:
                     instids = await_spot_requests(module, ec2, res, count)
+                else:
+                    instids = []
         except boto.exception.BotoServerError as e:
             module.fail_json(msg="Instance creation failed => %s: %s" % (e.error_code, e.error_message))
 
         # wait here until the instances are up
         num_running = 0
         wait_timeout = time.time() + wait_timeout
+        res_list = ()
         while wait_timeout > time.time() and num_running < len(instids):
             try:
                 res_list = ec2.get_all_instances(instids)
@@ -1275,7 +1278,7 @@ def create_instances(module, ec2, vpc, override_count=None):
                 inst.modify_attribute('disableApiTermination', True)
 
         # Leave this as late as possible to try and avoid InvalidInstanceID.NotFound
-        if instance_tags:
+        if instance_tags and instids:
             try:
                 ec2.create_tags(instids, instance_tags)
             except boto.exception.EC2ResponseError as e:


Test patch: