Ansible playbook complains about quotes - ansible

I'm using Ubuntu 16 with Ansible 2.2.1.0.
I am trying to install docker-compose with the following playbook:
- name: Install Docker Compose.
shell: "curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose"
file:
dest=/usr/local/bin/docker-compose mode=x
src=/usr/local/bin/docker-compose dest=/usr/bin/docker-compose state=link
I get this error:
- name: Install Docker Compose.
shell: "curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose"
^ here
This one looks easy to fix. It seems that there is a value started
with a quote, and the YAML parser is expecting to see the line ended
with the same kind of quote. For instance:
when: "ok" in result.stdout
Could be written as:
when: '"ok" in result.stdout'
What is the problem? I have starting and ending quotes.

shell module hasn't file parameter and shell and name should be on same column that why you got the error and also use a double quote for URL and not full shell command:
- name: Install Docker Compose.
shell: curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose"
You can use the get_url module to download the file to the destination and set permission. And I highly recommend using Ansible role that presented by contributors on the ansible galaxy and not to reinvited wheels!

Related

how to install the script interactive via ansible playbook

I can run the script with the command line argument on the linux server it works fine.
for e.g.: ./install.sh -n -I <IP address of the server>
The above command is able to install the script on the server.
When I am trying to do via ansible (version 2.5) playbook using the shell module it gives me an argument error.
- name: Running the script
shell: yes | ./fullinstall
Expect modules has been tried.
--my-arg1=IP address
- shell: "./install.sh -n -I"
args:
chdir: somedir/
creates: somelog.txt
You can look here for examples.
You can also place the install.sh file on the server as a template. Then you can set the variables as desired in Jinja2.
- name: Template install.sh
template:
src: /install.sh.j2
dest: /tmp/install.sh
- shell: "cd /tmp/ ; ./install.sh
Your install.sh.j2 contains:
IP adres: {{ my_ip }}
And set the variable on the command line with:
ansible-playbook -e my_ip="192.168.0.1"
Use command module
- name: run script
command: /path/to/install.sh -n -I {{ ip_addrress }}
playbook
ansible-playbook -e ip_address="192.168.3.9" play.yml
If you want to interactively wanted to enter the IP address, use prompt module.

Need syntax to work with both Ansible shell & command module

The below syntax works fine.
---
- hosts: all
tasks:
- name: run this command and ignore the result
shell: echo "The server is UP since " `uptime`
However when i change shell module to command module I was expecting this to still work.
command: echo "The server is UP since " `uptime`
But it does not print the uptime value with the command module.
Can I not have the same syntax to work with both the shell as well as the command module ?
Can I not have the same syntax to work with both the shell as well as the command module ?
Yes, of course, by just manually doing the job that shell: is going to do and wrapping the string in sh -c
- set_fact:
the_command: sh -c 'echo "The server is UP since `uptime`"'
- command: '{{ the_command }}'
- shell: '{{ the_command }}'

how to start the service in target server using ansible playbook

I'm trying to run the following ansible playbook to start the "nexus" service on remote server at path "nexux/bin" it gets failed :
- hosts: nexus
become: yes
become_user: nexus
become_method: sudo
tasks:
- name: changing dir and starting nexus service
shell:
chdir: nexux/bin
executable: ./nexus start
Can someone troubleshoot here to deduce the root cause ?
As the ansible output very clearly told you, in that syntax you did not provide a command. The executable: is designed to be the shell executable, not the "run this thing" argument. It is very clear in the examples section of the fine manual
- shell: cd /opt/nexus/bin && ./nexus start
If you want to use the chdir: option, you must put it under a sibling yaml key to the shell:, like so:
- shell: echo hello world
args:
chdir: /opt/nexus/bin
# I'm omitting the "executable:" key here, because you for sure
# do not want to do that, but if you did, then fine, put it here
Having said all of that, as the docs also indicate, what you really want is to use command: because you are not making use of any special shell characters (redirects, pipes, && phrases, etc), so:
- command: ./nexus start
args:
chdir: /opt/nexus/bin
Try use the shell module, i also recommend to run with nohup and send the output to a file
- shell: |
cd /opt/nexus/bin
nohup ./nexus start > /tmp/nexus.log 2>&1 &

Using ssh-keyscan in shell module does not produce any output in Ansible

I'm trying to follow this solution to add use the shell module and ssh-keyscan to add a key to my known_hosts file of a newly created EC2 instance.
After trying to do this multiple ways as listed on that question I eventually ran just the ssh-keyscan command using the shell module without the append. I am getting no output from this task:
- name: accept new ssh fingerprints
shell: ssh-keyscan -H {{ item.public_ip }}
args:
executable: /bin/bash
with_items: "{{ ec2.instances }}"
register: keyscan
- debug: var=keyscan
Debug here shows nothing in stdout and stdout_lines and nothing in stderr and stderr_lines
Note: I tried running this with the bash as the executable shown after reading that the shell module defaults to /bin/sh which is the dash shell on my Linux Mint VirtualBox. But it's the same regardless.
I have tested the shell command with the following task and I see the proper output in stdout and stdout_lines:
- name: test the shell
shell: echo hello
args:
executable: /bin/bash
register: hello
- debug: var=hello
What is going on here? Running ssh-keyscan in a terminal (not through Ansible) works as expected.
EDIT: Looking at the raw_params output from debug shows ssh-keyscan -H x.x.x.x and copying and pasting this into the terminal works as expected.
The answer is that it doesn't work the first time. While researching another method I stumbled across the retries keyword in ansible that allows a retry of whatever command. I tried this and on attempt number 2 in the retry loop it is working.

shell module: Bash <(process substitution) with ansible

I want to run a command:
- name: install pip
shell: "python <(curl https://bootstrap.pypa.io/get-pip.py)"
But achieve an error
failed: [default] => {"changed": true, "cmd": "python <(curl https://bootstrap.pypa.io/get-pip.py)", "delta": "0:00:00.002073", "end": "2014-12-03 15:52:01.780837", "rc": 2, "start": "2014-12-03 15:52:01.778764", "warnings": []}
stderr: /bin/sh: 1: Syntax error: "(" unexpected
I tried to change it to something like:
python <$(curl https://bootstrap.pypa.io/get-pip.py)
but it doesn't work. Any thoughts?
NB: this question about using < operator in shell module and I know that better to use apt for install something
Use command module if you actually do not need shell.
Also you will be better off using get_url module for downloading the file instead of relying on curl being installed on remote server.
Recent versions of Ansible will display a warning when you try to use curl instead of get_url module also:
"warnings": ["Consider using get_url module rather than running curl"]
Here is how I would do this:
- name: Download pip installer
get_url:
url=https://bootstrap.pypa.io/get-pip.py
dest=/tmp/get-pip.py
mode=0440
- name: Install pip
command: /usr/bin/python /tmp/get-pip.py
For extra options to get_url module visit: http://docs.ansible.com/get_url_module.html
EDIT: though this answers this the question I think mgsk's answer is a better answer since I agree that it's not the right way to go about it with Ansible.
This should fix your issue:
- name: install pip
shell: "python <(curl https://bootstrap.pypa.io/get-pip.py)" executable=/bin/bash
If you are wondering the difference between these two commands:
python <(curl https://bootstrap.pypa.io/get-pip.py)
python <$(curl https://bootstrap.pypa.io/get-pip.py)
The first one uses process substitution which is a bash feature which is why you cannot use it with /bin/sh as your shell. What it's doing is taking the output of the curl command (which is a python script), writing it to a temporary file and using that file as an argument to python which takes a python script as its first argument.
The second one is an ambiguous redirect because the python script that is generated from the curl is not a file
- name: configure zookeeper /etc/zookeeper/conf/zoo.cfg
shell: "{{ item }}"
with_items:
if [ -f /etc/zookeeper/conf/zoo_cfg.org ] ;
then cp /etc/zookeeper/conf/zoo_cfg.org /etc/zookeeper/conf/zoo.cfg ;
else cp /etc/zookeeper/conf/zoo.cfg /etc/zookeeper/conf/zoo_cfg.org;
fi;
cat /vagrant/zoo.cfg.j2 >> /etc/zookeeper/conf/zoo.cfg;

Resources