Repository: ansible/ansible

Issue:
Setting spot_price in ec2 module results in an error
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
ec2

##### ANSIBLE VERSION
```
ansible 2.3.0.0
  config file =
  configured module search path = Default w/o overrides
  python version = 2.7.13 (default, Dec 18 2016, 07:03:39) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
```

##### CONFIGURATION
None

##### OS / ENVIRONMENT
MacOSX 10.12.4 (16E195)

##### SUMMARY
Adding the `spot_price` parameter 

##### STEPS TO REPRODUCE
add the parameter `spot_price` with some pricing.

```yaml
# demo_setup.yml

- hosts: localhost
  connection: local
  gather_facts: False

  tasks:

    - name: Provision a set of instances
      ec2:
         key_name: mykey
         region: eu-west-1
         instance_type: t2.micro
         spot_price: 0.24
         image: "ami-01ccc867"
         wait: true
         exact_count: 1
         count_tag:
            Name: Demo
         instance_tags:
            Name: Demo
      register: ec2
```

##### EXPECTED RESULTS
A created ec2 instance with the `Name` tag being set.

##### ACTUAL RESULTS
* A type error (```TypeError: 'dict_values' object does not support indexing```) on the console
* no tags and name are being set in the AWS terminal

Removing `spot_pricing` fixes the issue.

Full traceback:

```
Traceback (most recent call last):
  File "/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py", line 1652, in <module>
    main()
  File "/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py", line 1641, in main
    (instance_dict_array, new_instance_ids, changed) = create_instances(module, ec2, vpc)
  File "/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py", line 1217, in create_instances
    res_list = ec2.get_all_instances(instids)
  File "/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py", line 585, in get_all_instances
    max_results=max_results)
  File "/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py", line 663, in get_all_reservations
    self.build_list_params(params, instance_ids, 'InstanceId')
  File "/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/connection.py", line 1122, in build_list_params
    params['%s.%d' % (label, i)] = items[i - 1]
TypeError: 'dict_values' object does not support indexing

fatal: [localhost -> localhost]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py\", line 1652, in <module>\n    main()\n  File \"/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py\", line 1641, in main\n    (instance_dict_array, new_instance_ids, changed) = create_instances(module, ec2, vpc)\n  File \"/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py\", line 1217, in create_instances\n    res_list = ec2.get_all_instances(instids)\n  File \"/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py\", line 585, in get_all_instances\n    max_results=max_results)\n  File \"/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py\", line 663, in get_all_reservations\n    self.build_list_params(params, instance_ids, 'InstanceId')\n  File \"/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/connection.py\", line 1122, in build_list_params\n    params['%s.%d' % (label, i)] = items[i - 1]\nTypeError: 'dict_values' object does not support indexing\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
```

Setting spot_price in ec2 module results in an error
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
ec2

##### ANSIBLE VERSION
```
ansible 2.3.0.0
  config file =
  configured module search path = Default w/o overrides
  python version = 2.7.13 (default, Dec 18 2016, 07:03:39) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
```

##### CONFIGURATION
None

##### OS / ENVIRONMENT
MacOSX 10.12.4 (16E195)

##### SUMMARY
Adding the `spot_price` parameter 

##### STEPS TO REPRODUCE
add the parameter `spot_price` with some pricing.

```yaml
# demo_setup.yml

- hosts: localhost
  connection: local
  gather_facts: False

  tasks:

    - name: Provision a set of instances
      ec2:
         key_name: mykey
         region: eu-west-1
         instance_type: t2.micro
         spot_price: 0.24
         image: "ami-01ccc867"
         wait: true
         exact_count: 1
         count_tag:
            Name: Demo
         instance_tags:
            Name: Demo
      register: ec2
```

##### EXPECTED RESULTS
A created ec2 instance with the `Name` tag being set.

##### ACTUAL RESULTS
* A type error (```TypeError: 'dict_values' object does not support indexing```) on the console
* no tags and name are being set in the AWS terminal

Removing `spot_pricing` fixes the issue.

Full traceback:

```
Traceback (most recent call last):
  File "/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py", line 1652, in <module>
    main()
  File "/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py", line 1641, in main
    (instance_dict_array, new_instance_ids, changed) = create_instances(module, ec2, vpc)
  File "/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py", line 1217, in create_instances
    res_list = ec2.get_all_instances(instids)
  File "/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py", line 585, in get_all_instances
    max_results=max_results)
  File "/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py", line 663, in get_all_reservations
    self.build_list_params(params, instance_ids, 'InstanceId')
  File "/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/connection.py", line 1122, in build_list_params
    params['%s.%d' % (label, i)] = items[i - 1]
TypeError: 'dict_values' object does not support indexing

fatal: [localhost -> localhost]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py\", line 1652, in <module>\n    main()\n  File \"/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py\", line 1641, in main\n    (instance_dict_array, new_instance_ids, changed) = create_instances(module, ec2, vpc)\n  File \"/var/folders/xr/92n4lxy129lcsb7mjh09yj1w0000gn/T/ansible_0fcxaicf/ansible_module_ec2.py\", line 1217, in create_instances\n    res_list = ec2.get_all_instances(instids)\n  File \"/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py\", line 585, in get_all_instances\n    max_results=max_results)\n  File \"/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/ec2/connection.py\", line 663, in get_all_reservations\n    self.build_list_params(params, instance_ids, 'InstanceId')\n  File \"/Users/nederhrj/anaconda3/envs/aws34/lib/python3.4/site-packages/boto/connection.py\", line 1122, in build_list_params\n    params['%s.%d' % (label, i)] = items[i - 1]\nTypeError: 'dict_values' object does not support indexing\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
```



Discussion:
* Does this only happen with python3?  Not with python2 on the remote machine?
* What version of boto do you have installed?  Since the traceback is coming from within boto code that could be important information to know.
* Note that we don't support Python-3.4; some modules and controller code is known to need Python-3.5 or greater.  I don't believe that's the issue here as dict_values is common to all of Python-3.x but using Python-3.4 could lead to other problems.

needs_info
* Does this only happen with python3?  Not with python2 on the remote machine?
* What version of boto do you have installed?  Since the traceback is coming from within boto code that could be important information to know.
* Note that we don't support Python-3.4; some modules and controller code is known to need Python-3.5 or greater.  I don't believe that's the issue here as dict_values is common to all of Python-3.x but using Python-3.4 could lead to other problems.

needs_info

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
@@ -914,7 +914,7 @@ def await_spot_requests(module, ec2, spot_requests, count):
         if len(spot_req_inst_ids) < count:
             time.sleep(5)
         else:
-            return spot_req_inst_ids.values()
+            return list(spot_req_inst_ids.values())
     module.fail_json(msg="wait for spot requests timeout on %s" % time.asctime())
 
 


Test patch: