Repository: ansible/ansible

Issue:
"a bytes-like object is required" Error on ec2 keypair module 
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
ec2/keypair

##### ANSIBLE VERSION
```
ansible 2.3.0 (devel a5e3d13adc) last updated 2017/02/28 09:29:30 (GMT +550)
  config file = 
  configured module search path = Default w/o overrides
```
Built locally

##### OS / ENVIRONMENT
N/A

##### SUMMARY
The ec2 keypair module errors out with a "TypeError: a bytes-like object is required, not 'str'" when run with python 3.

##### STEPS TO REPRODUCE
```
ec2_key:
         aws_access_key: "{{ accessKey }}"
         aws_secret_key: "{{ secretKey }}"
         name: testKey
         region: us-west-1
         key_material: 'ssh-rsa  ....'
         state: present
 ```

##### EXPECTED RESULTS
Keypair should be created successfully

##### ACTUAL RESULTS
```
TypeError: a bytes-like object is required, not 'str'
```

Boto connection.py's import_key_pair has a base64.b64encode method that takes the public key and encodes it, Unfortunately python3 expects that to be a byte stream rather than a string. 

Doing a 
```
tmpkey = ec2.import_key_pair(tmpkeyname, key_material.encode())
```
instead of
```
tmpkey = ec2.import_key_pair(tmpkeyname, key_material) 
```
on the ec2 module fixes this. This happens in both the states as well as the force method on the ec2 module. Pls let know if a PR can be posted.
"a bytes-like object is required" Error on ec2 keypair module 
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
ec2/keypair

##### ANSIBLE VERSION
```
ansible 2.3.0 (devel a5e3d13adc) last updated 2017/02/28 09:29:30 (GMT +550)
  config file = 
  configured module search path = Default w/o overrides
```
Built locally

##### OS / ENVIRONMENT
N/A

##### SUMMARY
The ec2 keypair module errors out with a "TypeError: a bytes-like object is required, not 'str'" when run with python 3.

##### STEPS TO REPRODUCE
```
ec2_key:
         aws_access_key: "{{ accessKey }}"
         aws_secret_key: "{{ secretKey }}"
         name: testKey
         region: us-west-1
         key_material: 'ssh-rsa  ....'
         state: present
 ```

##### EXPECTED RESULTS
Keypair should be created successfully

##### ACTUAL RESULTS
```
TypeError: a bytes-like object is required, not 'str'
```

Boto connection.py's import_key_pair has a base64.b64encode method that takes the public key and encodes it, Unfortunately python3 expects that to be a byte stream rather than a string. 

Doing a 
```
tmpkey = ec2.import_key_pair(tmpkeyname, key_material.encode())
```
instead of
```
tmpkey = ec2.import_key_pair(tmpkeyname, key_material) 
```
on the ec2 module fixes this. This happens in both the states as well as the force method on the ec2 module. Pls let know if a PR can be posted.


Discussion:

Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/ec2_key.py b/lib/ansible/modules/cloud/amazon/ec2_key.py
--- a/lib/ansible/modules/cloud/amazon/ec2_key.py
+++ b/lib/ansible/modules/cloud/amazon/ec2_key.py
@@ -117,6 +117,7 @@
 except ImportError:
     HAS_BOTO = False
 
+from ansible.module_utils._text import to_bytes
 import random
 import string
 
@@ -226,7 +227,7 @@ def main():
             if not module.check_mode:
                 if key_material:
                     '''We are providing the key, need to import'''
-                    key = ec2.import_key_pair(name, key_material)
+                    key = ec2.import_key_pair(name, to_bytes(key_material))
                 else:
                     '''
                     No material provided, let AWS handle the key creation and


Test patch: