Friday, July 21, 2017

Include tasks and Variables in playbook

Purpose of this playbook is to demonstrate how include tasks defined in a different file.
And how to define variables within the playbook
"include" is the key word to include tasks file
"vars" is the key word to defined variables in the playbook.


YML file to define tasks for playbook.

# copy from here:
# Only the tasks are defined in this file. 
- name: Install Web package
  yum:
    name:
      - "{{ web_package }}"
      - "{{ db_package }}"
    state: latest

- name: Start both DB and Web service
  service:
    name: "{{ item }}"
    state: started
    enabled: yes
  with_items:
    - "{{ web_service }}"
    - "{{ db_service }}"


Playbook to import above task file.
# hosts and tasks are the key words in playbook:  

# copy from here:
---
- name: Install Web and DB package and start services using variables
  hosts: node11
  vars:  # define list of packages
    - web_package: httpd
    - web_service: httpd
    - db_package: mariadb-server
    - db_service: mariadb
  tasks:
  - name: Install requrie packages
    include: envirenment.yml   # Import tasks from above yml file.
    register: output

  - name: Display the output
    debug:
      var: output
...

Custom Facts - Ansible

Default custom fact directory on the target host is - /etc/ansible/facts.d
Custom facts file name extension should be ".fact"
facts file follows INI format.


# Example custom fact file:
[package]
web_package: httpd
db_package: mariadb-server

Playbook to transfer above custom fact file to target/remote host

# copy from here:
---
- name: Custom Facts
  hosts: node11
  vars:
    remote_directory: /etc/ansible/facts.d  ## default directory for Ansible facts
    facts_file: custom.fact  ## fact file must have .fact extention
  tasks:

  - name: Create remote direcotry to trasfer custorm facts file
    file:
      path: "{{ remote_directory }}"
      state: directory
      recurse: yes

  - name: copy custome fact file to remote server
    copy:
      src: "{{ facts_file }}"
      dest: "{{ remote_directory }}"
...


Playbook to use above custom facts

# Copy from here
---
- name: Use custom defined facts
  hosts: node11
  tasks:
  - name: Install web package using facts
    yum:
      name:
        - "{{ ansible_local.custom.package.web_package }}"
        - "{{ ansible_local.custom.package.db_package }}"
      state: latest
    register: result

  - name: Display the results on controller
    debug:
      var: result
...


Playbook outcome:

# ansible-playbook playbook.yml

PLAY [Use custom defined facts] ************************************************

TASK [setup] *******************************************************************
ok: [node11]

TASK [Install web package using facts] *****************************************
ok: [node11]

TASK [Display the results on controller] ***************************************
ok: [node11] => {
    "result": {
        "changed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "All packages providing httpd are up to date",
            "All packages providing mariadb-server are up to date",
            ""
        ]
    }
}

PLAY RECAP *********************************************************************
node11                     : ok=3    changed=0    unreachable=0    failed=0

How to use Variables in Ansible - Simple example

Simple example to demonstrate variables in Ansible example.
This playbook is going to install HTTPD and Firewalld package.
There are two plays - first one will run on client node (node11) and the second one will run on master node (controller)


# Copy from here:

---
# First play
- name: Install apache and start the service
  hosts: node11  ## hosts is the MUST to include key word in playbook to define target servers. It can be single server or group from Ansible inventory. 
  vars: ## vars is the key word to define vaiables in playbook
    web_package: httpd
    firewall_package: firewalld
    web_service: httpd
    firewall_service: firewalld
    firewall_port: http
    webpage: "This is test page created by Ansible playbook"
  tasks: ## tasks is the MUST to include key word in playbook to list down tasks.

  - name: Install web server package
    yum:
      name: "{{ web_package }}"
      state: latest

  - name: Install firewall package
    yum:
      name: "{{ firewall_package }}"
      state: latest

  - name: Start web service
    service:
      name: "{{ web_service }}"
      state: started
      enabled: yes

  - name: Start "{{ firewall_service }}" service
    service:
      name: "{{ firewall_service }}"
      state: started
      enabled: yes

  - name: Allow web service in fiewall
    firewalld:
      service: "{{ firewall_port }}"
      permanent: true
      state: enabled
      immediate: yes

  - name: Create test web page
    copy:
     content: "{{ webpage }}"
     dest: /var/www/html/index.html

# Second play
- name: Verify that web page is accessible from outside
  hosts: controller
  tasks:
  - name: Try to access the test web page
    uri:
      url: http://node11.example.com
      status_code: 200
...

Monday, July 17, 2017

Ansible - Playbook to setup LAMP server


  • Purpose of this playbook is to setup LAMP server using Ansible.
  • To understand ARRAY's use in Ansible please refer to first block.
  • with_item is another example of loops. It can be mainly used where we can't use Array. Service is one of the module for example which does not support array.
  • You need to change "hosts" names only to use this playbook in your environment to setup LAMP server.  

#Copy from here:
---
- name: Setup LAMP server
  hosts: clientmachine ## change the name by your target server
  tasks:

## First of all we need to install all required packages. All packages are listed under YUM module using ARRAY feature instead writing same line of code multiple times for each package.
  - block:
    - name: Install all Packages - firewalld, httpd, php, php-mysql, and mariadb-server
      yum:
        name:
          - firewalld
          - httpd
          - php
          - php-mysql
          - mariadb-server
        state: latest

## Post installation of packages now we need to start services and enable these services to start automatically at next boot.
  - block:
    - name: Start services - firewalld, httpd and mariadb-server
      service:
        name: "{{ item }}"
        state: started
        enabled: yes
      with_items:
        - firewalld
        - httpd
        - mariadb

## Configure firewall to all Web service access from outside
  - block:
    - name: Allow Web service access from outside
      firewalld: service=http permanent=true state=enabled immediate=true

## Deploy test Web page. You can use either above indentation and format or the below one.
  - block:
    - name: Test Web page
      copy:
        content: "This is test page"
        dest: /var/www/html/index.php
        mode: 0644

    - name: Reload Web service
      service: name=httpd state=reloaded

## Test whether the web page is accessible from outside or not
- name: Test Web server access from outside
  hosts: controller ## change the name by your controller server
  tasks:

  - name: Browse default web page
    uri:
      url: http://node11.example.com/index.php
      status_code: 200
...

Ansible Playbook - Deploy VSFTP and Web Server

---
- name: Deploy VSFTP and Web Server
  hosts: ftpservers #Group name of the server going to host FTP service
  tasks:

# To demonstrate FACTs we used two different OS flavor - RHEL and Ubuntu.
  - block:
    - name: Install FTP package on RHEL
      yum:
        name: vsftpd
        state: present
      when: ansible_distribution == "RedHat"

    - name: Install FTP package on Ubuntu
      apt:
        name: vsftpd
        state: present
      when: ansible_distribution == "Ubuntu"

    - name: Install HTTP package on RHEL
      yum:
        name: httpd
        state: present
      when: ansible_distribution == "RedHat"

    - name: Install HTTP package on Ubuntu
      apt:
        name: apache2
        state: present
      when: ansible_distribution == "Ubuntu"

    - name: Install Firewalld package on RHEL
      yum:
        name: firewalld
        state: present
      when: ansible_distribution == "RedHat"

# Bringing up services only on RHEL - HTTP, FTP and Firwall. To bring up these services only on Ubuntu you can use same modules and attribute with "when: ansible_distribution == "Ubuntu" fact. 
  - block:
    - name: Start firewall Service
      service: name=firewalld state=started enabled=yes
      when: ansible_distribution == "RedHat"
   
    - name: Start WEB Service
      service: name=httpd state=started enabled=yes
      when: ansible_distribution == "RedHat"
   
    - name: Start FTP Service
      service: name=vsftpd state=started enabled=yes
      when: ansible_distribution == "RedHat"
   
# Allow Web and FTP services on RHEL Firewall
  - block:
    - name: Allow Web service in Firewall
      firewalld: service=http permanent=true state=enabled immediate=true
      when: ansible_distribution == "RedHat"
   
    - name: Allow FTP service in Firewall
      firewalld: port=21/tcp permanent=true state=enabled immediate=true
      when: ansible_distribution == "RedHat"

# Modify FTP server configuration to allow Anonymous access.
  - block:
    - name: Create home dir for anonymous user if it does not exists
      file:
        path: /var/ftp/pub
        state: directory
        mode: 0755

    - name: Modify FTP configuation
      lineinfile:
        dest: /etc/vsftpd/vsftpd.conf
        backup: yes
        backrefs: yes
        state: present
        regexp: "{{ item.regexp }}"
        line: "{{ item.line }}"
      with_items:
        - { regexp: anonymous_enable=NO, line: anonymous_enable=YES }
        - { regexp: anon_upload_enable, line: anon_upload_enable=YES }
        - { regexp: anon_mkdir_write_enable, line: anon_mkdir_write_enable=YES }
    when: ansible_distribution == "RedHat"

# Reload FTP service to apply above chanegs.
  - block:
    - name: Start FTP service
      service: name=vsftpd state=restarted enabled=yes
      when: ansible_distribution == "RedHat"
...

Monday, March 27, 2017

Test Second Post

This is second post for testing purpoase

Friday, March 24, 2017

Apache High Availibility Load Balancer

   
           HAProxy is a Load-Balancer, this is fact. It is used to route traffic to servers to primarily ensure applications reliability.  HAPRoxy, which stands for High Availability Proxy, is popular open source software TCP/HTTP Load Balancer and proxying solution which can be run on Linux, Solaris and FreeBSD.


 Keepalived project is to provide simple and robust facilites for loadbalancing and high availability to Linus systems . Load Balancing framework depends on Linux Virtual Server ( IPVS) kernel module which provides Layer4 loadbalacing.

We need to configure Keepalived and HAProxy to achieve this. Our Scnerio is as below
If these are on same network

SCENARIO

1) Node 1 : Web server : 192.168.85.87 . It has content "This is NODE01 Test Server".
2) Node 2 : Web server : 192.168.85.88. It has content "This is NODE02 Test Server".
3) Load1 :  Load Balancer : 192.168.85.97.
4) Load2 : Load Balacner : 192.168.85.99
5) One Virtual IP : 192.168.85.55


Our main Objective is to access website without any downtime. Loadbalancer should have responsibility to send access request to both nodes which are hosting web server. In case of any Web Server down and it should detect that and send next request to another server.

Also loadbalancer should not be single point of failure . So set up loadbalancer in Masters and Backup mode . In case any Loadbalancer get down, other loadbalancer  will get start to work automatically and forward request to Web Server nodes.



[root@load1 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     admin@example.com
   }
   notification_email_from load1@example.com
   smtp_server localhost
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass password123
    }
    virtual_ipaddress {
        192.168.85.55/24
    }
}

[root@load1 ~]#

[root@load1 ~] service keepalived restart


HAPROXY CONFIGURATION




/etc/haproxy/haproxy.cfg

frontend http_front
   bind 192.168.85.55:80
   stats uri /haproxy?stats
   default_backend http_back

backend http_back
   balance roundrobin
   server node1 192.168.85.194:8000 check
   server node2 192.168.86.70:80 check

Check Configuration file if it has some syntax error.
haproxy -f /etc/haproxy/haproxy.cfg –c

In some cases we need to add below entry in sysctl.conf file to get routing work.
vi /etc/sysctl.conf
Add this line
net.ipv4.ip_nonlocal_bind=1
sysctl –p

service haproxy restart


TESTING

[root@load1 ~]# while true; do curl http://192.168.85.55; sleep 1; done
This is NODE01 Test Server
This is NODE02 Test Server
This is NODE01 Test Server
This is NODE02 Test Server
This is NODE01 Test Server
This is NODE02 Test Server
This is NODE01 Test Server
This is NODE02 Test Server
This is NODE01 Test Server
This is NODE02 Test Server


[root@load1 ~]# curl http://192.168.85.55 -D /dev/stdout
HTTP/1.1 200 OK
Date: Fri, 24 Mar 2017 07:28:19 GMT
Server: Apache/2.2.15 (Red Hat)
Last-Modified: Wed, 22 Mar 2017 06:16:01 GMT
ETag: "2c0f91-1b-54b4bb1d7ed3c"
Accept-Ranges: bytes
Content-Length: 27
Content-Type: text/html; charset=UTF-8
Set-Cookie: WEBSVR=1; path=/

This is NODE01 Test Server
[root@load1 ~]#
[root@load1 ~]# curl http://192.168.85.55 -D /dev/stdout
HTTP/1.1 200 OK
Date: Fri, 24 Mar 2017 07:28:23 GMT
Server: Apache/2.2.15 (Red Hat)
Last-Modified: Wed, 22 Mar 2017 06:16:25 GMT
ETag: "2c0f91-1b-54b4bb33dde1e"
Accept-Ranges: bytes
Content-Length: 27
Content-Type: text/html; charset=UTF-8
Set-Cookie: WEBSVR=2; path=/

This is NODE02 Test Server
[root@load1 ~]#



[root@load1 ~]# while true; do curl http://192.168.85.55 --cookie "WEBSVR=2"; sleep 1; done
This is NODE02 Test Server
This is NODE02 Test Server
This is NODE02 Test Server
This is NODE02 Test Server
This is NODE02 Test Server
This is NODE02 Test Server
This is NODE02 Test Server
This is NODE02 Test Server