Monday, August 13, 2018

Ansible Certification : 2. Deploying Ansible

2. Deploying Ansible. 

  • Installing Ansible.
  • Managing Ansible Configuration Files.
  • Running Ad Hoc Commands.
  • Managing Dynamic Inventories.
  • Summary
  • Lab:
  • Exercise

=========================================================================

Installing Ansible 

Ansible installation is relatively simple. All it needs is that you have python 2 or 2.6 version present on the server where its about to be installed. On the managed hosts 2.4 and above will be good. 

Just in case if the version of python installed is earlier than 2.5 then it must also have python-simplejson package installed. 

SSH-key-based Authentication:

As ssh connection requires authentication each time it connects, hence the need for Key-based authentication is needed. Private and public key needs to be created and Public key needs to be pushed on to Managed hosts so that going forward we don't have to authenticate again and again. 
SSH key can be copied to different hosts with a command "ssh-copy-id" . 

Once ansible has been installed you can use the help option ( $ ansible -h ) to get help and ( $ ansible --version) to check for the installed version. 

Referencing Inventory Hosts:









Managing Ansible Configuration Files : 

Configuration of ansible can be controlled using the below files mentioned in the directories with Priorities.

1.  /etc/ansible/ansible.cfg --> This file is used when no other files are present. 
2.  ~/.ansible.cfg --> present in user's home directory. This is used b4 first entry if present. 
3.  ./ansible.cfg -->   If this file is present in the home directory from where the command is run then this will be used first.
4.  $ANSIBLE_CONFIG --> this is used to setup in an environment for Ansible if you have multiple locations to be run at multiple directories. This precedes all other entries. 

Due to these multitude of locations where ansible file can be placed, its very difficult to identify which files is being currently used by ansible, Hence in order to identify which file is currently being in use we can take help of the below command. 

# ansible --version 

 # ansible --version

   ansible 2.5.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules',       u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, May  3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]


Another active way to see currently used ansible configuration is with -v option . 

# ansible server --list-hosts -v 

[root@Automation-1 ~]# ansible all --list-hosts -v
Using /etc/ansible/ansible.cfg as config file
  hosts (2):
    auto-2
    auto-3

Ansible configuration file breakup can be divided into below sections : 

[root@Automation-1 ~]# grep "^\[" /etc/ansible/ansible.cfg
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]


All the above mentioned parameters are configured ansible configurations but you have a miss here which is ( galaxy ) will talk about it later. 


1. Inventory -- > Location of the ansible inventory file. 
2. remote user -- > The remote user account used to establish connections to managed hosts. 
3. become -- >  Enables or disables privilege escalations for operations on managed hosts.
4. become_method -- > Defines the privilege escalations method on managed hosts. 
5. become_user -- > The user account to escalate privilege on managed hosts. 
6. become_ask_pass -- > Its for asking password while escalating user privilege on managed hosts.


Practicals : 

1. Log onto any system and run ansible version command to check active config files. 
#  ansible --version.

2. Open /etc/ansible/ansible.cfg file and examine the different sections for example. 
    Under the [default] section, locate and examine the inventory settings. 
    Check for [privilege_escalation] section. 
# cat /etc/ansible/ansible.cfg.


3. Create a user level Ansible configuration file at your home directory and then check which file is getting used for ansible config changes. 
# touch /home/xyz/ansible.cfg
# ansible --version.


4. Create a directory and when you are in that directory create a ansible cfg file and then check which file is being read for ansible configuration. 
# mkdir /home/xyz/vikas/ansible.cfg
# ansible --version. 


5. Create another user level ansible configuration file at /home/xyz/vikas/aaa/ansible.cfg. Set the $ANSIBLE_CONFIG  environment variable full path and then check which file is getting used currently. 
# touch /home/xyz/vikas/aaa/ansible.cfg. 
# export ANSIBLE_CONFIG=/home/xyz/vikas/aaa/ansible.cfg. 
# ansible --version. 

6. How to change default working inventory location for ansible. 
In the file ansible.cfg go to defaults section and modify the below : 

[defaults]
inventory=/home/xyz/vikas/inventory 

7. Go to that folder and create a hosts file in the directory. 
# cd /home/xyz/vikas/inventory
# vi hosts
   server1.lab.com
   server2.lab.com

Check with the below command if you are able to get the same content as below :
# ansible classroom --list-hosts.


Running AD-Hoc commands : 

- Running ad hoc commands locally.
- Running ad hoc commands remotely.
- Usage of ad hoc commands.


Ansible allows user to run/execute on-demand tasks on managed hosts. These ad hoc commands are the most basic operations that can be performed using ansible.

Each ad hoc command is capable of performing a single operation. If you need to run multiple commands then you will need to execute a series of ad hoc commands on the hosts.

Ad hoc commands are the simplest way for an user to start with learning ansible and then move on towards more complex ways like modules, plays and playbooks.

Alternatively ad hoc commands can be used to perform non-invasive commands such as querying a large group of managed for diagnostic information.

Syntax for Ad-hoc commands :

# ansible host-pattern -m module [ -a 'module arguments'] [-i inventory] 


Using modules in an Ad hoc commands: 

The modules are specified by -m options and this specifies which ansible module needs to be used to perform the remote operations. Will talk about modules later. 

Arguments are passed to a specified module using -a options. Some modules can handle no arguments and others can handle multiple arguments. When no arguments are needed simple run the command without providing -a option. if multiple arguments are needed then you can run them as below : 

# ansible host-pattern -m module -a 'argument1 argument2' [-i inventory]

Administrator has the rights of defining a default module that can be used by Ansible if no module has been specified. 
By default Ansible uses command module and mentioned in /etc/ansible/ansible.cfg file under 
# default module name for /usr/bin/ansible.
# module_name = command. 


So these 2 commands are equivalent to 1 another. 

Command 01 :  # ansible host-pattern -m command -a 'module arguments'
Command 02 :  # ansible host-pattern -a 'module arguments'


Mostly if you see below the normal Ansible output is fetched in 2 lines, 1 signifies the server it tried to reach and other is what it ran over there. 

You can get the Ansible output listed in 1 line with -o switch like below : 

[root@Automation-1 ansible]# ansible all -m command -a 'date' -o
auto-3 | SUCCESS | rc=0 | (stdout) Mon Aug  6 13:02:11 IST 2018
auto-2 | SUCCESS | rc=0 | (stdout) Mon Aug  6 13:02:02 IST 2018

Note : Drawbacks of command module over shell.
The commands run by using command module in Ansible cannot execute stuff related to piping and redirecting as they are not provided any shell by system when they execute. 

For such instance you need to use shell command instead of "command" command. 
Examples below : 

[root@Automation-1 ansible]# ansible auto-2 -m command -a set
auto-2 | FAILED | rc=2 >>
[Errno 2] No such file or directory

[root@Automation-1 ansible]# ansible auto-2 -m shell -a set
auto-2 | SUCCESS | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()


Ad Hoc command configuration:
When an Ad Hoc command is executed, several things occur behind the scene. First the ansible configuration file is consulted for various parameters. Module_name that we had seen before is one such example. 

a. Connection settings: 
Reading the connection related parameters mentioned in the cfg file, Ansible triggers connection using the remote user mentioned in file. 

b. Privilege Escalation: 
After successfully connecting to a hosts, ansible can switch users before executing any operation.

Ansible Command line Options : 

Settings :                                                 Command line options 
Inventory                                                  -i 
remote_user                                            -u 
become                                                    --become, -b 
become_method                                      --become_method 
become_user                                           --become_user
become_ask_pass                                   --ask-become-pass, -k 

# ansible --help 

======================================================================
EXERCISE: 

1. [root@Automation-1 ~]# ansible auto-2 -m command -a 'id'
auto-2 | SUCCESS | rc=0 >>
uid=0(root) gid=0(root) groups=0(root)

2. Now we will try to change the remote file with dynamic content for ex: motd file.
[root@Automation-1 ~]# ansible auto-2 -m command -a 'cat /etc/motd'
auto-2 | SUCCESS | rc=0 >>


#  Here you can see that the file is empty .

3. Now lets try to put some content on to the empty file remotely.
[root@Automation-1 ~]# ansible auto-2 -m copy -a 'content="Managed by Vikas\n" dest=/etc/motd'
auto-2 | SUCCESS => {
    "changed": true,
    "checksum": "881a4e0ddbf6172bc0f7c4a0bb7919fbac59d6ab",
    "dest": "/etc/motd",
    "gid": 0,
    "group": "root",
    "md5sum": "ff7609058aa99d919ca273d99f2e1b95",
    "mode": "0644",
    "owner": "root",
    "size": 17,
    "src": "/root/.ansible/tmp/ansible-tmp-1534002527.61-15459222671883/source",
    "state": "file",
    "uid": 0
}

4. [root@Automation-1 ~]# ansible auto-2 -m command -a 'cat /etc/motd'
auto-2 | SUCCESS | rc=0 >>
Managed by Vikas

=================================================================

Managing Dynamic Inventory :

In this section we will use an Ansible Dynamic inventory to Pro-grammatically build an inventory from external data sources. 

By default, Ansible provides a text-based inventory format to define the hosts to be managed. When operating with larger systems ansible provides options of using the directories service monitored by them. Ansible supports dynamically building of an inventory from these external data sources through the use of scripts which retrieves information from them. 
AWS, Virtual environments also have such information of an instances such information can be used by ansible to build a hosts file in short time period. 

Difference between Static and Dynamic Inventory :
If the inventory file is executable then it is termed as dynamic inventory and if its not executable then its termed as static inventory. 

Supported Platforms : Below is the path of the scripts which can/will help you to generate a large number of inventory list if you have a large environment. 
Ansible Github site : https://github.com/ansible/ansible/tree/devel/contrib/inventory. 

1. Private cloud - redhat openstack platform. 
2. Public cloud - Rackspace, AWS & Google Space. 
3. Virtualization platforms like - OVIRT. 
4. Platform as a service solution - Openshift. 
5. Spacewalk. 

Writing Dynamic Inventory program : 

If a dynamic inventory script does not exists for the directory structure or infrastructure in use, It is possible to write a custom dynamic inventory program. Scripting can be done in any programming language, and it must return in JSON format when passed appropriate options. 

In order for an ansible script to retrieve list of hosts, script will have to run with option like --list parameter. Which in return should provide the details like group and hostname or IP address. 

# ./inventoryscript --list
{
        "Webservers" : [ "webserver1.example.com", "webserver2.example.com" ],
        "Database"   : [ "db1.example.com", "db2.example.com" ],
}

Working with multiple inventories:     

Ansible supports the use of Multiple inventories in the same run. If you place the inventory files in a directory and change the config files accordingly then all the inventory files under that directory will be read and executed. Path to change /etc/ansible/ansible.cfg. 


When multiple file exists in the same directory then they are examined in alphabetical order. In a similar fashion if you can include the inventory list so you can ignore them as per files. 



SUMMARY :

Lets summarize as to what we have completed until now: 

- Any system on which ansible is installed and which has access to right configuration files and playbooks to manage remote hosts can be termed as control hosts. 

- The managed hosts are defined in the inventory file. Host patterns are used to reference managed hosts defined in an inventory. 

- Inventory can be static or dynamic generated from a script or a program. 

- The location of the inventory should be managed by ansible.cfg file but it would great if its maintained at playbook directories. 

- Ansible look for a number of places for its configuration file. In an order mentioned before the first match point is taken by passing all the rest ansible cfg files. 

- The Ansible command is used to perform one time Ad-hoc requests on the server. 

- Ad Hoc commands determine the operation to perform through the use of modules and their arguments. 

- Ad Hoc commands which require additional permissions to get the job done, for these kind of jobs you can use escalation feature in ansible.