DevOps Classroom Series – 13/Aug/2020

Execution Strategies

  • Lets start with an assumption we have an Ansible control node and 20 nodes in our inventory. Preview
  • Now lets assume we have a playbook
---
- hosts: all
  tasks:
    - ping: 
  • Now when we execute this playbook how will it execute?
    • On all nodes at one shot
    • One node after other
  • Ansible by default executes in the batches of 5 nodes at a time & this is called as fork. The value of fork can be changed by executing a playbook with -f parameter
ansible-playbook -i hosts -f 20 ping.yaml
  • Fork can be changed in the ansible.cfg file /etc/ansible.cfg
forks = 100
  • How about task executions?
    • On same machines tasks might execute quickly, will they wait for tasks on other nodes to happen or will they continue
  • To decided this ansible has added a play level parameters called as strategy. The default is linear strategy.
  • In linear strategy a task is executed on all nodes & only when they are completed, the next task starts
  • In Free strategy, the tasks are executed one after other in the nodes irrespective of completion on other nodes
- hosts: all
  strategy: free
  tasks:
    - ping: 

Host selection for plays & tasks

  • In the play book we can select hosts rather than using group name or all
  • The value of hosts can be in the following format
hostname:groupname:*.example
  • Lets see sample inventory
[webservers]
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5

[dbservers]
db1.example.com
db2.example.com
db3.example.com
db4.example.com
db4.example.com
  • See the samples
---
- name: sample1
  hosts: webservers[2:4]
  .....
# result
#192.168.0.3
#192.168.0.4
#192.168.0.5

---
- name: sample2
  hosts: db*.example.com
  ...

# result
#db1.example.com
#db2.example.com
#db3.example.com
#db4.example.com
#db5.example.com

--- 
- name: sample3
  hosts: webservers:&dbservers # webserver and dbservers

- name: sample4
  hosts: webservers:!dbservers #webservers not dbservers
   

How Ansible Works with Nodes

  • Ansible Control Node will parse the playbook & gather modules

  • Ansible Control Node will open ssh connection to the node to gather facts and closes the connection

  • Modules from playbook are loaded in to the RAM of Ansible control Node and then a new ssh connection gets opened, Now the modules are transported to some directory on the remote node and ansible closes the connection

  • Now Ansible control node opens the new ssh connection and executes the modules (generally by taking help from python) and gets results and closes the connection Preview

  • To optimize task performance, we can do two performance enhancements

    1. This is in SSH on Ansible control Server, Enable ControlPersist which can drastically reduce the time Ansible takes in Opening & Closing Connections (Linux Feature)
    2. This is an ansible feature. In the Ansible configuration (ansible.cfg)
    [ssh_connection]
    pipelining=true
    
  • The setting changes how modules are transported, Ansible will pipe the 3 steps in one connection. By default pipelining is disabled

Special Variables

  • Lets have the following inventory
[ubuntu]
172.31.3.192

[centos]
172.31.4.122
localhost

[webserver]
172.31.4.122
172.31.3.192

  • The playbook looks like
---
- name: demonstrate special variables
  hosts: all
  gather_facts: false
  tasks:
    - name: tell me which host are you working on
      debug:
        var: inventory_hostname
    - name: tell me which groups are you in
      debug:
        var: group_names
  • Now execute the playbook Preview
  • For the whole list of special variables Refer Here

Ansible Variable Precedence

  • If the same variable is defined at different places in ansible, Ansible chooses the winner depending on the precedence. Refer Here

Accessing external data

  • Data for role, play and task variables can also come from external sources like etcd, redis etc. To fetch values form external sources, ansible provides a mechanism which is called as lookup plugin
  • Syntax
lookup('<plugin_name>', '<plugin_argument>)
  • Example:
- name: get data from etcd
  debug:
    msg: "{{ lookup('etcd', 'package_name') }}"

Next Steps

  • How to make our playbook reusable?
  • Dynamic inventory
  • How to encrypt sensitive information?
  • Ansible Collections
  • Ansible Tower
  • Ansible with Windows (Youtube)

Leave a Reply

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

About learningthoughtsadmin