I tried this:
- command: ./configure chdir=/src/package/ - command: /usr/bin/make chdir=/src/package/ - command: /usr/bin/make install chdir=/src/package/ which works, but I was hoping for something neater.
So I tried this:
from: which give me back "no such file or directory"
- command: ./configure;/usr/bin/make;/usr/bin/make install chdir=/src/package/ but I couldn't find the right syntax to put:
- command: "{{ item }}" chdir=/src/package/ with_items: ./configure /usr/bin/make /usr/bin/make install That does not work, saying there is a quote issue.
16 Answers
If a value in YAML begins with a curly brace ({), the YAML parser assumes that it is a dictionary. So, for cases like this where there is a (Jinja2) variable in the value, one of the following two strategies needs to be adopted to avoiding confusing the YAML parser:
Quote the whole command:
- command: "{{ item }} chdir=/src/package/" with_items: - ./configure - /usr/bin/make - /usr/bin/make install or change the order of the arguments:
- command: chdir=/src/package/ {{ item }} with_items: - ./configure - /usr/bin/make - /usr/bin/make install Thanks for @RamondelaFuente alternative suggestion.
4To run multiple shell commands with ansible you can use the shell module with a multi-line string (note the pipe after shell:), as shown in this example:
- name: Build nginx shell: | cd nginx-1.11.13 sudo ./configure sudo make sudo make install 1You can also do like this:
- command: "{{ item }}" args: chdir: "/src/package/" with_items: - "./configure" - "/usr/bin/make" - "/usr/bin/make install" Hope that might help other
Shell works for me.
Simply to say, Shell is the same as you run a shell script.
Notes:
- Make sure use | when running multiple cmds.
- Shell won't return errors if the last cmd is success (just like normal shell)
- Control it with exit 0/1 if you want to stop ansible when error occurs.
The following example shows an error in shell, but it's success at the end of the execution.
- name: test shell with an error become: no shell: | rm -f /test1 # This should be an error. echo "test2" echo "test1" echo "test3" # success This example shows stopinng shell with exit 1 error.
- name: test shell with exit 1 become: no shell: | rm -f /test1 # This should be an error. echo "test2" exit 1 # this stops ansible due to returning an error echo "test1" echo "test3" # success I faced the same issue. In my case, part of my variables were in a dictionary i.e. with_dict variable (looping) and I had to run 3 commands on each item.key. This solution is more relevant where you have to use with_dict dictionary with running multiple commands (without requiring with_items)
Using with_dict and with_items in one task didn't help as it was not resolving the variables.
My task was like:
- name: Make install git source command: "{{ item }}" with_items: - cd {{ tools_dir }}/{{ item.value.artifact_dir }} - make prefix={{ tools_dir }}/{{ item.value.artifact_dir }} all - make prefix={{ tools_dir }}/{{ item.value.artifact_dir }} install with_dict: "{{ git_versions }}" roles/git/defaults/main.yml was:
--- tool: git default_git: git_2_6_3 git_versions: git_2_6_3: git_tar_name: git-2.6.3.tar.gz git_tar_dir: git-2.6.3 git_tar_url: The above resulted in an error similar to the following for each {{ item }} (for 3 commands as mentioned above). As you see, the values of tools_dir is not populated (tools_dir is a variable which is defined in a common role's defaults/main.yml and also item.value.git_tar_dir value was not populated/resolved).
failed: [server01.poc.jenkins] => (item=cd {# tools_dir #}/{# item.value.git_tar_dir #}) => {"cmd": "cd '{#' tools_dir '#}/{#' item.value.git_tar_dir '#}'", "failed": true, "item": "cd {# tools_dir #}/{# item.value.git_tar_dir #}", "rc": 2} msg: [Errno 2] No such file or directory Solution was easy. Instead of using "COMMAND" module in Ansible, I used "Shell" module and created a a variable in roles/git/defaults/main.yml
So, now roles/git/defaults/main.yml looks like:
--- tool: git default_git: git_2_6_3 git_versions: git_2_6_3: git_tar_name: git-2.6.3.tar.gz git_tar_dir: git-2.6.3 git_tar_url: #git_pre_requisites_install_cmds: "cd {{ tools_dir }}/{{ item.value.git_tar_dir }} && make prefix={{ tools_dir }}/{{ item.value.git_tar_dir }} all && make prefix={{ tools_dir }}/{{ item.value.git_tar_dir }} install" #or use this if you want git installation to work in ~/tools/git-x.x.x git_pre_requisites_install_cmds: "cd {{ tools_dir }}/{{ item.value.git_tar_dir }} && make prefix=`pwd` all && make prefix=`pwd` install" #or use this if you want git installation to use the default prefix during make #git_pre_requisites_install_cmds: "cd {{ tools_dir }}/{{ item.value.git_tar_dir }} && make all && make install" and the task roles/git/tasks/main.yml looks like:
- name: Make install from git source shell: "{{ git_pre_requisites_install_cmds }}" become_user: "{{ build_user }}" with_dict: "{{ git_versions }}" tags: - koba This time, the values got successfully substituted as the module was "SHELL" and ansible output echoed the correct values. This didn't require with_items: loop.
"cmd": "cd ~/tools/git-2.6.3 && make prefix=/home/giga/tools/git-2.6.3 all && make prefix=/home/giga/tools/git-2.6.3 install", Here is worker like this. \o/
- name: "Exec items" shell: "{{ item }}" with_items: - echo "hello" - echo "hello2"