ansible unable to find boto: boto required for this module

Created on 17 Mar 2016  ·  32Comments  ·  Source: ansible/ansible

The "msg": "boto required for this module" seems to make all aws support in ansible useless as the logic seems to be broken in too many places.

This is broken in both cases, even if you try to run via local_action or directly and I checked

- hosts:
  - localhost

  tasks:
    - pip:
        name: boto
    - name: Provision Krypton (kr)
      local_action: ec2
        key_name=kr
        instance_type=m4.4xlarge
        image=ami-c109e8aa
        wait=yes
        group=webserver
        count=3
        vpc_subnet_id="{{ aws_vpc }}"
        assign_public_ip=yes

This is happening on an OS X machine, and I verified that I have boto installed.

Python 2.7.10 (default, Jul 13 2015, 12:05:58)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto

As you can observe from the playbook itself, it does also import boto on the target machine, and if you call the ec2 module directly instead of using the local_action, you will still get the same error.

which python
/usr/local/bin/python

Most helpful comment

@stevenscg, still working me with this in my inventory file:

[localhost]
localhost ansible_connection=local ansible_python_interpreter=python

Let me know if that does anything for you!

All 32 comments

List Information

Hi!

Thanks very much for your interest in Ansible. It sincerely means a lot to us.

This appears to be a user question, and we'd like to direct these kinds of things to either the mailing list or the IRC channel.

If you can stop by there, we'd appreciate it. This allows us to keep the issue tracker for bugs, pull requests, RFEs and the like.

Thank you once again and we look forward to seeing you on the list or IRC. Thanks!

@bcoca closing bugs with copy and past is going to help with building a community goals. That's valid bug report, not a but.

The fact that ansible assumes that python 2 is installed on /usr/bin/python is a bug, quite a critical one.

@ssbarnea - Been banging my head off this nuisance issue as well for everything ec2-related ever since I added localhost explicitly to the host file to include it in the limit pattern.

https://www.zigg.com/2014/using-virtualenv-python-local-ansible.html has a decent solution that seems to be working both for actions directly with hosts: localhost or calling local_action

@ssbarnea @pauricthelodger Are you guys still having issues with this?

I just had a playbook that has worked for months (years) start failing on local_action: ec2_elb when registering an instance with ELB and using the ec2.py inventory.

Happens for me when running from MacOS with Ansible 2.0.0.2, 2.0.1, and 2.1.0.

I haven't tried the zigg article recommendations yet.

TASK [AWS - Register instances with the load balancer] *************************
fatal: [10.x.x.x -> localhost]: FAILED! => {"changed": false, "failed": true, "msg": "boto required for this module"}
$ which python
/usr/local/bin/python

$ pip list boto | grep boto
boto (2.38.0)
boto3 (1.1.4)
botocore (1.2.10)

$ ansible --version
ansible 2.0.0.2

$ python -V
Python 2.7.9

@stevenscg, still working me with this in my inventory file:

[localhost]
localhost ansible_connection=local ansible_python_interpreter=python

Let me know if that does anything for you!

@pauricthelodger I can confirm that this worked for me on ansible versions 2.0.0.2, 2.0.1, and 2.1.0. Thanks again!

Any reason this is closed? It's still an issue on OS X (Sierra):

$ which python
/usr/local/bin/python

$ pip list boto | grep boto
boto (2.45.0)
botocore (1.5.1)

$ ansible --version
ansible 2.2.1.0

$ python -V
Python 2.7.12

The inventory file work-around gets past it, but still an issue.

@rolette Ansible uses default /usr/bin/python (not the same as /usr/local/bin/python). My advice - use virtualenv (virtualenv .venv)

and your localhost inventory: inventory/localhost:

#!/bin/bash
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.."
echo "{
  \"localhost\": {
    \"ansible_connection\": \"local\",
    \"ansible_python_interpreter\": \"${ROOT_DIR}/.venv/bin/python\"
  }
}"

@wojtek-oledzki Thanks for another work-around, but what I'm looking for is a fix for ansible so it works properly on OS X instead of requiring everyone that runs into the problem to spend time tracking down a work-around.

it's not a workaround - it's how python works. You have to simply tell Ansible where your python executable is if you do not want to use the default location /usr/bin/python.

negative ghostrider... Oddly enough, every other python program manages to work just fine without requiring a virtualenv.

Hard-coding paths to executables breaks in lots of environments. Usually it's not entire platforms like this particular bug though.

Let's be correct, the right way to call python is via #!/usr/bin/env python and not via a hardcoded path. There is one exception to this rule, the shell scripts from virtualenvs where it is prefered to have a full path instead of using env.

On MacOS using the default system Python the env happens to resolve to /usr/bin/python but this does not mean that we should see /usr/bin/python in the installed script.

One thing that I used over time was to avoid using the shell scripts and to call ansible as a module.

@ssbarnea Agreed, except that #!/usr/bin/env python does the right thing within virtualenvs, so still no reason to hardcode the path.

Got the same error when use ec2_tag module in ansible.

TASK [Retrieve all tags on an instance] ****************************************
fatal: [10_12_26_12]: FAILED! => {"changed": false, "failed": true, "msg": "boto required for this module"}

playbook:

  - name: Get instance ec2 facts
    action: ec2_facts
    register: ec2_facts

  - name: Retrieve all tags on an instance
    ec2_tag:
      region: '{{ ansible_ec2_placement_region }}'
      resource: '{{ ansible_ec2_instance_id }}'
      state: list
    register: ec2_tags

But work with local_action

  - name: Get instance ec2 facts
    action: ec2_facts
    register: ec2_facts

  - name: Get resource tags from ec2 facts
    #sudo: false
    local_action: ec2_tag resource={{ec2_facts.ansible_facts.ansible_ec2_instance_id}} region={{ec2_facts.ansible_facts.ansible_ec2_placement_region}} state=list
    register: ec2_tags

Same error with ec2_elb tag:

  pre_tasks:
    - name: Gathering ec2 facts
      action: ec2_facts
    - name: Trackor Instance de-register
      become: no
      local_action:
        module: ec2_elb
        region: "{{ ansible_ec2_placement_region }}"
        instance_id: "{{ ansible_ec2_instance_id }}"
        state: absent
        wait_timeout: 30
        ec2_elbs: '{{ trackor_elb_name }}'

Not sure it's connected but, in case it helps people down the road, I just noticed the following in the devel changelog under Ansible 2.3:

Added 'ansible_playbook_python' which contains 'current python executable', it can be blank in some cases in which Ansible is not invoked via the standard CLI (sys.executable limitation).

If you're on Mac and you have installed other copies of python via homebrew, you can run these commands to install boto to the system python:

sudo /usr/bin/python -m easy_install pip
sudo /usr/bin/python -m pip install boto

This solved the problem. Thank you!!

I'm using Arch Linux and default seems to be python 3 while Ansible seems to be using python 2 by default.
So @rsanchez's solution works for me if I replace python with explicit python2.
Thanks.

In addition to @rsanchez's solution to the scenario where there might be multiple copies of python on your mac, another way is to tell ansible which python to use via the "ansible_python_interpreter" variable.

Suppose /usr/bin/python does not have boto in its path and the python at /usr/local/bin/python (installed via homebrew) has it ("import boto" works while in the repl). You can then set "ansible_python_interpreter= /usr/local/bin/python" in the inventory file.

Also you set it at the command line with the "--extra-vars='ansible_python_interpreter=/usr/local/bin/python '" option.

I was having this same problem, but with netaddr.

Ansible was using some absolutely random python version installed on my machine:

ansible all -i ./.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory -m debug -a "var=ansible_playbook_python"
elastic0 | SUCCESS => {
    "ansible_playbook_python": "/usr/local/opt/python/bin/python2.7"
}

I then just used the /usr/local/opt/python/bin/python2.7 -m pip install netaddr trick to get it installed.

I'm wondering if python environment variables such as PYTHON_HOME and PYTHON_PATH would help this issue, but I don't know too much about them.

When I naively did a docker build for ansible 2.3.1.0 with somethhing like

FROM python:2.17
RUN pip install --upgrade pip
RUN pip install boto3 botocore ansible>=2.3.1.0 awscli

I got the error

fatal: [127.0.0.1]: FAILED! => {"changed": false, "failed": true, "msg": "boto3 and botocore are required for this module"}

Huh, interesting. Of course I can set the interpreter to some hard coded thing, or find some other workaround, but it's important to note as said before that _no other python apps have this problem_. Only fair to point out that the way ansible marshals the tasks out to hosts ( even localhost without ssh ) is copying a python executable - but nevertheless, that executable should respect the environment settings.

To get up on a soapbox for a second, ignorance of standard practice s a recurring problem with ansible. I've had so many challenges with using the AWS modules with session tokens ( for role assumption or mfa auth ) that I tend to use awscli for everything possible. The silly thing is, if they would have just let boto handle the resolution of credentials instead of injecting their own 2/3 solution of passing them about, they'd have had the best of both worlds. Granted, the local credentials wouldn't be available from remote hosts, but 1) if they didn't have their own credentials, what would be the point of running the task remotely anyway, as it would only hit a public api anyway and that could just as easily be done locally in most cases; and 2) if they did have their own credentials, you'd probably want to pick them up. Unrelated, but another example of the ansible implementers proceeding in ignorance of a best practice they could have and should have followed. Easy for me to say, I'm not trying to implement ansible :P

As a temp fix I did:

[local]
localhost              ansible_connection=local     ansible_python_interpreter=/usr/local/bin/python3

I have pip, botocore, and boto3 integrated to python3, not the Mac OS default /usr/bin/python. As a proper fix I might try to set the ansible_python_interpreter as an environment variable.

Any reason why this is closed ? Still having this issue on 2.5 devel.

My nuclear-option workaround was to go hack up the ansible install in my site-packages, because I don't want to remember to pass extra vars every single time. You may wince, don't yell at me, proceed at own risk, no warranty express or implied.

To find the files:

python -c "import ansible; print ansible.__path__"

To fix all python shebangs:

 grep -lir "/usr/bin/python" /path/to/my/site-packages/ansible/* | xargs sed -i '' "s|/usr/bin/python|/usr/bin/env python|g"

I had faced some error by doing this
fatal: [localhost]: FAILED! => {"changed": false, "msg": "boto required for this module"}
but boto is installed already
so I used this command (because am using the mac)
sudo /usr/bin/python -m pip install boto
and I added one more line in env/hosts
ansible_pyhton_interpreter=/usr/bin/python
so its work

anyone can suggest what is the reason for getting these error, I had installed already boto then why I need this command
sudo /usr/bin/python -m pip install boto

@jawad486, I use a Mac as well and have made it a practice to run ansible exclusively with docker. It has completely avoided issues with finding modules and has made it possible to reliable run any version of ansible , new or old, simultaneously. I can't say the same of any other method with brew, virtualenv, or the built-in Python. I mount in ~/.aws and ~/.ssh as necessary.

@jawad846 Read back through the posts on this issue. It's a bug. ansible incorrectly hardcodes the path to python instead of getting it from the environment.

In ansible 2.5.1 this problem still persists (on linux), and different modules behave differently. I have used @pauricthelodger workaround with the ansible_python_interpreter=python setting in the hosts file. This causes ec2_vpc_net and ec2_vpc_subnet to work, but ec2_vpc_igw to fail with {"changed": false, "msg": "boto is required for this module"}. Which is strangely funny because these modules are all part of the same set and used together.

Digging into this I found that ec2_vpc_net and ec2_vpc_subnet use boto3, but ec2_vpc_igw use boto v2. Thus you will need to install into your virtualenv BOTH boto3 and boto2. Then I munged all the shebang headers with a modified version of @benauthor s sed script. I set it up in my Makefile to run after building the virtualpython, thusly:

grep -lir "/usr/bin/python" vp/local/lib/python2.7/site-packages/ansible/* | xargs sed -i "s@/usr/bin/python@/usr/bin/env python@g"

Where vp is the local virtualenv path I am using.

Still an issue on 2.5.2 also

@timm088 I just fixed that issue in my macbook.
run "which python". it should provide you the path, in my case it was "/usr/local/bin/python".
Then go to your inventory file, paste that path in ansible_python_interpreter.
This is how my inventory hosts file looks:
[local]
localhost ansible_connection=local ansible_python_interpreter=/usr/local/bin/python/

It should work now.

I'm assuming the Ansible developers haven't seen any of the ongoing discussions since it was auto-closed 4 days after it was opened. I finally got around to posting a question on the mailing list to see if we can get it fixed that way.

https://groups.google.com/forum/#!topic/ansible-project/WCqmyKB46qQ

Was this page helpful?
0 / 5 - 0 ratings