DevOps Classroom Series – 06/Aug/2020

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 Preview
  • 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 Preview
  • 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

Preview

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

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About learningthoughtsadmin