`Ansible-playbook` command fails when run from a non-root user - linux

I am trying to run an ansible-playbook from the cloud-user(non-root) user on the RHEL machine. The playbook requires sudo access, for which I have used the below command -
ansible-playbook -i inventory -e #install_vars.yaml playbooks/install.yaml --become-method=sudo --become
On using the become it has solved the issues encountered earlier of the package installations.
However, I get the following error:
fatal: [ash-test-bb22-bastion-0]: FAILED! => {"changed": true, "cmd": "openshift-install create manifests --log-level info", "delta": "0:00:00.002662", "end": "2022-01-20 04:36:30.224594", "msg": "non-zero return code", "rc": 127, "start": "2022-01-20 04:36:30.221932", "stderr": "/bin/sh: openshift-install: command not found", "stderr_lines": ["/bin/sh: openshift-install: command not found"], "stdout": "", "stdout_lines": []}
openshift-install executable is available under the /usr/local/bin directory and works fine when the user is root.
PATH also has it defined.
PATH=/home/cloud-user/.local/bin:/home/cloud-user/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
Am I doing anything wrong? Can anybody tell me the exact command for the ansible-playbook for the above scenario?

As suggested by #Zeitounator, I modified the /etc/sudoers file and updated the $PATH variable which solved the above issue.

Related

Ansible service module returns service status as stopped when the service is actually running

Trying to stop a service (dse datastax enterprise) using ansible 2.7
- name: Stop service dse, if started
service:
name: dse
state: stopped
What I think ansible is saying is, I'm not doing anything because this service is already stopped. Part of the verbose output:
ok: [myhostname.domain.com] => {
"changed": false,
"invocation": {
"module_args": {
"daemon_reload": false,
"enabled": null,
"force": null,
"masked": null,
"name": "dse",
"no_block": false,
"scope": null,
"state": "stopped",
"user": null
}
},
"name": "dse",
"state": "stopped",
When I check the service on the remote host this is what I see
[user#remotehost ~]$ service dse status
dse is running
So what am I missing here?
FYI it's recommended doing a sudo service dse stop for this service, I don't know if lack of the sudo will make such a difference.
My understanding of this is since I do not have an unrestricted sudo and I do not have the ability to execute in /bin/sh thus it is failing.
The same command works when directly run on the server, and that is because
Ansible sends Python code to be executed on the targeted servers. Since Ansible is running Python code and generally not executing system commands directly, you can't limit system commands with sudo and expect them to work with Ansible.
More: https://gist.github.com/nanobeep/3b3d614a709086ff832a
Not sure everyone has this luxury but in my case modifying the sudoers file
from
TheGroupNameImPartOf ALL= ALL, !SU, !SHELLS
to
TheGroupNameImPartOf ALL= ALL
Did the magic!

Ansible - how to run Java jar with parameters?

I have a problem with ansible playbook. I am trying to run a Java jar as a command. Whenever I run this directly on the virtual machine - it works all the time:
java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir
important information: the installation HAS to be run from user vf5511, and his home folder is /opt/installPath/vf5511
But when trying to write a playbook and run it - it gets all wrong.
This is the playbook:
---
- hosts: webmwc10
become: yes
become_user: wm5511
become_method: sudo
tasks:
- name: installing server
shell: java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir
When I run the playbook, I get an error:
"rc": 127,
"start": "2017-06-02 09:21:31.931049",
"stderr": "/bin/sh: java: command not found",
"stderr_lines": [
"/bin/sh: java: command not found"
],
"stdout": "",
"stdout_lines": []
Java not found? I don't understand this. Java is installed and working properly!
Can anyone help me with this?
Run below commands on your target server to rule out Java issues
which java
java -version
Upon successful results add quotes to your shell command like below and run the playbook again.
shell: "java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir"
You should add your java address before "java". This problem may be occurs when using ssh too. For example:
shell: /your_java_address_in_target_server/java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir
#1. make sure you "become_user" who has access to java
#2. In the .bash_profile, make sure you are setting the Java home path.
#3. Before calling the java command, run .bash_profile to make sure the JDK path is set.
Eg: - name: unjar abc.jar
shell: source ~/.bash_profile; jar xvf abc.jar

ansible 2.3> while check on windows hosts, error: Thread failed to start

I am connecting to windows host via ansible. But I am getting from win_shell an error.
[as_user#tt ansible-winconnect]$ ansible-playbook -i WIN win_conn.yml -t echo_test --ask-pass -vvvv
fatal: [x.x.x.x]: FAILED! => {
"changed": true,
"cmd": "echo %HOMEDIR% > print.txt",
"delta": "0:00:00.287028",
"end": "2017-05-25 11:38:05.603907",
"failed": true,
"rc": 1,
"start": "2017-05-25 11:38:05.316878",
"stderr": "Thread failed to start.\r\n",
"stderr_lines": [
"Thread failed to start."
],
"stdout": "",
"stdout_lines": []
}
[as_user#tt ansible-winconnect]$ cat win-conn/tasks/main.yml
---
- name: Print Home Dir in a file
win_shell: echo %HOMEDIR% > print.txt
tags: echo_test
Assuming you have powershell 3+ and you followed the Ansible docs you very well maybe be running into an out of memory issue. According to Microsoft
The issue occurs because the Windows Remote Management (WinRM) service does not use the customized value of the MaxMemoryPerShellMB quota. Instead, the WinRM service uses the default value, which is 150 MB.
The shell created by WinRM might not have enough memory in order to run the powershell that Ansible is trying to run via WinRM.
Try using the following hotfix from Microsoft https://support.microsoft.com/en-us/help/2842230/out-of-memory-error-on-a-computer-that-has-a-customized-maxmemorypersh
Do you know which version of powershell your host machine is using? Try upgrading to version 4 or above and see if that fixes the error. Or you could also try running that command with the win_command or raw ansible modules.

Ansible fails to pass parameters when executing a .run file

I am trying to use Ansible to install a .run file (created using Makeself 2.1.5) using the following task in a playbook:
- name: Install Program
command: /home/user/folder/program.run -- /S /D=/home/user/folder/destination/
Here, /S is a switch to run a silent installation and the parameter /D sets the destination for the installation. Running this command in the console succeeds.
Ansible claims to run the task without error:
changed: [127.0.0.1] => {
"changed": true,
"cmd": [
"/home/user/folder/program.run",
"--",
"/S",
"/D=/home/user/folder/destination/"
],
"delta": "0:00:00.065261",
"end": "2017-01-06 09:08:43.114265",
"invocation": {
"module_args": {
"_raw_params": "/home/user/folder/program.run -- /S /D=/home/user/folder/destination/",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
},
"module_name": "command"
},
"rc": 0,
"start": "2017-01-06 09:08:43.049004",
"stderr": "",
"stdout": "",
"stdout_lines": [],
"warnings" : []
So somehow the additional parameters cause the execution to fail without Ansible noticing. I've tried using the shell command and various ways of quoting my command, but to no avail.
If I do not pass parameters to the .run file, that is use command: /home/user/folder/program.run, an installation prompt is opened asking for user input, which defeats the purpose of Ansible.
Does anybody have a solution for this? A possible workaround might be to use the expect module, but I would prefer to be able to use the command line arguments, as this is not the only file I would like to install.
I am using Ansible 2.2.0.0 on Ubuntu 16.04.1 LTS.
EDIT:
Following techraf's advice, I found a simple solution using the shell module. Using shell: konsole -e /home/user/folder/program.run /S /D=/home/user/folder/destination/ caused the installation to complete correctly. It is also possible to put the command in a script file and run it using the script module.
Try using the shell module instead of command:
- name: Install Program
shell: /home/user/folder/program.run -- /S /D=/home/user/folder/destination/
You are using -- in the command execution, which actually prevents shell form parsing the arguments that follow. It's a shell built-in, not a parameter of the command.
Can't test it now (and frankly showing without the real program you run it's impossible), but I bet it should work.
If the above won't work, you'd probably have to put this line in a script and run it with the script module.

How to run supervisor with Ansible?

I've got a server on which Supervisord is managing my processes. I normally start supervisord with the following command:
sudo /var/www/imd/venv/bin/supervisord -c /var/www/imd/deploy/supervisord.conf
I'm now trying to set things up with Ansible, but I'm unsure of how I should start Ansible. I can of course do it using something like:
- name: run supervisord
command: "/var/www/imd/venv/bin/supervisord -c /var/www/imd/deploy/supervisord.conf"
This works, but only the first time that you run it. Second time you run the same script supervisord is of course already running, which causes the following error:
TASK [run supervisord]
******************************************************* fatal: [ansible-test1]: FAILED! => {"changed": true, "cmd":
["/var/www/imd/venv/bin/supervisord", "-c",
"/var/www/imd/deploy/supervisord.conf"], "delta": "0:00:00.111700",
"end": "2016-06-03 11:57:38.605804", "failed": true, "rc": 2, "start":
"2016-06-03 11:57:38.494104", "stderr": "Error: Another program is
already listening on a port that one of our HTTP servers is configured
to use. Shut this program down first before starting
supervisord.\nFor help, use /var/www/imd/venv/bin/supervisord -h",
"stdout": "", "stdout_lines": [], "warnings": []}
Does anybody know how I can correctly run supervisord with Ansible? All tips are welcome!
[EDIT]
Because the solution in the answer by mbarthelemy doesn't work for socket files I now managed to get it working with the following:
- name: run supervisord
shell: if [ ! -S /var/run/supervisor.sock ]; then sudo /var/www/imd/venv/bin/supervisord -c /var/www/imd/deploy/supervisord.conf; fi
This of course is not very "ansibleish". If anybody has a real Ansible-based solution that would still be really welcome.
You can use supervisor module
- supervisorctl:
name: my_app
state: restarted
config: /var/opt/my_project/supervisord.conf
or
- name: Restart my_app
supervisorctl:
name: my_app
state: restarted
config: /var/opt/my_project/supervisord.conf
full documentation on https://docs.ansible.com/ansible/2.7/modules/supervisorctl_module.html#examples
Your situation is specific since you don't seem to use a regular Supervisor installed as a normal system package ; in that case you would start/stop/restart it like any other regular system service, using Ansible's service module.
By default, upon starting Supervisor creates a socket to listen for administrations commands from supervisorctl. When it stops it it supposed to remove it.
Try to find where this socket is created in your specific setup (default would be /var/run/supervisor.sock).
Then, let the Ansible command module know that if the Suopervisord process is already running, the socket exists, using the creates option (documentation). This way it won't try to run the command if it's already running:
- name: run supervisord
command: "./venv/bin/supervisord -c ./deploy/supervisord.conf"
args:
chdir=/var/www/imd
creates=/var/run/supervisor.sock
Edit : while this would be the right answer if /var/run/supervisor.sock were a file, it won't work because it's a socket, and Ansible's create parameter won't work.
The most Ansible-ish solution I can think of is using an external Ansible module like one of these, to check if you process already exists (test_process) or is already listening (test_tcp)

Resources