how to install the script interactive via ansible playbook - shell

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.

Related

Ansible playbook complains about quotes

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!

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 }}'

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.

Setting an environment variable in Ansible from a command output of bash command

I would like to set output of a shell command as an environment variable in Ansible.
I did the following to achieve it:
- name: Copy content of config.json into variable
shell: /bin/bash -l -c "cat /storage/config.json"
register: copy_config
tags: something
- name: set config
shell: "echo $TEMP_CONFIG"
environment:
TEMP_CONFIG: "{{copy_config}}"
tags: something
But somehow after the ansible run, when I do run the following command:
echo ${TEMP_CONFIG}
in my terminal it gives an empty result.
Any help would be appreciated.
There are at least two problems:
You should pass copy_config.stdout as a variable
- name: set config
shell: "echo $TEMP_CONFIG"
environment:
TEMP_CONFIG: "{{copy_config.stdout}}"
tags: something
You need to register the results of the above task and then again print the stdout, so:
- name: set config
shell: "echo $TEMP_CONFIG"
environment:
TEMP_CONFIG: "{{copy_config.stdout}}"
tags: something
register: shell_echo
- debug:
var: shell_echo.stdout
You never will be able to pass the variable to a non-related process this way. So unless you registered the results in an rc-file (like ~/.bash_profile which is sourced on interactive login if you use Bash) no other shell process would be able to see the value of TEMP_CONFIG. This is how system works.

How to process output from Ansible using local script

I want to run some command that return some data and process these data somehow with a script that is located on ansible server. How could I do that?
For example:
I want to run
ansible all -a "cat /etc/redhat-release"
Then I want to call script called version_parser.py (located on local ansible server, not host where ansible is executing the command) with parameters name_of_server and pipe the output of this call as input.
So that in reality I get something similar like
ssh server1 "cat /etc/redhat-release" | version_parser.py server1
ssh server2 "cat /etc/redhat-release" | version_parser.py server2
...
What is most easy approach to do something like this?
You could run the remote command and store the result in a variable. Next you can run a local_action and execute your local script with the stored variable:
---
- name: Run remote command
command: "bash -c 'ls -l /etc/init.d/a* | grep -c app'"
register: store
- name: Run result against local script
local_action: "shell echo '{{ store.stdout }}' | /path/to/local/parser.py {{ inventory_hostname }}"

Resources