11

I have a very simple Ansible playbook, all dependencies installed for docker-compose and docker but I get an error when installing docker-compose, this is the task on my playbook to install docker-compose in a CentOS7 environment.

    #ensure docker-compose and chmod +x /usr/local/bin/docker-compose
  - name: Ensure docker-compose is installed and available
    command: curl -L https://github.com/docker/compose/releases/download/1.7.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
  - name: Ensure permissions docker-compose
    command: chmod +x /usr/local/bin/docker-compose

The following error appears:

TASK: [Ensure docker-compose is installed and available] ********************** 
failed: [nutrilife-aws] => {"changed": true, "cmd": ["curl", "-L", "https://github.com/docker/compose/releases/download/1.7.0-rc1/docker-compose-`uname", "-s`-`uname", "-m`", ">", "/usr/local/bin/docker-compose"], "delta": "0:00:00.004592", "end": "2016-03-26 14:19:41.852780", "rc": 2, "start": "2016-03-26 14:19:41.848188", "warnings": ["Consider using get_url module rather than running curl"]}
stderr: curl: option -s`-`uname: is unknown
curl: try 'curl --help' or 'curl --manual' for more information

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/mmaia/playbook.retry

nutrilife-aws              : ok=4    changed=0    unreachable=0    failed=1 

I am kind of stuck with this simple error for a couple of hours. I got the command from standard docker site and tested directly in the shell and it works. I have also tried using double quotes to wrap around the command like command: "curl ..." but it didn't change the error.

2 Answers 2

23

As helloV pointed out you need to use the shell module if you want to utilise things like shell expansion or the shell's environment variables.

However, in Ansible you are typically better off using higher level modules and only resorting to the shell or command modules if you can't do what you need with another module. This approach gives you better control of execution for free such as easy idempotency and better output visibility.

In your case you can use get_url (I believe Ansible will actually warn you if you attempt to shell out with curl that you might be better off with this module) to fetch things from the internet.

In your case your task might look something like this:

  - name: Ensure docker-compose is installed and available
    get_url: 
      url : https://github.com/docker/compose/releases/download/1.7.0-rc1/docker-compose-{{ ansible_system }}-{{ ansible_userspace_architecture }}
      dest: /usr/local/bin/docker-compose
      mode: 'u+x,g+x'

The above task uses special variables that are returned by gathering facts on the targeted host so that your task should run fine on either Linux systems or OS X (you'd need a conditional suffix of .exe for the Windows link to work and obviously a different destination path etc).

It also uses the mode parameter from the file module to add execution permissions for the user and group so you can avoid your chmod task.

Sign up to request clarification or add additional context in comments.

5 Comments

This looks like a wise suggestion, will also try it as it seems a better "good practice". Thank you!
Your answer helped me a lot. I had to install linux-image-extra-$(uname -r) as a package in a yaml list, but I couldn't. Goole introduce me this page and your point about using gathering facts helped me. Now I can install via linux-image-extra-{{ ansible_kernel }}. Thanks
I would also suggest to use checksum when it comes to downloading files over the internet!
I ended up explicitly setting the mode mode: 'u=rwx,g=rx,o=rx', which mirrors the same permissions on the docker executable installed via apt-get. This will also create the file with root owner and group (assuming you are running ansible as root). Any other user that needs this should be added to the sudoers group anyway for docker to work.
If ansible complains about ansible_system or similar missing, you might have set gather_facts: no somewhere in your config or provisioning.yml. Change it to yes so that ansible gathers facts about your system (like version, etc..) on startup
7

command is not processed through a shell. Use shell.

  - name: Ensure docker-compose is installed and available
    shell: curl -L https://github.com/docker/compose/releases/download/1.7.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

1 Comment

Yeah, it worked and yes, I am a total noob with ansible :) . Thanks a bunch.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.