Ansible variables adoption to Lamp
- Rather than use when statements separately for centos & ubuntu we would use ansible variables.
- Let’s identify the difference b/w
- name: install httpd
package:
name: httpd
state: present
when: ansible_facts['distribution'] == "CentOS"
- name: install apache2
package:
name: apache2
state: present
when: ansible_facts['distribution'] == "Ubuntu"
- If i have a variable called as package_name & the value of package name for ubuntu is apache2 and for centos is httpd
- name: "Install apache"
package:
name: "{{ package_name }}"
state: present
- So lets define variables in the inventory file
[centos]
172.31.4.122 package_name="httpd" php_packages='["php","php-mysql", "php-fpm"]'
[ubuntu]
172.31.3.192 package_name="apache2" php_packages='["php","libapache2-mod-php","php-mysql","php-cli"]'
- The playbook now looks like
---
- name: install apache
hosts: all
become: yes
tasks:
- name: update Ubuntu packages
apt:
update_cache: yes
when: ansible_facts['distribution'] == "Ubuntu"
- name: install apache
package:
name: "{{ package_name }}"
state: present
- name: start and enable apache
service:
name: "{{ package_name }}"
enabled: yes
state: started
- name: install php packages
package:
name: "{{ item }}"
state: present
loop: "{{ php_packages }}"
- name: restart apache2
service:
name: "{{ package_name }}"
state: restarted
- If you look at service section first problem is we have service copied twice and second one is service needs to be restarted and enabled only as reaction to successful task execution
- Can we visualize this as action => reaction, or Only when action has occurred it will raise notification to restart.
- Without handlers the service restart every time which is unnecessary

- In ansible to handle the above mentioned scenarios we have handlers Refer Here
---
- name: some play
become: yes
tasks:
- name: install package
package:
name: {{some_package }}
state: present
notify:
- enable and start some package
handlers:
- name: enable and start some package
service:
name: {{some_package }}
enabled: yes
state: restarted
- when you execute the above playbook only when ansible installs the package (i.e. when it is execute for the first time) the service will be enabled and restarted, during subsequent runs the service will not be restarted as the package is not installed.
- Now lets apply this to our lamp playbook
---
- name: install apache
hosts: all
become: yes
tasks:
- name: update Ubuntu packages
apt:
update_cache: yes
when: ansible_facts['distribution'] == "Ubuntu"
- name: install apache
package:
name: "{{ package_name }}"
state: present
notify:
- restart and enable apache
- name: install php packages
package:
name: "{{ item }}"
state: present
loop: "{{ php_packages }}"
notify:
- restart and enable apache
handlers:
- name: restart and enable apache
service:
name: "{{ package_name }}"
enabled: yes
state: restarted
- After adopting handler approach, services will be restarted only when the packages are installed

- What will happen if some one executes this playbook on windows node or open suse linux will it work?
- So lets add a bail out approach when user executes this playbook on any other distribution apart from ubuntu or centos
- In ansible we have a module which can show message to the user and stop execution, this module is fail module Refer Here
- After adding a bailout error the playbook looks as shown below
---
- name: install apache
hosts: all
become: yes
tasks:
- name: fail when node is not Ubuntu or Centos
fail:
msg: This playbook works only on CentOS and Ubuntu Nodes
when: ansible_facts['distribution'] != "Ubuntu" and ansible_facts['distribution'] != "CentOS"
- name: update Ubuntu packages
apt:
update_cache: yes
when: ansible_facts['distribution'] == "Ubuntu"
- name: install apache
package:
name: "{{ package_name }}"
state: present
notify:
- restart and enable apache
- name: install php packages
package:
name: "{{ item }}"
state: present
loop: "{{ php_packages }}"
notify:
- restart and enable apache
handlers:
- name: restart and enable apache
service:
name: "{{ package_name }}"
enabled: yes
state: restarted
- Now we need to create php info page with contents in /var/www/info.php
<?php
phpinfo();
?>
- Lets choose copy module Refer Here to copy the file called as info.php from ansible control node to nodes.
- Create a file called as info.php with content
<?php
phpinfo();
?>
- Now use copy module
---
- name: install apache
hosts: all
become: yes
tasks:
- name: fail when node is not Ubuntu or Centos
fail:
msg: This playbook works only on CentOS and Ubuntu Nodes
when: ansible_facts['distribution'] != "Ubuntu" and ansible_facts['distribution'] != "CentOS"
- name: update Ubuntu packages
apt:
update_cache: yes
when: ansible_facts['distribution'] == "Ubuntu"
- name: install apache
package:
name: "{{ package_name }}"
state: present
notify:
- restart and enable apache
- name: install php packages
package:
name: "{{ item }}"
state: present
loop: "{{ php_packages }}"
notify:
- restart and enable apache
- name: copy the phpinfo page
copy:
src: info.php
dest: /var/www/html/info.php
notify:
- restart and enable apache
handlers:
- name: restart and enable apache
service:
name: "{{ package_name }}"
enabled: yes
state: restarted
- Now execute ansible-playbook
ansible-playbook -i hosts lamp.yaml

- Now lets navigate to http://<publicip-centosnode>/info.php

- Now lets navigate to http://<publicip-ubuntunode>/info.php

Exercise:
- Write an ansible playbook to install tomcat8 on ubuntu Refer Here
- Try till step 4 in the following docs for installing nginx Refer Here
