Shell command works manually, not using Ansible - bash

I'm playing with Ansible (still learning), but I encountered a problem I can't think of a solution.
I'm trying to install and launch Tomcat on a remote server using Ansible.
The installation is working, but the last step which is the activation of the Tomcat server is failing.
If I manually launch the startup.sh script (as su -), using the following command : bash /opt/tomcat/startup.sh, I can see the tomcat homepage.
Using the ansible playbook I wrote, even though Ansible doesn't show up any errors, I can't see the tomcat homepage.
Here is the task I'm running :
- name: Launch Tomcat
command: bash /opt/tomcat/startup.sh
become: true
I tried to add become_user: root and become_method: sudo with no success.
I think it may be related to how become: true is handled by ansible but I'm not sure.

Have you also tried using the shell-module instead of the command-module?
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.
(Source: https://blog.confirm.ch/ansible-modules-shell-vs-command/)

There might be a problem with the environment. "sudo su" is different from "su -" where
-, -l, --login Provide an environment similar to what the user would expect had the user logged in directly.
Try shell (because it allows pipes, redirection, logical operations, ...) without become: true
shell: su - && bash /opt/tomcat/startup.sh
Make sure remote_user is the same whom the su - command works fine for.

i had the same problem while working with startup.sh in ansible script.i got to know the tomcat server process got starts but immediately shutdown as well.
so the solution to the problem is running or starting the tomcat server in nohup
thru ansible
Here is the sample script.
cat start.yml
---
- name: Playbook to stop server
#hosts: localhost
hosts: webserver
tasks:
- name: Start the server tomcat from UI
shell:
nohup /home/tomcat/bin/catalina.sh start >> /home/tomcat/somelog

Related

Running terminal command via Ansible playbook

I'm having, what appears to be, a common issue of running shell/terminal commands via an ansible playbook.
If I were to go onto on of my remote machines and type the command on a fresh terminal window, it works, however attempting to do the same via a playbook is having directory issues.
This is essentially the command, but some of it changed a little for privacy, but its essentially an authenticator...
authenticator authenticate user userkeytab
If I try to just run it as shell, I get an error that the authenticator command cant be found in /bin/sh, so I attempted to use chdir to run the command at the default window, (/Users/username).
Here is roughly, the playbook, with one of my failed attempts... I just don’t know what chdir I should be using...
- hosts: all
tasks:
- name: Reauthenticate login
shell: authenticator authenticate user userkeytab
args:
chdir: ~/
ive also tried usr/local/bin.... any thoughts?
can you try with the 'command' module, example below:
- name: Change the working directory to somedir/ and run the command as db_owner if /path/to/database does not exist.
command: /usr/bin/make_database.sh db_user db_name
become: yes
become_user: db_owner
args:
chdir: somedir/
creates: /path/to/database
Resource:
https://docs.ansible.com/ansible/latest/modules/command_module.html

Whats the difference between ansible 'raw', 'shell' and 'command'?

What is the difference between raw, shell and command in the ansible playbook? And when to use which?
command: executes a remote command on the target host, in the same shell of other playbook's tasks.
It can be used for launch scripts (.sh) or for execute simple commands. For example:
- name: Cat a file
command: cat somefile.txt
- name: Execute a script
command: somescript.sh param1 param2
shell: executes a remote command on the target host, opening a new shell (/bin/sh).
It can be used if you want to execute more complex commands, for example, commands concatenated with pipes. For example:
- name: Look for something in a file
shell: cat somefile.txt | grep something
raw: executes low-level commands where the interpreter is missing on the target host, a common use case is for installing python. This module should not be used in all other cases (where command and shell are suggested)
Since I were I stumbling about the same question, I wanted to share my findings here too.
The command and shell module, as well gather_facts (annot.: setup.py) depend on a properly installed Python interpreter on the Remote Node(s). If that requirement isn't fulfilled one may experience errors were it isn't possible to execute
python <ansiblePython.py>
In a Debian 10 (Buster) minimal installation i.e., python3 was installed but the symlink to python missing.
To initialize the system correctly before applying all other roles, I've used an approach with the raw module
ansible/initSrv/main.yml
- hosts: "{{ target_hosts }}"
gather_facts: no # is necessary because setup.py depends on Python too
pre_tasks:
- name: "Make sure remote system is initialized correctly"
raw: 'ln -s /usr/bin/python3 /usr/bin/python'
register: set_symlink
failed_when: set_symlink.rc != 0 and set_symlink.rc != 1
which is doing something like
/bin/sh -c 'ln -s /usr/bin/python3 /usr/bin/python'
on the remote system.
Further Documentation
raw module – Executes a low-down and dirty command
A common case is installing python on a system without python installed by default.
... but not only restricted to that
Playbook Keyword - pre_tasks
A list of tasks to execute before roles.
Set the order of task execution in Ansible

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 &

Can't run sudo command in Ansible playbook

I am writing an Ansible playbook to automate a series of sudo commands on various hosts. When I execute these commands individually in puTTY, I have no permission problems, as I have been granted proper access. However, when I attempt to create a playbook to do the same thing, I am told
user is not allowed to execute ... on host_name
For example, if I do $ sudo ls /root/, I have no problem, and, once I enter my password, can see the contents of /root/
In the case of my Ansible playbook ...
---
- host: servers
tasks:
- name: ls /root/
shell: ls /root/
become: true
become_method: sudo
...I then get the error mentioned above.
Any ideas why this would be the case? It seems to be telling me I don't have permission to run a command that I otherwise could run in an individual puTTY terminal.
[ ] automate a series of sudo commands on various hosts. When I execute these commands individually [ ]
Any ideas why this would be the case?
Sounds like you configured specific commands in the sudoers file (unfortunately you did not provide enough details, fortunately you asked for "ideas" not the real cause).
Ansible shell module does not run the command you specify prepended with sudo - it runs the whole shell session with sudo, so the command doesn't match what you configured in sudoers.
Either allow all commands to be run with elevated privileges for the Ansible user, or use raw module instead of shell.

Ansible Command, Shell modules not executing script

I have a tomcat.sh with its intended purpose to restart (stop and start) the tomcat after it has been deployed onto the remote host.
I noticed that the Shell and Command modules is not executing the .sh file. However, I am able to execute the .sh file manually on the remote host as the the remote user.
The Playbook tasks are listed below:
Shell
- name: ensures tomcat is restarted
shell:
"nohup {{tomcat_dir}}/apache-tomcat-{{tomcat_version}}/tomcat.sh &"
Command
- name: ensures tomcat is restarted test-test
command: ./tomcat.sh
args:
chdir: "{{tomcat_dir}}/apache-tomcat-{{tomcat_version}}"
I was having the same problem. I have my simple script that is supposed to start a java program. shell and command module work very erratically. That is sometimes the java program is started successfully, and sometimes nothing happens. Even though ansible rc status shows as 0 (which is successful exit code ). I even put a echo "Hello" >> output.log as the first line in my script, to check if the script is actually picked for running. But, even that does not get printed.But, no errors whatsoever is printed and ansible module exit status (rc) is 0.Also, be sure to look at the stderr too. Sometimes, even though rc could be 0, but there might be some info in stderr
After lots of hair tearing, I could manage to fix my issue. I was running the java program as "sudo".I removed the sudo out of my script, and put it within playbook as the "become" directive - http://docs.ansible.com/ansible/become.html . This directive is available from ansible 2.0 onwards only, so I had to upgrade my ansible from 1.5 to 2.0. My playbook finally looked like this
- name: Execute run.sh
become: true
script: /home/vagrant/deploy/target/scripts/run.sh
The script looks like this:
nohup java -Djava.net.preferIPv4Stack=true -Xms1048m -Xmx1048m -cp /x/y/z/1.jar com.github.binitabharati.x.Main >> output.log 2>&1 &
Also, notice that I have not used the command or shell module, instead I used script module.
Does the value of {{tomcat_dir}} start with a "/"? If not then it will try to execute the command using the specified path relative to the home dir of whichever user ansible using to ssh in to the remote host.
incidentally, If you installed via package manager, this might be easier?
- name: restart tomcat
become: yes
become_user: sudo
service: name=tomcat state=restarted
More detail on the "service" module here
Of course, the service name may be different, like tomcat6 or tomcat7 or whatever, but you get the gist, I hope.
Lastly, if you installed tomcat via ansible using a role from galaxy or github, your role may have handlers that you could copy to get this done.

Resources