This question already has answers here:
How to run tomcat catalina script on Ansible
(2 answers)
Closed 5 years ago.
I've been working on ansible playbook to download and start tomcat in a host.
This is my inventory host file:
[group1]
machine1 ansible_host=10.40.0.168
I have group1.yml file in my group_vars:
---
ansible_ssh_user: user
ansible_ssh_pass: pass
ansible_sudo_pass: passp
My playbook is:
---
- hosts: group1
sudo: yes
tasks:
- name: Update all packages to the latest version
apt:
upgrade: dist
- name: Download tomcat
get_url: url=http://mirrors.up.pt/pub/apache/tomcat/tomcat-9/v9.0.1/bin/apache-tomcat-9.0.1-fulldocs.tar.gz dest=/opt/apache-tomcat-9.0.1.tar.gz
- name: Unarchive a file that is already on the remote machine
unarchive:
src: /opt/apache-tomcat-9.0.1.tar.gz
dest: /opt/
remote_src: yes
- name: Run Tomcat
shell: ./startup.sh
args:
chdir: /opt/apache-tomcat-9.0.1/bin
I try to run ./startup.sh in /opt/apache-tomcat-9.0.1/bin folder to start tomcat.
I run the following command:
ansible-playbook playbookname.yml
If I run ./startup.sh in a host machine it works fine, but when I run it from the control machine I get:
PLAY [group1] **********************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [myname]
TASK [Update all packages to the latest version] ***********************************************************************
ok: [myname]
TASK [Download tomcat] *************************************************************************************************
ok: [myname]
TASK [Unarchive a file that is already on the remote machine] **********************************************************
ok: [myname]
TASK [Run Tomcat] ******************************************************************************************************
changed: [myname]
PLAY RECAP *************************************************************************************************************
myname : ok=5 changed=1 unreachable=0 failed=0
After this I try to open tomcat, but it's not running on the host.
How can I start tomcat from ansible?
You should add it as a service, eg as below:
service file: /etc/systemd/system/tomcat.service (It should be in target destination machine)
File should contain as below, (Adjust to your java environment)
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk/jre
Environment=CATALINA_PID=/opt/tomcat/apache-tomcat-8.0.47/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat/apache-tomcat-8.0.47
Environment=CATALINA_BASE=/opt/tomcat/apache-tomcat-8.0.47
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'
ExecStart=/opt/tomcat/apache-tomcat-8.0.47/bin/startup.sh
ExecStop=/bin/kill -15 $MAINPID
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
Then start the server with below systemd ansible module,
- name: enable tomcat startup
systemd:
name: tomcat
enabled: yes
state: restarted
become: true
You should use system tools for that, like Systemd etc. depending on your OS.
Ansible should only create the service file and start the service. Running the servie is not the job of Ansible.
Possible way to do that: https://www.digitalocean.com/community/tutorials/how-to-install-apache-tomcat-8-on-centos-7#install-tomcat
Related
Question:
This scenario is used to explain the usage of modules in Ansible.
For this you have to stop and start a service named ssh.
Tasks to be done:- Write a task in main.yml file present in fresco_module\tasks folder.
The task is to stop and start the service named ssh using the service module in Ansible.
Note:
Run project install to install ansible.mainplaybook.yml file is provided to ansible-playbook.
Use the localhost for the inventory for ansible-playbook.
My Code:
- hosts: localhost
become: yes
tasks:
- name: Stop and Start ssh
service:
name: ssh
state: "{{ item }}"
with_items:
- stopped
- started
Output:
PLAY [localhost] *******************************************************************************
TASK [Gathering Facts] *************************************************************************
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host localhost should use /usr/bin/python3,
but is using /usr/bin/python for backward compatibility with prior Ansible releases. A future
Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more
information. This feature will be removed in version 2.12. Deprecation warnings can be disabled
by setting deprecation_warnings=False in ansible.cfg.
ok: [localhost]
TASK [Stop and Start ssh] **********************************************************************
changed: [localhost] => (item=stopped)
ok: [localhost] => (item=started)
PLAY RECAP *************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Issue: The service is already running after Ansible stopped it, which looks like sshd was never stopped in the first place.
Command used to check the status: service ssh status. I used this command with state:stopped also but the sshd is still running. I have been facing this issue for so long. I tried with state:restarted also.
Hi Vivek and welcome to the community!
This should be an easy one. You can tell Ansible to restart the service directly without stopping and starting it in two separate steps.
The following code should work:
- hosts: localhost
become: yes
tasks:
- name: Stop and Start ssh
service:
name: ssh
state: restarted
This way Ansible ensures, that the ssh service was stopped an started - in short: restarted. You don't even need the with_items loop.
Ive tried the below and getting the same "sshd running " output , but the issue here i think is they want us to have both stop and start under one task. Also we are not allowed to use the restarted state :/
-
name: "Stop ssh"
service:
name: ssh
state: stopped
-
name: "start ssh"
service:
name: ssh
state: started
---
- hosts: localhost
connection: local
become: true
become_method: sudo
tasks:
- name: stop a service
service:
name: ssh
state: stopped
- name: start a service
service:
name: ssh
state: started
Add become-method sudo and task as stop and start the service.
Even i tried this problem with many other modules, like systemd, still i was not able to stop the service. But using command module, and passing 'sudo service ssh stop', i was able to stop the service. but still not passed the problem.
Even tried felix's answer before, still not able to pass.
And also if anybody can help me with "Ansible Choral | 5 | Ansible Roles problem"
would be great. even in that problem after getting 100% fs score not able to pass.
Just run the playbook for stopping starting ssh service without restart.
or use this
-
name: "Stop ssh"
service:
name: ssh
state: stopped
-
name: "start ssh"
service:
name: ssh
state: started
After running playbook successfully. Just stop the service by
sudo serivce ssh stop and then start the service sudo service ssh start.
then just submit the test. you will pass the handson
Just write below command in your main yaml file. This will first stop the ssh service and then start it again.
- name: Stop service ssh, if started
ansible.builtin.service:
name: ssh
state: stopped
- name: Start service ssh, if not started
ansible.builtin.service:
name: ssh
state: started
On AWS EC2 instances the ssh service is sshd.
- name: restart ssh daemon
hosts: all
remote_user: ec2-user
become: yes
become_method: sudo
tasks:
- name: Stop and Start ssh
service:
name: sshd
state: restarted
In the above YAML, replacing sshd with ssh will fail with "msg": "Could not find the requested service ssh
I am logged in as root#x.x.x.12 with ansible 2.8.3 Rhel 8.
I wish to copy few files to root#x.x.x.13 Rhel 8 and then execute a python script.
I am able to copy the files sucessfully using ansible. I had even copied the keys and now it is ssh-less.
But during execution of script :
'fatal: [web_node1]: FAILED! => {"changed": false, "msg": "Could not find or access '/root/ansible_copy/write_file.py' on the Ansible Controller.\nIf you are using a module and expect the file to exist on the remote, see the remote_src option"}'
Please note that I am a novice to ansible.
I guess there is some permission issues.
Please Help me out if possible.
Thanking in anticipation
**yaml_file**
-
name: Copy_all_ansible_files_to_servers
hosts: copy_Servers
become: true
become_user: root
tasks:
-
name: copy_to_all
copy:
src: /home/testuser/ansible_project/{{item}}
dest: /root/ansible_copy/{{item}}
owner: root
group: root
mode: u=rxw,g=rxw,o=rxw
with_items:
- write_file.py
- sink.txt
- ansible_playbook_task.yaml
- copy_codes_2.yaml
notify :
- Run_date_command
-
name: Run_python_script
script: /root/ansible_copy/write_file.py > /root/ansible_copy/sink.txt
args:
#chdir: '{{ role_path }}'
executable: /usr/bin/python3.6
**inventory_file**
-
web_node1 ansible_host=x.x.x.13
[control]
thisPc ansible_connection=local
#Groups
[copy_Servers]
web_node1
Command: ansible-playbook copy_codes_2.yaml -i inventory.dat =>
PLAY [Copy_all_ansible_files_to_servers] *******************************************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************************************
ok: [web_node1]
TASK [copy_to_all] *****************************************************************************************************************************************************************************************
ok: [web_node1] => (item=write_file.py)
ok: [web_node1] => (item=sink.txt)
ok: [web_node1] => (item=ansible_playbook_task.yaml)
ok: [web_node1] => (item=copy_codes_2.yaml)
TASK [Run_python_script] ***********************************************************************************************************************************************************************************
fatal: [web_node1]: FAILED! => {"changed": false, "msg": "Could not find or access '/root/ansible_copy/write_file.py' on the Ansible Controller.\nIf you are using a module and expect the file to exist on the remote, see the remote_src option"}
PLAY RECAP *************************************************************************************************************************************************************************************************
web_node1 : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
The script command will actually copy the file to the remote server before running it. Thus, when it complains about not being able to find or access the script, it's because it's trying to copy from /root/ansible_copy/write_file.py to the server.
If you don't really need the script to remain on the server after you execute it, you could remove the script from the copy task and change the script task to have the src point at /home/testuser/ansible_project/write_file.py.
Alternatively, instead of using the script command, you can manually run the script after transferring it using:
- name: run the write_file.py after it has already been transferred
command: python3.6 /root/ansible_copy/write_file.py > /root/ansible_copy/sink.txt
(Note: you may need to provide the full path to your python3.6 executable)
I'm trying to write a playbook for a Windows VM that also creates the VM with the os_server module.
I'm starting with a simple win_ping, given the VM is already there:
- name: Create instance
hosts: all
tasks:
- name: Ping machine
win_ping:
running it with ansible-playbook site.yml --inventory=10.204.0.9,
results in:
PLAY [Create instance] ************************************************************************
TASK [Gathering Facts] ************************************************************************
ok: [10.204.0.9]
TASK [Ping machine] ***************************************************************************
ok: [10.204.0.9]
PLAY RECAP ************************************************************************************
10.204.0.9 : ok=2 changed=0 unreachable=0 failed=0
Now I add the os_server task:
- name: Create Windows Instance
connection: local
os_server:
state: present
region_name: "{{ os_region_name }}"
auth: "{{ cloud.auth }}"
name: "windows-{{ inventory_hostname }}"
image: Windows 2012 R2 Datacenter
key_name: vector_ops
flavor: 1C-2GB-50GB
floating_ips:
- "{{ inventory_hostname }}"
- name: Ping machine
win_ping:
I'm setting connection to local as I want this task to be executed from the control machine, in case the VM is not created yet.
When I run this playbook again with ansible-playbook site.yml --inventory=10.204.0.9,, I get:
TASK [Create Windows Instance] ****************************************************************
[WARNING]: FATAL ERROR DURING FILE TRANSFER: Traceback (most recent call last): File
"/usr/lib/python2.7/dist-packages/ansible/plugins/connection/winrm.py", line 276, in
_winrm_exec self._winrm_send_input(self.protocol, self.shell_id, command_id, data,
eof=is_last) File "/usr/lib/python2.7/dist-packages/ansible/plugins/connection/winrm.py",
line 256, in _winrm_send_input protocol.send_message(xmltodict.unparse(rq)) File
"/usr/local/lib/python2.7/dist-packages/winrm/protocol.py", line 207, in send_message
return self.transport.send_message(message) File "/usr/local/lib/python2.7/dist-
packages/winrm/transport.py", line 202, in send_message raise WinRMTransportError('http',
error_message) WinRMTransportError: (u'http', u'Bad HTTP response returned from server. Code
500')
fatal: [10.204.0.9]: FAILED! => {"msg": "winrm send_input failed"}
I'm a bit puzzled why there is an error during a file transfer, so I ran the command with -vvv:
TASK [Create Windows Instance] ****************************************************************
task path: /home/ubuntu/basic-windows-example/trunk/playbooks/site.yml:8
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/cloud/openstack/os_server.py
<10.204.0.9> ESTABLISH WINRM CONNECTION FOR USER: Admin on PORT 5986 TO 10.204.0.9
EXEC (via pipeline wrapper)
And indeed it seems so that Ansible tries to establish a winrm connection, despite connection: local. Removing connection: local from the task brings the same result as above.
I would expect the task to return a simple "ok" since the VM is already there.
What am I missing here?
Update 2018-01-09, 9:45 GMT:
So I tried another experiment: I removed all ansible_* variables from the var file (see below) just to see what Ansible does with the os_server task when no WinRM connection is configured. Running it again with ansible-playbook site.yml --inventory=10.204.0.9, -vvv this time I get for the os_server task:
TASK [Create Windows Instance] ****************************************************************
task path: /home/ubuntu/basic-windows-example/trunk/playbooks/site.yml:9
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/cloud/openstack/os_server.py
<10.204.0.9> ESTABLISH LOCAL CONNECTION FOR USER: ubuntu
<10.204.0.9> EXEC /bin/sh -c 'echo ~ && sleep 0'
<10.204.0.9> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/ubuntu/.ansible/tmp/ansible-tmp-1515490597.4-208015762064624 `" && echo ansible-tmp-1515490597.4-208015762064624="` echo /home/ubuntu/.ansible/tmp/ansible-tmp-1515490597.4-208015762064624 `" ) && sleep 0'
<rest cut off for brevity>
So now a local connection does get established and the os_server task completes successfully. But of course, this is not the answer, because I need the WinRM connection configured for the Windows VM.
Update 2018-01-09, 10:00 GMT:
Following the suggestion to add gather_facts: false to the play and running ansible-playbook site.yml --inventory=10.204.0.9,, I now get:
PLAY [Create instance] ************************************************************************
META: ran handlers
TASK [Create Windows Instance] ****************************************************************
task path: /home/ubuntu/basic-windows-example/trunk/playbooks/site.yml:10
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/cloud/openstack/os_server.py
<10.204.0.9> ESTABLISH WINRM CONNECTION FOR USER: Admin on PORT 5986 TO 10.204.0.9
EXEC (via pipeline wrapper)
[WARNING]: FATAL ERROR DURING FILE TRANSFER: Traceback (most recent call last): File
"/usr/lib/python2.7/dist-packages/ansible/plugins/connection/winrm.py", line 276, in
_winrm_exec self._winrm_send_input(self.protocol, self.shell_id, command_id, data,
eof=is_last) File "/usr/lib/python2.7/dist-packages/ansible/plugins/connection/winrm.py",
line 256, in _winrm_send_input protocol.send_message(xmltodict.unparse(rq)) File
"/usr/local/lib/python2.7/dist-packages/winrm/protocol.py", line 207, in send_message
return self.transport.send_message(message) File "/usr/local/lib/python2.7/dist-
packages/winrm/transport.py", line 202, in send_message raise WinRMTransportError('http',
error_message) WinRMTransportError: (u'http', u'Bad HTTP response returned from server. Code
500')
fatal: [10.204.0.9]: FAILED! => {
"msg": "winrm send_input failed"
}
The error is the same, Ansible still tries to establish a WinRM connection.
Full Playbook (site.yml, added gather_facts: false):
- name: Create instance
hosts: all
gather_facts: false
tasks:
- name: Create Windows Instance
connection: local
os_server:
state: present
region_name: Region1
auth: "{{ cloud.auth }}"
name: "windows-{{ inventory_hostname }}"
image: Windows 2012 R2 Datacenter
key_name: mykey
flavor: 1C-2GB-50GB
floating_ips:
- "{{ inventory_hostname }}"
- name: Ping machine
win_ping:
Vars in group_vars/all (used throughout all examples):
cloud:
auth:
auth_url: https://cloud.internal:5000/v3/
domain_name: Domain_01
password: mypassword
project_name: dev-project
username: apiuser
os_region_name: Fra1
ansible_user: Admin
ansible_port: 5986
ansible_password: myvmpassword
ansible_connection: winrm
ansible_winrm_server_cert_validation: ignore
Version info:
ansible --version
ansible 2.4.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/ubuntu/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.12 (default, Nov 20 2017, 18:23:56) [GCC 5.4.0 20160609]
If I use delegate_to: localhost instead of connection: local for the os_server task, a local connection does get established. delegate_to avoids loading the WinRM connection variables for that connection.
If someone else is facing the same issue with Ansible then check the WinRM memory setting on the host and ensure it has sufficient memory.
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024
I am using below ansible yml file to install python, pip, etc.
roles/python/main.yml:
---
- name: python
apt:
pkg: python
- name: python-pip
apt:
pkg: python-pip
- name: mongopy
pip:
pkg: mongopy
- name: mtools
pip:
pkg: mtools
when I run ansible-playbook on this script, I get below
PLAY [ec2] ***********************************************************************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************************************************************
ok: [xxxxx.ap-southeast-2.compute.amazonaws.com]
PLAY RECAP ***********************************************************************************************************************************************************************************************
xxxxxap-southeast-2.compute.amazonaws.com : ok=1 changed=0 unreachable=0 failed=0
there is no error on them but I checked these apps are not installed on the remote host. What wrong with my yml file? Is there any place I can check what the error is?
below is my playbook:
python.yml:
---
- hosts: ec2
remote_user: ubuntu
roles:
- python
below is the command I run:
ansible-playbook -i hosts python.yml
There are no tasks in your python role. Please have a look at the role structure.
If roles/x/tasks/main.yml exists, tasks listed therein will be added to the play
Tasks file (main.yml) should be placed in the tasks subdirectory of the role, not in the main role's directory.
And this has nothing to do with how you described the problem (installing Python or Pip). Even if you replaced the tasks with a single debug task which displays Hello world by default, it would not run.
I need to set up Apache/mod_wsgi in Centos 6.5 so my main YAML file is as such:
---
- hosts: dev
tasks:
- name: Updates yum installed packages
yum: name=* state=latest
- hosts: dev
roles:
- { role: apache }
This should update all yum-installed packages then execute the apache role.
The apache role is configured to install Apache/mod_wsgi, set Apache to start at boot time and restart it. The following are the contents of roles/apache/tasks/main.yml:
---
- name: Installs httpd and mod_wsgi
yum: name={{ item }} state=latest
with_items:
- httpd
- mod_wsgi
notify:
- enable httpd
- restart httpd
And the handlers in roles/apache/handlers/main.yml:
---
- name: enable httpd
service: name=httpd enabled=yes
- name: restart httpd
service: name=httpd state=restarted
The handlers do not seem to run since the following output is given when I execute the playbook:
PLAY [dev] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [dev.example.com]
TASK: [Updates yum installed packages] ****************************************
ok: [dev.example.com]
PLAY [dev] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [dev.example.com]
TASK: [apache | Installs httpd and mod_wsgi] **********************************
ok: [dev.example.com] => (item=httpd,mod_wsgi)
PLAY RECAP ********************************************************************
dev.example.com : ok=4 changed=0 unreachable=0 failed=0
And when I vagrant ssh into the virtual machine, sudo service httpd status shows httpd is stopped and sudo chkconfig --list shows it has not been enabled to be started by init.
I'm just starting out with Ansible, so is there something obvious I could be missing?
Well, to answer my own question, I realized that there's a subtle point I missed:
http://docs.ansible.com/playbooks_intro.html#handlers-running-operations-on-change
Specifically, the notify signal is produced only if the task introduces a change. So for my use case I think I'll go with enabling and starting Apache in standalone tasks instead of relying on change signal handlers.