Ansible Playbook to automate Salt Minion deployment

This Ansible playbook is written to automate the steps provided in my previous blog to setup Salt Minion in a Python3 Virtual Environment. Ansible is so beautiful yet cool to complementing SALT to be deployed across all hosts ūüôā

This playbook is self explanatory for those who know Ansible at an intermediate level. Please feel free to reach out to me for help, comments and suggestions.

# vi: set shiftwidth=2 tabstop=2 softtabstop=-1 expandtab:
# Pre-requisites:
# - User 'ansible_admin' to be created on all target hosts
# - User 'ansible_admin' to be added to wheel group with no password prompt
# - SSH keys to be configured for User 'ansible_admin' from Ansible server to all hosts

---
- name: Ansible Playbook to install Salt Minion in a Python Virtual Environment
  hosts: minions
  become: yes
  tasks:
  
  # Step 1: Stop and disable default system's salt minion service. 
  # Service module used for backward compatibility.
  - name: Stop and disable Salt Minion service 
    service:
      name: salt-minion
      state: stopped
      enabled: no
    ignore_errors: true

  # Step 2: To build Python from source code gcc, gcc-c++, zlib, openssl-devel
  # are mandatory. Remaining packages are required for automated install of salt
  # minion in the virtual environment.
  - name: Install dependency packages to build Python3.6
    yum:
      name: "{{ packages }}"
      state: present
    vars:
      packages:
      - libselinux-python
      - libffi-devel
      - gcc
      - gcc-c++
      - zlib
      - zlib-devel
      - readline-devel
      - openssl-devel
      - bzip2-devel
      - sqlite-devel
      - git
      - logrotate
    register: install_result
  - debug:
      var: install_result.stdout

  # Step 3: Check if Python3.6 is already installed on the host.
  - name: Check Python3.6 availability
    stat:
      path: /usr/local/bin/python3.6
    register: out
  - debug:
      msg: "Python3.6 not installed"
    when: out.stat.exists == false

  - debug:
      msg: "REPO Host: {{ url_repo }}"
  # Step 4: Download python and salt source code. salt-minion is the venv
  # which has salt-minion configuration and python modules required to run 
  # salt minion in venv.
  - name: Download files from repo     
    get_url:
      url: "{{ url_repo }}{{ item }}"
      dest: /tmp/{{ item }}
      use_proxy: no 
    with_items:
      - salt-minion.tgz
      - Python-3.6.10.tgz
      - salt.tgz
    when: out.stat.exists == false

  # Step 5: Extract Python and place it in /tmp folder.
  - name: Extract Python3.6
    unarchive:
      src: /tmp/Python-3.6.10.tgz
      dest: /tmp
      remote_src: yes
    when: out.stat.exists == false
  
  # Step 6: Build Python3.6 from source. "make altinstall" is used
  # so that build is not merged with system's default python.
  - name: Build Python3.6 from source
    command: chdir=/tmp/Python-3.6.10 {{ item }}
    with_items:
      - ./configure
      - /usr/bin/make
      - /usr/bin/make altinstall
    register: result
    when: out.stat.exists == false
  
  # Step 7: Validate Python 3.6 build and installed successfully
  - name: Validate Python 3.6 build and installed successfully
    debug:
      msg: "Python3.6 is installed successfully"
    when: out.stat.exists == true

  # Step 8: Check Salt folder exists on the host. It won't exists unless 
  # this playbook was run earlier.
  - name: Check Salt folder exists on the host
    stat:
      path: /salt
    register: salt
  - debug:
      msg: "Salt folder not exists"
    when: salt.stat.exists == false

  # Step 9: Check Salt minionfolder exists on the host. It won't exists  
  # unless this playbook was run earlier.
  - name: Check Salt Minion folder exists
    stat:
      path: /salt-minion
    register: minion
  - debug:
      msg: "salt-minion folder not exists"
    when: minion.stat.exists == false

  # Step 10: Extract salt to root partition on the host. 
  - name: Extract salt to root partition
    unarchive:
      src: /tmp/salt.tgz
      dest: /
      remote_src: yes
    when: salt.stat.exists == false
  
  # Step 11: Extract salt to root partition on the host. 
  - name: Extract salt-minion to root partition
    unarchive:
      src: /tmp/salt-minion.tgz
      dest: /
      remote_src: yes
    when: salt.stat.exists == false

  # Step 12: Add Salt Master and host's ip and hostname in 
  # /etc/hosts file. 
  - name: Add entries to /etc/hosts file
    blockinfile:
      path: /etc/hosts
      block: |
        {{ ansible_default_ipv4.address }}    {{ ansible_hostname }}
        {{ salt_master }}      salt
  
   # Step 13: Copy salt minion logrotate policy on the host.
  - name: Copy salt minion logrotate policy
    copy:
      src: logrotate-salt-minion
      dest: /etc/logrotate.d/salt-minion
      backup: yes
      mode: '0644'

  # Step 14: Validate salt minion logrotate configuration
  - name: Validate salt minion logrotate configuration
    command: logrotate -d /etc/logrotate.d/salt-minion
    register: valrotate
    ignore_errors: true
    changed_when: false
  - debug:
      var: valrotate.stdout_lines

  # Step 15: Check python modules in virtual environment /salt-minion
  - name: Check python modules in virtual environment 
    shell: /salt-minion/bin/python -m pip freeze | wc -l
    register: modcount
    changed_when: false
  - debug:
      msg: "Total number of modules {{ modcount.stdout_lines }}"

  # Step 16: Install missing modules in virtual environment /salt-minion
  - name: Install missing modules in virtual environment
    pip:
      virtualenv: /salt-minion
      requirements: /salt-minion/requirements.txt
      extra_args: "--no-index --find-links=/salt-minion/modules/"
    register: pip
    when: modcount.stdout_lines < 18
  - debug:
      var: pip

  # Step 17: Install salt module in virtual environment /salt-minion
  - name: Install salt module in virtual environment
    pip:
      virtualenv: /salt-minion     
      name: ''
      extra_args: " -e /salt"
    when: modcount.stdout_lines < 19

  # Step 18: Check Salt Minion daemon is already running
  - name: Check Salt Minion daemon is already running or not
    command: pgrep salt-minion  
    ignore_errors: true
    changed_when: false
    register: check_minion
  - debug:
      var: check_minion.stdout

  # Step 19: Start Salt Minion in virtual environment /salt-minion
  - name: Start Salt Minion 
    command: /salt-minion/bin/salt-minion -c /salt-minion/etc/salt -d
    register: start_minion    
    when: check_minion.stdout == ''
  - debug:
      var: start_minion.stdout

  # Step 20: Clean up files downloaded in the /tmp directory
  - name: Clean up
    file:
      path: "{{ item }}"
      state: absent
    with_items:
      - /tmp/Python-3.6.10.tgz
      - /tmp/salt.tgz
      - /tmp/salt-minion.tgz
      - /tmp/Python-3.6.10

One thought on “Ansible Playbook to automate Salt Minion deployment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s