DevOps Classroom Series – 05/Aug/2020

Ansible lamp stack contd..

  • Lamp stack playbook for yaml
---
- name: 'Install and configure lamp'
  hosts: ubuntu
  become: yes
  tasks:
    - name: install apache2 and update ubuntu package definitions
      apt:
        name: apache2
        update_cache: yes
        state: present
    - name: enable and start apache2
      service:
        name: apache2
        enabled: yes
        state: started
    - name: install php
      apt:
        name: php
        state: present
    - name: install libapache2-mod-php
      apt:
        name: libapache2-mod-php
        state: present
    - name: install php-mysql
      apt:
        name: php-mysql
        state: present
    - name: install php-cli
      apt:
        name: php-cli
        state: present
    - name: restart apache
      service:
        name: apache2
        state: restarted
  • Lamp stack playbook for centos
---
- name: install lamp stack on Centos
  become: yes
  hosts: centos
  tasks:
    - name: install apache
      yum:
        name: httpd
        state: present
    - name: start and enable apache
      service:
        name: httpd
        enabled: yes
        state: started
    - name: install php
      yum:
        name: php
        state: present
    - name: install php-mysql
      yum:
        name: php-mysql
        state: present
    - name: install php-fpm
      yum:
        name: php-fpm
        state: present
    - name: restart apache
      service:
        name: httpd
        state: restarted

  • For installing php modules we have used the same task with different values. consider the below statement
# repeating statements
print(1)
print(2)
print(3)
print(4)

# using loops
for index in range(1,4):
    print(index)
  • Now we need to find out if the loops are supported by ansible and if yes how? Refer Here for ansible documentation
- name: add several users
  user:
    name: "{{ item }}"
    state: present
    groups: "wheel"
  loop:
     - testuser1
     - testuser2

  • The above example is equivalent to
- name: add testuser1
  user:
    name: testuser1
    state: present
    group: wheel
- name: add testuser2
  user:
    name: testuser2
    state: present
    group: wheel

  • Consider the following lines in centos yaml
- name: install php
    yum:
    name: php
    state: present
- name: install php-mysql
    yum:
    name: php-mysql
    state: present
- name: install php-fpm
    yum:
    name: php-fpm
    state: present
  • These can be replaced with
- name: install php packages
  yum:
    name: "{{ item }}"
    state: present
  loop:
    - php
    - php-mysql
    - php-fpm

  • If the similar concept is applied to ubuntu.yaml
- name: install php packages
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - php
    - libapache2-mod-php
    - php-mysql
    - php-cli


  • By adopting above changes our lamp_centos.yaml will be
---
- name: install lamp stack on Centos
  become: yes
  hosts: centos
  tasks:
    - name: install apache
      yum:
        name: httpd
        state: present
    - name: start and enable apache
      service:
        name: httpd
        enabled: yes
        state: started
    - name: install php packages
      yum:
        name: "{{ item }}"
        state: present
      loop:
        - php
        - php-mysql
        - php-fpm
    - name: restart apache
      service:
        name: httpd
        state: restarted

  • lamp_ubuntu.yaml will be looking as shown below
---
- name: 'Install and configure lamp'
  hosts: ubuntu
  become: yes
  tasks:
    - name: install apache2 and update ubuntu package definitions
      apt:
        name: apache2
        update_cache: yes
        state: present
    - name: enable and start apache2
      service:
        name: apache2
        enabled: yes
        state: started
    - name: install php packages
      apt:
        name: "{{ item }}"
        state: present
      loop:
        - php
        - libapache2-mod-php
        - php-mysql
        - php-cli
    - name: restart apache
      service:
        name: apache2
        state: restarted
  • Now execute these playbooks to verify if they are working or not Preview Preview
  • Do i really need two files, cant i write something like
if node is centos
  execute the centos tasks
else if node is ubuntu 
  execute the ubuntu tasks
  • How to find if the node is ubuntu or centos?
  • Ansible has concept of gathering a facts. Facts are information about nodes. facts can be collected by using a module called as setup. Refer Here
  • Execute the following commands
ansible -i hosts -m setup centos
ansible -i hosts -m setup ubuntu
  • Lets evaluate playbook vs adhoc command
- name: testing
  setup:
    filter: "*distribution*"

ansible -m setup -a "filter=*distribution*" all

Preview

  • So now we have some thing to verify or use as condition in playbook. For centos machine the value of ansible_distribution is "Centos" and for ubuntu node the value is "Ubuntu"
if ansible_distribution == "Centos"
   run centos tasks
else if ansible_distribution == "Ubuntu"
   run ubuntu tasks
  • For ansible conditionals refer here
  • IF the fact name is ansible_something this can be used in playbook as ansible_facts[‘something’]. our key is ansible_distribution so we will be using ansible_facts[‘distribution’]
- name: "shut down Debian flavored systems"
  command: /sbin/shutdown -t now
  when: ansible_facts['os_family'] == "Debian"
  • Our resulting playbook with combined yaml files will be
---
- name: install apache
  hosts: all
  become: yes
  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: present
      when: ansible_facts['distribution'] == "CentOS"
    - name: start and enable httpd
      service:
        name: httpd
        enabled: yes
        state: started
      when: ansible_facts['distribution'] == "CentOS"
    - name: install php packages httpd
      yum:
        name: "{{ item }}"
        state: present
      loop:
        - php
        - php-mysql
        - php-fpm
      when: ansible_facts['distribution'] == "CentOS"
    - name: restart httpd
      service:
        name: httpd
        state: restarted
      when: ansible_facts['distribution'] == "CentOS"
    - name: install apache2 and update ubuntu package definitions
      apt:
        name: apache2
        update_cache: yes
        state: present
      when: ansible_facts['distribution'] == "Ubuntu"
    - name: enable and start apache2
      service:
        name: apache2
        enabled: yes
        state: started
      when: ansible_facts['distribution'] == "Ubuntu"
    - name: install php packages
      apt:
        name: "{{ item }}"
        state: present
      loop:
        - php
        - libapache2-mod-php
        - php-mysql
        - php-cli
      when: ansible_facts['distribution'] == "Ubuntu"
    - name: restart apache
      service:
        name: apache2
        state: restarted
      when: ansible_facts['distribution'] == "Ubuntu"
  • Now lets execute the playbook
ansible-playbook -i hosts lamp.yaml

Preview

  • In ansible there is a generic module called as package.
  • This module when executed on centos will execute yum & when executed on ubuntu machines will execute apt-get, so shall we use this module
---
- name: install apache
  hosts: all
  become: yes
  tasks:
    - name: install httpd
      package:
        name: httpd
        state: present
      when: ansible_facts['distribution'] == "CentOS"
    - name: start and enable httpd
      service:
        name: httpd
        enabled: yes
        state: started
      when: ansible_facts['distribution'] == "CentOS"
    - name: install php packages httpd
      package:
        name: "{{ item }}"
        state: present
      loop:
        - php
        - php-mysql
        - php-fpm
      when: ansible_facts['distribution'] == "CentOS"
    - name: restart httpd
      service:
        name: httpd
        state: restarted
      when: ansible_facts['distribution'] == "CentOS"
    - name: update Ubuntu packages
      apt:
        update_cache: yes
      when: ansible_facts['distribution'] == "Ubuntu"
    - name: install apache2 
      package:
        name: apache2
        state: present
      when: ansible_facts['distribution'] == "Ubuntu"
    - name: enable and start apache2
      service:
        name: apache2
        enabled: yes
        state: started
      when: ansible_facts['distribution'] == "Ubuntu"
    - name: install php packages
      package:
        name: "{{ item }}"
        state: present
      loop:
        - php
        - libapache2-mod-php
        - php-mysql
        - php-cli
      when: ansible_facts['distribution'] == "Ubuntu"
    - name: restart apache
      service:
        name: apache2
        state: restarted
      when: ansible_facts['distribution'] == "Ubuntu"
  • Now executing this will get the same results Preview
  • But in our playbook we use different package task for ubuntu and centos. Cant we use one package task rather than two package tasks?. What is difference in
- 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"

  • Lets compare the above statements to
if machine is ubuntu
    print("ubuntu")
else if machine is centos
    print("centos")

or 
def print_message(message):
   print(message)
  • To achieve this we need to use variable message. So lets see if ansible supports variables. Refer Here

Summary

  • Today we have introduced
    • Looping statements using loop
    • conditional statements using when
    • information about nodes using facts and setup module
    • We have discussed about generic os packager module package

Leave a Reply

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

Please turn AdBlock off
Floating Social Media Icons by Acurax Wordpress Designers

Discover more from Direct DevOps from Quality Thought

Subscribe now to keep reading and get access to the full archive.

Continue reading

Visit Us On FacebookVisit Us On LinkedinVisit Us On Youtube