Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EC2 user-data error when spot_price != null #34978

Closed
brainstorm opened this issue Jan 17, 2018 · 5 comments · Fixed by #37628
Closed

EC2 user-data error when spot_price != null #34978

brainstorm opened this issue Jan 17, 2018 · 5 comments · Fixed by #37628
Labels
affects_2.4 This issue/PR affects Ansible v2.4 aws bug This issue/PR relates to a bug. cloud module This issue/PR relates to a module. python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team.

Comments

@brainstorm
Copy link

brainstorm commented Jan 17, 2018

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ec2

ANSIBLE VERSION
$ ansible --version
ansible 2.4.2.0
  config file = /Users/romanvg/dev/pcgr-deploy/ansible/ansible.cfg
  configured module search path = ['/Users/romanvg/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/site-packages/ansible
  executable location = /Users/romanvg/.miniconda/envs/ansible24/bin/ansible
  python version = 3.6.3 | packaged by conda-forge | (default, Nov  4 2017, 10:13:32) [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]
CONFIGURATION

$ ansible-config dump --only-changed
ANSIBLE_SSH_ARGS(/Users/romanvg/dev/pcgr-deploy/ansible/ansible.cfg) = -o ControlMaster=auto
HOST_KEY_CHECKING(/Users/romanvg/dev/pcgr-deploy/ansible/ansible.cfg) = False
INVENTORY_ENABLED(/Users/romanvg/dev/pcgr-deploy/ansible/ansible.cfg) = ['host_list', 'script', 'yaml', 'ini', 'constructed']
RETRY_FILES_ENABLED(/Users/romanvg/dev/pcgr-deploy/ansible/ansible.cfg) = False

OS / ENVIRONMENT

N/A

SUMMARY

There's a parsing error on the base64 encoding of user-data when spot-price has a defined price.

https://github.com/brainstorm/pcgr-deploy/blob/master/ansible/aws.yml#L16

STEPS TO REPRODUCE

ansible-playbook aws.yaml

---
- hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: Launch EC2 instance
      ec2:
         group: "{{ aws.security_group }}"
         instance_type: "{{ aws.instance_type }}"
         instance_profile_name: "{{ aws.instance_profile_name }}"
         instance_tags:
             Name: pcgr "{{ pcgr.release }}"
             name: pcgr
             pcgrexecid: "{{ pcgr.execution_id }}"
         spot_price: "{{ aws.spot_price }}"
         user_data: "{{ lookup('file', 'files/s3_user_data.sh') }}"
         image: "{{ aws.image_id }}"
         keypair: "{{ aws.keypair }}"
         region: "{{ aws.region }}"
         zone: "{{ aws.zone }}"
         wait: yes
         volumes:
           - device_name: "{{ aws.volume_device }}"
             volume_type: gp2
             volume_size: "{{ aws.volume_size }}"
             delete_on_termination: true
         count_tag:
           name: pcgr
         exact_count: 1
      register: ec2

    - name: Add new instance to host group
      add_host:
        hostname: "{{ item.public_dns_name }}"
        groupname: launched
      with_items: "{{ ec2.instances }}"

    - name: Wait for SSH to come up
      wait_for:
        host: "{{ item.public_dns_name }}"
        port: 22
        delay: 60
        timeout: 320
        state: started
      with_items: "{{ ec2.instances }}"
EXPECTED RESULTS

Clean instantiation of an ec2 instance, loading its corresponding user-data:

https://github.com/brainstorm/pcgr-deploy/blob/master/ansible/files/s3_user_data.sh

ACTUAL RESULTS
(ansible24) brainstorm:ansible romanvg$ ansible-playbook aws.yml -vvvv
ansible-playbook 2.4.2.0
  config file = /Users/romanvg/dev/pcgr-deploy/ansible/ansible.cfg
  configured module search path = ['/Users/romanvg/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/site-packages/ansible
  executable location = /Users/romanvg/.miniconda/envs/ansible24/bin/ansible-playbook
  python version = 3.6.3 | packaged by conda-forge | (default, Nov  4 2017, 10:13:32) [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]
Using /Users/romanvg/dev/pcgr-deploy/ansible/ansible.cfg as config file
setting up inventory plugins
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: Could not match supplied host pattern, ignoring: all

 [WARNING]: provided hosts list is empty, only localhost is available

Loading callback plugin default of type stdout, v2.0 from /Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/site-packages/ansible/plugins/callback/__init__.py

PLAYBOOK: aws.yml ************************************************************************************************************************************************************************************************************************************************
1 plays in aws.yml

PLAY [localhost] *************************************************************************************************************************************************************************************************************************************************
META: ran handlers

TASK [Launch EC2 instance] ***************************************************************************************************************************************************************************************************************************************
task path: /Users/romanvg/dev/pcgr-deploy/ansible/aws.yml:6
Using module file /Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/site-packages/ansible/modules/cloud/amazon/ec2.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: romanvg
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/romanvg/.ansible/tmp/ansible-tmp-1516170269.445788-236322726281460 `" && echo ansible-tmp-1516170269.445788-236322726281460="` echo /Users/romanvg/.ansible/tmp/ansible-tmp-1516170269.445788-236322726281460 `" ) && sleep 0'
<127.0.0.1> PUT /var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/tmpk8nz061i TO /Users/romanvg/.ansible/tmp/ansible-tmp-1516170269.445788-236322726281460/ec2.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/romanvg/.ansible/tmp/ansible-tmp-1516170269.445788-236322726281460/ /Users/romanvg/.ansible/tmp/ansible-tmp-1516170269.445788-236322726281460/ec2.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/Users/romanvg/.miniconda/envs/ansible24/bin/python /Users/romanvg/.ansible/tmp/ansible-tmp-1516170269.445788-236322726281460/ec2.py; rm -rf "/Users/romanvg/.ansible/tmp/ansible-tmp-1516170269.445788-236322726281460/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py", line 1725, in <module>
    main()
  File "/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py", line 1719, in main
    (tagged_instances, instance_dict_array, new_instance_ids, changed) = enforce_count(module, ec2, vpc)
  File "/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py", line 963, in enforce_count
    = create_instances(module, ec2, vpc, override_count=to_create)
  File "/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py", line 1253, in create_instances
    res = ec2.request_spot_instances(spot_price, **params)
  File "/Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/site-packages/boto/ec2/connection.py", line 1616, in request_spot_instances
    params['%s.UserData' % ls] = base64.b64encode(user_data)
  File "/Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'

fatal: [localhost]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py\", line 1725, in <module>\n    main()\n  File \"/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py\", line 1719, in main\n    (tagged_instances, instance_dict_array, new_instance_ids, changed) = enforce_count(module, ec2, vpc)\n  File \"/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py\", line 963, in enforce_count\n    = create_instances(module, ec2, vpc, override_count=to_create)\n  File \"/var/folders/wz/__dd9trs0kl4jb3rs83704y80000gn/T/ansible_6sdx67__/ansible_module_ec2.py\", line 1253, in create_instances\n    res = ec2.request_spot_instances(spot_price, **params)\n  File \"/Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/site-packages/boto/ec2/connection.py\", line 1616, in request_spot_instances\n    params['%s.UserData' % ls] = base64.b64encode(user_data)\n  File \"/Users/romanvg/.miniconda/envs/ansible24/lib/python3.6/base64.py\", line 58, in b64encode\n    encoded = binascii.b2a_base64(s, newline=False)\nTypeError: a bytes-like object is required, not 'str'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1

/cc @vladsaveliev

@ansibot
Copy link
Contributor

ansibot commented Jan 17, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot
Copy link
Contributor

ansibot commented Jan 17, 2018

@ansibot ansibot added affects_2.4 This issue/PR affects Ansible v2.4 aws bug_report cloud module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Jan 17, 2018
@brainstorm brainstorm changed the title EC2 user-data error with python3 runtime EC2 user-data error when spot_price != null Jan 17, 2018
@sivel sivel removed the needs_triage Needs a first human triage before being processed. label Jan 17, 2018
@brainstorm
Copy link
Author

Can anyone confirm this bug?

@ansibot ansibot added bug This issue/PR relates to a bug. and removed bug_report labels Mar 1, 2018
abadger added a commit to abadger/ansible that referenced this issue Mar 20, 2018
The user_data field is base64 encoded inside of the boto library.  In
Python3, base64 must be used with byte strings.  So we make sure to
encode the user_data into a byte string before passing it on to the boto
library.

Fixes ansible#34978
@abadger
Copy link
Contributor

abadger commented Mar 20, 2018

@brainstorm I don't use ec2 but I do fix Python3 bugs. Can you test whether this PR fixes your issue? #37628

s-hertel pushed a commit that referenced this issue Mar 20, 2018
The user_data field is base64 encoded inside of the boto library.  In
Python3, base64 must be used with byte strings.  So we make sure to
encode the user_data into a byte string before passing it on to the boto
library.

Fixes #34978
abadger added a commit to abadger/ansible that referenced this issue Mar 20, 2018
The user_data field is base64 encoded inside of the boto library.  In
Python3, base64 must be used with byte strings.  So we make sure to
encode the user_data into a byte string before passing it on to the boto
library.

Fixes ansible#34978

(cherry picked from commit 0d55081)
@abadger abadger moved this from TODO to Done in Python 3 compatibility Mar 20, 2018
@brainstorm
Copy link
Author

Woah, thanks @abadger! Will give it a try ;)

nitzmahone pushed a commit that referenced this issue Mar 29, 2018
* Fix use of user_data field with spot_price in ec2 module (#37628)

The user_data field is base64 encoded inside of the boto library.  In
Python3, base64 must be used with byte strings.  So we make sure to
encode the user_data into a byte string before passing it on to the boto
library.

Fixes #34978

(cherry picked from commit 0d55081)

* Python3 ec2 fix added to changelog
abadger added a commit that referenced this issue Mar 29, 2018
The user_data field is base64 encoded inside of the boto library.  In
Python3, base64 must be used with byte strings.  So we make sure to
encode the user_data into a byte string before passing it on to the boto
library.

Fixes #34978

(cherry picked from commit 0d55081)
@ansible ansible locked and limited conversation to collaborators Apr 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.4 This issue/PR affects Ansible v2.4 aws bug This issue/PR relates to a bug. cloud module This issue/PR relates to a module. python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

4 participants