Ansible Modules – shell vs. command

In the Ansible Core are a lot of Ansible modules included for almost all use cases. On this page
are all modules listed and described with the available options and some examples. Some Ansible modules are on the first view quite similar and can be used for the same purpose, but often are there some crucial differences.

Shell vs. Command

A typical example are the Ansible modules Shell and Command. In the most use cases both modules lead to the same goal. Here are the main differences between these modules.

  • With the Command module the command will be executed without being proceeded through a shell. As a consequence some variables like $HOME are not available. And also stream operations like <, >, | and & will not work.
  • The Shell module runs a command through a shell, by default /bin/sh. This can be changed with the option executable. Piping and redirection are here therefor available.
  • The command module is more secure, because it will not be affected by the user’s environment.

Conclusion

Before the usage of both modules, you should check, if there isn’t a more specific Ansible module for that task. It’s always better to use a module instead of running a raw command, because the modules are designed to be idempotent and fulfill other standards like exception handling.

If there isn’t a module available, it’s safer to use the command module, because the task will not be affected through the user environment.

If you need the user environment or streaming operations there’s only the shell module, but you should be careful. Keep in mind the following hint from Ansible, if you use the shell module in combination with variables:

To sanitize any variables passed to the shell module, you should use “{{ var | quote }}” instead of just “{{ var }}” to make sure they don’t include evil things like semicolons.)

28 Comments

  • Max

    Maybe include infos about the raw module

    • Dominique Barton

      Good point Max. I think we should add another blog entry for the `raw` module, as it can execute commands on a remote machine without using Python. Thanks for the hint!

  • Howard

    Very helpful!! I was wondering why ‘mkdir /data && chown user:user /data’ does not work in command, because && is streaming operation!

  • Zex

    Unfortunately, Ansible is incapable of executing some common shell commands. For example when you use shell sequence it won’t work in ansible:

    shell: echo {1..5000}

    When you copy the above command to shell and execute, it will echo 5000 numbers. Of course, echo repeated 5000 times is not that useful, but I have a real-life example with configuring redis cluster where you have to assign slots in a loop. Now, shell is incredibly fast and does it in less than a second.

    If you try to simulate it by using Ansible loops, it’s so slow that our Sun will inflate and scorch the Earth before you see the end of that loop.

    On top of that, yaml imposes some stupid limitations, after that the Ansible parser imposes some idiotic limitations, for example you can write – fail msg=”Error” but not – fail msg = “Now it really failed”, because they forgot to skip whitespace during parsing. However, you can add spaces around the == sign, because I guess that part was written by another programmer.

    If you’re a programmer, Ansible is total crap. It doesn’t simplify things. More like “complexifies”.
    If you’re a non-programmer, and you learn Ansible, you’ll probably never learn how to program because it will screw up your brain.

    Haven’t seen for a long time that many design mistakes like in Ansible. And I’ve been coding in Erlang, so I know how horrible the design mistakes can be.

    • Dominique Barton

      Hi Zex.

      Oh gosh, Erlang – please hit me as hard as you can!
      Just kidding. It seems you’re just here to bash against Ansible which is fine. You don’t like it and that’s your personal preference. I’m happy that you can share your personal experience here in our blog.

      However, I’m a developer too. I used to program PHP, Java, Objectiv-C, a bit of C and C++ and lately a lot of Python. I’m probably not that hardcore developer as you are, but hey that’s OK. So even if I’m a programmer, I don’t think Ansible is “total crap”. Sure there are some things which could be optimised, but hey nothing’s perfect. Some bits of the code are a bit odd, sure. But instead of complaining about Ansible you could make a difference in let’s say, fixing the code and opening a merge request on Github?

      Regarding your “problem”. I’m sure you’re aware of the fact that the `{1..5000}` syntax is a shell-specific syntax (e.g. bash), which means you can’t really compare Ansible’s shell module with bash (or alike). However, you can pass that syntax via Ansible to bash or create a bash script and execute it. I’m sure both of these methods would work.

      Now as you’re the perfect developer and you’re very well experienced in Erlang, hit us with an alternative solution to Ansible. Do you have built a product by yourself and do you want to share it, probably even open-source? I’m open-minded and I love great products which make my life as a system engineer / developer simpler.

      I’m enthusiastic, passioned and impulsive too. It’s a great gift, but writing whining blog posts doesn’t help you nor the guys who put all that effort into an IMHO great product. So next time, please be more kind. You seem to have a lot of knowledge and it would be great if you can share it with people around you in a nice way.

      You can express yourself in several ways. One way about my opinion of Erlang could be:

      > Erlang is total bullshit and next to assembler the ugliest programming language out there. This will totally fuck up your brain.

      Or I could say:

      > I don’t like Erlang, because in my opinion it doesn’t look very nice. I like nice styled code. However, the performance of Erlang is outstanding and isn’t comparable to Java.

      As you can see, the second one is much nicer and reflects by personal opinion, while the first statement is offending anyone who might like, programm and contribtue to Erlang.

      Cheers & have a nice day
      Domi

    • Alan Sible

      Hilarious.
      So true, I quite like ansible from an operational point of view, yet I entirely agree with your opinion.

      PS: you forgot the blank space before your list items, syntax error: invisible panic mode activated!

  • Santosh

    I’m surprised !! unstable behaviors of shell and command modules:

    Suddenly “rm -rf ” command stop working with command module, even it was working fine in past on same host. when i used same command ( rm -rf ) with shell then it works, But again error, now shell command fails on different host.

    Below are the error :
    failed: [xxxxxxxxxx.com] => {“changed”: true, “cmd”: [“rm”, “-rf”, “/xxx/xxxx/xxxx/xxxx/jenkins”], “delta”: “0:00:00.651038”, “end”: “2016-11-23 03:15:49.552958”, “rc”: 1, “start”: “2016-11-23 03:15:48.901920”, “warnings”: [“Consider using file module with state=absent rather than running rm”]}
    stderr: rm: cannot remove `/xxx/xxxx/xxxx/xxxx/jenkins/jenkins/WEB-INF/lib’: Directory not empty

    Any help ?

    • Paolo

      @santosh both “Consider using file module with state=absent rather than running rm” and “Directory not empty” seem to be more than sufficient hints to me…

      • Santosh

        Hi Paolo, Thanks for your reply, I already checked, even file module is not working for me. my Ansible version is 1.9.4
        same error showing below link:
        https://github.com/ansible/ansible/issues/11087

        currently I’m moving the folder instead of deleting 🙂

    • Lilian

      Very true! Makes a change to see sonmeoe spell it out like that. 🙂

  • happy wheels

    To sanitize any variables passed to the shell module, you should use “{{ var | quote }}” instead of just “{{ var }}” to make sure they don’t include evil things like semicolons.)

    • Writing Metier

      Hey Happy,

      Are you absolutely sure this option is working? Coz, I’m trying to complete this right now and have issues. I’m changing “{{ var | quote }}” instead of just “{{ var }}” but it doesn’t help. Maybe I didn’t get your point?

  • Austin Taylor

    It was a piece of nice information shared by the author. Please share some more articles. I am very interested to read such kind of articles in the future.

  • Sophie Walker

    It’s time to choose the best on Assignment service online in the Australia. We are in the Assignment writing service industry for the last 10 years.

  • themarketingviews

    We provide the best SEO services according to our client/customer requirement & need in a good budget. We also working on given deadlines by using our expertise of our professional employees

  • kohls voucher

    Great job you did as I saw your new blog which gives positive feelings and encourages me in my future steps. Thanks for uploading this detailed post. This blog is easy to capture subscribers and attract the reader. I am feeling proud to be your subscriber; your post is so amazing. Keep it up.

  • towing

    Great post! Thanks for this information.

  • david rubulotta biography

    It is very easy to understand. I am really inspired and want to appreciate your efforts. I found a huge content in this Blog which is very attractive and new for me as a regular reader. I loved it. Moreover, I liked the tips that you have shared in it. Please come up with new and exciting ideas as well as I can’t wait to read more exciting ideas from you.

  • janice

    I’m here mostly for the powerful boomer energy

  • www.klamathlandscapepros.com

    So informative things are provided here,I really happy to read this post,I was just imagine about it and you provided me the correct information

  • doula

    I think I need more information

  • InteriorHomesIdeas

    This article talks about interior design ideas for homes. It gives a brief outline on how bachelors may differ from married couples while decorating. It also sheds light on how a space can be utilized efficiently.