Saturday, 29 June 2019

Running salt-ssh as a non-root user



Introduction

Security is of the essence in every enterprise infrastructure but so is automation. One of the requirements to maintain a healthy balance among the two is to not use root directly while working with automation tools. In this article I'll be setting up salt-ssh, the agentless version of salt and work with it as a non-root user.

This is by no means a comprehensive write up on how Salt or Salt-ssh works and is rather more of a let's get started.

First let's install the tool using yum.

[root@sahil-lab ~]# yum install salt salt-ssh -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.aktkn.sg
 * epel: d2lzkl7pfhq30w.cloudfront.net
 * extras: mirror.aktkn.sg
 * nux-dextop: li.nux.ro
 * updates: mirror.aktkn.sg
Resolving Dependencies
--> Running transaction check
---> Package salt.noarch 0:2015.5.10-2.el7 will be installed
--> Processing Dependency: m2crypto for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: python-crypto for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: python-msgpack for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: python-zmq for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: systemd-python for package: salt-2015.5.10-2.el7.noarch
---> Package salt-ssh.noarch 0:2015.5.10-2.el7 will be installed
 ------------------------------output truncated for brevity


Now let's create the required directory structure.

[sahil@sahil-lab ~]$ mkdir salt_setup
[sahil@sahil-lab ~]$ cd salt_setup/
[sahil@sahil-lab salt_setup]$ mkdir -p {config,salt/{files,templates,states,pillar,formulas,pki/master,logs}}
[sahil@sahil-lab salt_setup]$ mkdir cache
[sahil@sahil-lab salt_setup]$ touch ssh.log


We would also need to copy the contents of /etc/salt directory to the salt_setup directory under the user's home directory.

[root@sahil-lab ~]# cp -rp /etc/salt/* /home/sahil/salt_setup/
[root@sahil-lab ~]# chown sahil:sahil -R /home/sahil/salt_setup/*


The master config file:
The master config file has the same declarations that you would define when using Salt in master mode. Create a master config file with the following contents that points Salt SSH to the location of the previously created directories.

[sahil@sahil-lab salt_setup]$ cat master
root_dir: "/home/sahil/salt_setup"
pki_dir: "pki"
cachedir: "cache"
log_file: "salt-ssh.log"
[sahil@sahil-lab salt_setup]$


The Saltfile:
The Saltfile allows you to set command line configuration option in a file instead of declaring them at runtime. Create a Saltfile with the following contents.

[sahil@sahil-lab salt_setup]$ cat Saltfile
salt-ssh:
  config_dir: "/home/sahil/salt_setup/"
  log_file: "/home/sahil/salt_setup/ssh.log"
  pki_dir: "/home/sahil/salt_setup/pki"
  cachedir: "/home/sahil/salt_setup/cache"
  roster_file: "/home/sahil/salt_setup/roster"
  ssh_wipe: True
[sahil@sahil-lab salt_setup]$


The roster file:
The roster file is used to define remote minions and their connection parameters. The default roster file has some commented out examples that you could use. I've set up a fairly simple one as shown below:

[sahil@sahilsuri0082c salt_setup]$ cat roster
# Sample salt-ssh config file
#web1:
#  host: 192.168.42.1 # The IP addr or DNS hostname
#  user: fred         # Remote executions will be executed as user fred
#  passwd: foobarbaz  # The password to use for login, if omitted, keys are used
#  sudo: True         # Whether to sudo to root, not enabled by default
#web2:
#  host: 192.168.42.2

my-salt-vm: 172.40.36.36

In the above example, my-salt-vm is the salt id of the host I wish to connect to followed by its IP address. I could've also used the server's hostname instead of the IP address.


Testing the setup


Let's use the cmd.run module to get the uptime of our host.

[sahil@sahil-lab salt_setup]$ salt-ssh  '*'  cmd.run 'uptime' --user sahil --priv /home/sahil/.ssh/id_dsa
my-salt-vm:
     05:19:32 up  2:17,  1 user,  load average: 0.15, 0.07, 0.10
[sahil@sahil-lab salt_setup]$


You might be wondering the reason for specifying the user name and key file path explicitly. If you don't salt-ssh defaults to the root user and the following happens:

sahil@sahil-lab salt_setup]$ salt-ssh  '*'  cmd.run 'uptime'
Permission denied for host my-salt-vm, do you want to deploy the salt-ssh key? (password required):
[Y/n] y
Password for root@my-salt-vm:
my-salt-vm:
    Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
[sahil@sahil-lab salt_setup]$

The '*' implies run the command on all hosts defined in the roster.
If you do not wan to specify the user name and key file path every time you connect then you could also specify them in the roster file. 
Here is an example:

cat roster | grep -v '#'

lab-node1:
  host: 172.40.36.36
  user: sahil
  priv: /home/sahil/.ssh/id_dsa
  sudo: True

With this in place you could invoke salt-ssh as shown below:

[sahil@sahil-lab salt_setup]$ salt-ssh lab-node1 cmd.run 'uptime'
lab-node1:
     06:51:28 up  3:49,  2 users,  load average: 0.00, 0.01, 0.05
[sahil@sahil-lab salt_setup]$


Salt-ssh requires Python 2.7 or 3.x to be available on the target machines. But what if you are connecting to a system that has Python version 2.6 or what if it doesn't even Python installed?
In that case you could use -r option to execute a raw shell command.

[sahil@sahil-lab salt_setup]$ salt-ssh  '*'  -r 'uptime' --user sahil --priv /home/sahil/.ssh/id_dsa
my-salt-vm:
    ----------
    retcode:
        0
    stderr:
    stdout:
         06:47:10 up  3:45,  2 users,  load average: 0.00, 0.01, 0.05
[sahil@sahil-lab salt_setup]$


Note: For invoking all salt-ssh commands being executed as non-root user, you must be in the directory where the salt configuration, roster, Saltfile and master configuration file are located.


Last words..

Salt-ssh is a nice agentless extension to the Salt tool but having worked with Ansible I find the inventory file system in Ansible coupled with the ease of setup as a whole to be much more flexible. As a result, given the option to work with salt-ssh or Ansible, I would choose Ansible. If you've worked with both tools, I'd love to hear your experience.

Merge two consecutive lines using awk

Introduction:
As system admins we spend a lot of our time working with files. While doing so we may come across situations wherein we may need to manipulate the content of a file or the output of a command to suit our needs. I came across such a situation recently wherein I had to run nslookup on a couple of hosts and get the hostname the IP address printed on the same line with a colon and a space acting as a delimiter. As with many things in UNIX/Linux there is more than one tool for the job. My task could've been accomplished using sed or perl but I chose to go with awk.

The command:

[ssuri@ulabtestpinfra09:~] $ for i in `cat<<EOF
> ulabtestdinfap31
> ulabtestdinfap35
> ulabtestdinfap37
> EOF`
> do nslookup   $i | awk '/Name|Address: 10/  {print $2}' | awk '!(NR%2){print p ": " $0 }{p=$0}'
> done
ulabtestdinfap31.example.org: 10.47.84.34
ulabtestdinfap35.example.org: 10.47.64.58
ulabtestdinfap37.example.org: 10.47.216.14
[ssuri@ulabtestpinfra09:~] $


Explanation:
As you might've noticed I've used awk twice. The first use is basic so I won't get into it. Now let's talk about the second awk. NR represents the number of rows. % is the modulus operator (i.e. a%b is the remainder when a is divided by b)... (NR%2) is the modulus of NR by two, i.e. is true when NR is even and false when odd. !(NR%2) is true when NR is odd, thus. !(NR%2){print p ": " $0 } means the program will print the line concatenated with the variable p, only on odd lines. {p=$0} means that on every line, p is set to be the current line (but only after printing the current and previous line if the current line is odd).


Conclusion:
This concludes our quick article on how we could use awk to merge or join two consecutive lines. I hope that you found this post to be useful.

Monday, 17 June 2019

Lists in Python

Introduction

Lists in Python are analogous to arrays in Perl. A list holds a set of entities which could be strings or numbers. A list can in fact contain another list.
Declaring a list is fairly straight forward. Type the list name followed by the assignment operator (=) and then the list of items in square brackets separated by a comma.

>>> list=[1,2,3,4,'sahil']
>>> print list
[1, 2, 3, 4, 'sahil']
>>>

To access an individual element in the list type list_name[index]. Note that the indices start from 0 and not 1.

>>> print list[4]
sahil
>>>

Modifying lists:

There are a number of operations we can perform on lists to manipulate them. Here are a couple of examples.

Adding an element to a list:

>>> print list
[1, 2, 3, 4, 'sahil']
>>> list +=["hello"]
>>> print list
[1, 2, 3, 4, 'sahil', 'hello']
>>>


Substituting an element in the list:

>>> list=[1,2,3,4,'sahil']
>>> list[2]=9
>>> print list
[1, 2, 9, 4, 'sahil']


Replacing multiple items in a list:

>>> list[1:3]=[7,8]
>>> print list
[1, 7, 8, 4, 'sahil']
>>>
>>> list=[1, 7, 8, 4, 'sahil']
>>> list[1:2]=[2,3]
>>> print list
[1, 2, 3, 8, 4, 'sahil']
>>>


Removing multiple items in a list:

>>> list[1:3]=[]
>>> print list
[1, 4, 'sahil']
>>>


Add an element using append function:

>>> list.append('world')
>>> print list
[1, 2, 3, 8, 4, 'sahil', 'world']
>>>


Remove list element using pop function:

>>> list.pop(2)
3
>>> print list
[1, 2, 8, 4, 'sahil', 'world']
>>>


Remove list element using it's value:

>>> list.remove('sahil')
>>> print list
[1, 2, 8, 4, 'world']
>>>


Conclusion

This concludes our discussion on lists in Python. We hope that you found this quick and simple explanation to be useful.

Strings in Python

Introduction

In this quick article we'll be talking about strings in Python. Strings are a common data type found in most programming languages. The most basic definition of a string is a sequence of characters that can store anything.
For example 'hello world' is a string. If we type it in the Python REPL, it will print the string back.

>>> 'hello world'
'hello world'
>>>

To assign a string to a variable, type: variable='string' and then print the value of the variable using the print function. For example, on the REPL

>>> greeting='Good Morning'
>>> print greeting
Good Morning
>>>

Concatenating strings:
We often need to concatenate strings in our everyday scripts. To concatenate two strings we use the plus (+) operator. Here is an example.

>>> first_word='hello'
>>> second_word='world'
>>> print (first_word+' '+second_word)
hello world
>>>

Converting a number to a string:
To convert a number to a string we use the str() function. Here is an example.

>>> year=1990
>>> print ('I was born in'+' '+str(year))
I was born in 1990
>>>

If you do not perform the conversion you get a type error.

>>> print ('I was born in'+' '+year)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects


String methods:
Python is an object oriented language and a string in Python is a type of object. An object encapsulates some sort of state. In case of a string the state is a sequence of characters. We can call methods on strings since they are objects. Methods contain functions. Here are two methods that you can use on string objects:

1. Find method:
This searches of a character/s in a string and returns the index value where the character was found in the string.

>>> name="sahil"
>>> name.find("il")
3

2. Lower method:
This converts all characters in a string to lower case.

>>> name="sAhIl"
>>> name.lower()
'sahil'


Slicing strings:
Extracting a part of a string or slicing it is something that Python excels at. To slice a string we need to specify tell Python the starting and ending indices where the string needs to be sliced at. These indices need to be enclosed within square brackets and separated by a colon(:) symbol. We can also assign the sliced strings to variables. Here are a few examples:

>>> name='sahil suri'
>>> fname=name[0:5]
>>> fname
'sahil'
>>> lname=name[6:]
>>> lname
'suri'
>>>


Conclusion:

This concludes our discussion on strings in Python. I hope that you found this post to be useful and there are more Python tutorials on the way.
Here are a few examples.

Tuesday, 4 June 2019

Perl one liner to extract LUNid and disk alias from /etc/multipath.conf file

Introduction:

We may run into situations wherein we need to fetch the LUN id and alias mapping for disks under multipath on a Linux machine. Obtaining this data manually would prove to be cumbersome. One way to fetch this data would be to use the combination of grep and paste commands. But I felt that my Perl was getting a bit rusty so I decided to go the Perl way.

First take a look at the entries from the sample file.

        multipath {
                wwid                    36000d3100008f20000000000000001f4
                alias                   dvd-rhel5-2-64
        }
        multipath {
                wwid                    36000d3100008f20000000000000001f6
                alias                   dvd-rhel5-2-32
        }
        multipath {
                wwid                    36000d3100008f20000000000000003e2
                alias                   dvd-rhel4-7-32
        }

The above output shows the multipath stanzas for a couple of disks. We are basically interested in the wwid and alias section. To extract the required information we will be using the below combination of two Perl one liners.

[root@sahil-lab1 ~]# cat mpath.cf  | perl -ne 'print if(/wwid|alias/);' | perl -pne 'if($.%2){s/\n/\t/;}'
                wwid                    36000d3100008f2000000000000000356                       alias                   aleppo
                wwid                    36000d3100008f2000000000000000a3a                       alias                   dc2tst
                wwid                    36000d3100008f2000000000000000b02                       alias                   dc1tst
                wwid                    36000d3100008f20000000000000003cf                       alias                   algiers
                wwid                    36000d3100008f2000000000000000397                       alias                   algiers_local
                wwid                    36000d3100008f200000000000000004b                       alias                   chicago
                wwid                    36000d3100008f200000000000000004c                       alias                   chicago_mysql
                wwid                    36000d3100008f200000000000000004d                       alias                   chicago_local
                wwid                    36000d3100008f200000000000000004e                       alias                   chicago_assets
                wwid                    36000d3100008f20000000000000001f4                       alias                   dvd-rhel5-2-64
                wwid                    36000d3100008f20000000000000001f6                       alias                   dvd-rhel5-2-32
                wwid                    36000d3100008f20000000000000003e2                               alias                   dvd-rhel4-7-32
[root@sahil-lab1 ~]#

You could further add an additional Perl one liner to print only the alias and LUN id as shown below.

[root@sahil-lab1~]# cat mpath.cf  | perl -ne 'print if(/wwid|alias/);' | perl -pne 'if($.%2){s/\n/\t/;}' | perl -F"\s+" -lane 'print "$F[4]  $F[2]"' 
 aleppo  36000d3100008f2000000000000000356
dc2tst  36000d3100008f2000000000000000a3a
dc1tst  36000d3100008f2000000000000000b02
algiers  36000d3100008f20000000000000003cf
algiers_local  36000d3100008f2000000000000000397
chicago  36000d3100008f200000000000000004b
chicago_mysql  36000d3100008f200000000000000004c
chicago_local  36000d3100008f200000000000000004d
chicago_assets  36000d3100008f200000000000000004e
dvd-rhel5-2-64  36000d3100008f20000000000000001f4
dvd-rhel5-2-32  36000d3100008f20000000000000001f6
dvd-rhel4-7-32  36000d3100008f20000000000000003e2
[root@sahil-lab1~]#


Explanation:

The first one liner simply prints lines containing the strings wwid or alias.
The next one liner loops over the content piped from the previous one liner and uses $. variable denoting the line number. If the remainder of the division of the line number by 2 is not 0 i,e. the line is odd, then the new line after the end of the line gets replaced by a tab thereby combining the even and odd numbered lines together. 
The last one liner invokes the awk like functionality available with Perl one liners. The -F flag in conjunction with -a flag allow us to split lines based on a delimiter and the individual strings in the line get stored in an array variable named @F and we can extract the fields by using the scalar elements that make up the @F array.


Conclusion:

I'm sure there are easier and perhaps more compact versions of Perl one liners out there to accomplish this task. I would appreciate any suggestions and feedback on this approach of extracting the required fields from the /etc/multipath.conf file.

Saturday, 9 March 2019

Installing Ansible on Centos 7

Introduction

As Ansible is agentless, unlike other configuration management platforms, it only requires a master node installation. Ansible is also particularly light due to its lack of daemons, database reliance, and keep-on-running services. Ansible uses Secure Shell (SSH) and WinRM to manage its host clients. Installing Ansible is a fairly straightforward process and in this article we will quickly demonstrate how to install it on a Centos 7 system using the yum package manager.

Prerequisites:

In this respect, Ansible is awesome. For a Linux package installation, all you need is Python 2 (version 2.6 or higher) or Python 3 (version 3.5 or higher). For source installation, we may need the development suite, such as the build-essential package for the Debian family, or the Development Tools group package for the Red Hat family. Most package managers of Linux operating systems will
automatically download the appropriate Python version and its dependencies when asked to install Ansible.

Ansible installation on Centos 7:

If you are using Yellowdog Updater, Modified (Yum), you will have an extra step, since Ansible is not located in the default RHEL repositories. As you may have experienced when installing tools in the past, the Extra Package for Enterprise Linux (EPEL) is often required to be installed before you can use the package manager to install the tools. This is a very straightforward step. We first need to download the epel-release rpm file from the Fedora Project website: http:/ / fedoraproject. org/ wiki/ EPEL. We then need to install it using rpm as follows:

rpm -i epel-release-latest-7.noarch.rpm 
or
yum install epel-release -y 


We can verify that the EPEL repository is now available on the system:

[root@lab ~]# yum repolist epel
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.nbrc.ac.in
 * epel: d2lzkl7pfhq30w.cloudfront.net
 * extras: mirror.nbrc.ac.in
 * nux-dextop: mirror.li.nux.ro
 * updates: mirror.nbrc.ac.in
repo id                                                          repo name                                                                                          status
*epel/x86_64                                                     Extra Packages for Enterprise Linux 7 - x86_64                                                     12,909
repolist: 12,909
[root@lab ~]#

Just like installing any other package using Yum, we will use the yum install command following by the package name (Ansible in this case).

[root@lab ~]# yum install ansible -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.nbrc.ac.in
 * epel: d2lzkl7pfhq30w.cloudfront.net
 * extras: mirror.nbrc.ac.in
 * nux-dextop: mirror.li.nux.ro
 * updates: mirror.nbrc.ac.in
Resolving Dependencies
--> Running transaction check
---> Package ansible.noarch 0:2.7.8-1.el7 will be installed
--> Processing Dependency: python-crypto for package: ansible-2.7.8-1.el7.noarch
--> Processing Dependency: python-httplib2 for package: ansible-2.7.8-1.el7.noarch
--> Processing Dependency: python-keyczar for package: ansible-2.7.8-1.el7.noarch
--> Processing Dependency: python-paramiko for package: ansible-2.7.8-1.el7.noarch
--> Processing Dependency: python2-jmespath for package: ansible-2.7.8-1.el7.noarch
--> Processing Dependency: sshpass for package: ansible-2.7.8-1.el7.noarch
--> Running transaction check
---> Package python-httplib2.noarch 0:0.9.2-1.el7 will be installed
---> Package python-keyczar.noarch 0:0.71c-2.el7 will be installed
---> Package python-paramiko.noarch 0:2.1.1-9.el7 will be installed
--> Processing Dependency: python-cryptography for package: python-paramiko-2.1.1-9.el7.noarch
---> Package python2-crypto.x86_64 0:2.6.1-15.el7 will be installed
--> Processing Dependency: libtomcrypt.so.0()(64bit) for package: python2-crypto-2.6.1-15.el7.x86_64
---> Package python2-jmespath.noarch 0:0.9.0-3.el7 will be installed
---> Package sshpass.x86_64 0:1.06-2.el7 will be installed
--> Running transaction check
---> Package libtomcrypt.x86_64 0:1.17-26.el7 will be installed
--> Processing Dependency: libtommath >= 0.42.0 for package: libtomcrypt-1.17-26.el7.x86_64
--> Processing Dependency: libtommath.so.0()(64bit) for package: libtomcrypt-1.17-26.el7.x86_64
---> Package python2-cryptography.x86_64 0:1.7.2-2.el7 will be installed
--> Processing Dependency: python-idna >= 2.0 for package: python2-cryptography-1.7.2-2.el7.x86_64
--> Processing Dependency: python-cffi >= 1.4.1 for package: python2-cryptography-1.7.2-2.el7.x86_64
--> Processing Dependency: python-enum34 for package: python2-cryptography-1.7.2-2.el7.x86_64
--> Running transaction check
---> Package libtommath.x86_64 0:0.42.0-6.el7 will be installed
---> Package python-cffi.x86_64 0:1.6.0-5.el7 will be installed
--> Processing Dependency: python-pycparser for package: python-cffi-1.6.0-5.el7.x86_64
---> Package python-enum34.noarch 0:1.0.4-1.el7 will be installed
---> Package python-idna.noarch 0:2.4-1.el7 will be installed
--> Running transaction check
---> Package python-pycparser.noarch 0:2.14-1.el7 will be installed
--> Processing Dependency: python-ply for package: python-pycparser-2.14-1.el7.noarch
--> Running transaction check
---> Package python-ply.noarch 0:3.4-11.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==========================================================================================================================================================================
 Package                                          Arch                               Version                                    Repository                           Size
==========================================================================================================================================================================
Installing:
 ansible                                          noarch                             2.7.8-1.el7                                epel                                 11 M
Installing for dependencies:
 libtomcrypt                                      x86_64                             1.17-26.el7                                extras                              224 k
 libtommath                                       x86_64                             0.42.0-6.el7                               extras                               36 k
 python-cffi                                      x86_64                             1.6.0-5.el7                                base                                218 k
 python-enum34                                    noarch                             1.0.4-1.el7                                base                                 52 k
 python-httplib2                                  noarch                             0.9.2-1.el7                                extras                              115 k
 python-idna                                      noarch                             2.4-1.el7                                  base                                 94 k
 python-keyczar                                   noarch                             0.71c-2.el7                                epel                                218 k
 python-paramiko                                  noarch                             2.1.1-9.el7                                updates                             269 k
 python-ply                                       noarch                             3.4-11.el7                                 base                                123 k
 python-pycparser                                 noarch                             2.14-1.el7                                 base                                104 k
 python2-crypto                                   x86_64                             2.6.1-15.el7                               extras                              477 k
 python2-cryptography                             x86_64                             1.7.2-2.el7                                base                                502 k
 python2-jmespath                                 noarch                             0.9.0-3.el7                                extras                               39 k
 sshpass                                          x86_64                             1.06-2.el7                                 extras                               21 k

Transaction Summary
==========================================================================================================================================================================
Install  1 Package (+14 Dependent packages)

Total download size: 14 M
Installed size: 71 M
Downloading packages:
(1/15): libtommath-0.42.0-6.el7.x86_64.rpm                                                                                                         |  36 kB  00:00:00
(2/15): python-enum34-1.0.4-1.el7.noarch.rpm                                                                                                       |  52 kB  00:00:00
(3/15): libtomcrypt-1.17-26.el7.x86_64.rpm                                                                                                         | 224 kB  00:00:00
(4/15): python-cffi-1.6.0-5.el7.x86_64.rpm                                                                                                         | 218 kB  00:00:00
(5/15): python-httplib2-0.9.2-1.el7.noarch.rpm                                                                                                     | 115 kB  00:00:00
(6/15): python-idna-2.4-1.el7.noarch.rpm                                                                                                           |  94 kB  00:00:00
(7/15): ansible-2.7.8-1.el7.noarch.rpm                                                                                                             |  11 MB  00:00:00
(8/15): python-keyczar-0.71c-2.el7.noarch.rpm                                                                                                      | 218 kB  00:00:00
(9/15): python-pycparser-2.14-1.el7.noarch.rpm                                                                                                     | 104 kB  00:00:00
(10/15): python-ply-3.4-11.el7.noarch.rpm                                                                                                          | 123 kB  00:00:00
(11/15): python-paramiko-2.1.1-9.el7.noarch.rpm                                                                                                    | 269 kB  00:00:00
(12/15): python2-crypto-2.6.1-15.el7.x86_64.rpm                                                                                                    | 477 kB  00:00:00
(13/15): python2-jmespath-0.9.0-3.el7.noarch.rpm                                                                                                   |  39 kB  00:00:00
(14/15): sshpass-1.06-2.el7.x86_64.rpm                                                                                                             |  21 kB  00:00:00
(15/15): python2-cryptography-1.7.2-2.el7.x86_64.rpm                                                                                               | 502 kB  00:00:00
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                      10 MB/s |  14 MB  00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python-enum34-1.0.4-1.el7.noarch                                                                                                                      1/15
  Installing : python-httplib2-0.9.2-1.el7.noarch                                                                                                                    2/15
  Installing : sshpass-1.06-2.el7.x86_64                                                                                                                             3/15
  Installing : libtommath-0.42.0-6.el7.x86_64                                                                                                                        4/15
  Installing : libtomcrypt-1.17-26.el7.x86_64                                                                                                                        5/15
  Installing : python2-crypto-2.6.1-15.el7.x86_64                                                                                                                    6/15
  Installing : python-keyczar-0.71c-2.el7.noarch                                                                                                                     7/15
  Installing : python2-jmespath-0.9.0-3.el7.noarch                                                                                                                   8/15
  Installing : python-ply-3.4-11.el7.noarch                                                                                                                          9/15
  Installing : python-pycparser-2.14-1.el7.noarch                                                                                                                   10/15
  Installing : python-cffi-1.6.0-5.el7.x86_64                                                                                                                       11/15
  Installing : python-idna-2.4-1.el7.noarch                                                                                                                         12/15
  Installing : python2-cryptography-1.7.2-2.el7.x86_64                                                                                                              13/15
  Installing : python-paramiko-2.1.1-9.el7.noarch                                                                                                                   14/15
  Installing : ansible-2.7.8-1.el7.noarch                                                                                                                           15/15
  Verifying  : python-keyczar-0.71c-2.el7.noarch                                                                                                                     1/15
  Verifying  : python-idna-2.4-1.el7.noarch                                                                                                                          2/15
  Verifying  : python-ply-3.4-11.el7.noarch                                                                                                                          3/15
  Verifying  : ansible-2.7.8-1.el7.noarch                                                                                                                            4/15
  Verifying  : python-paramiko-2.1.1-9.el7.noarch                                                                                                                    5/15
  Verifying  : python2-jmespath-0.9.0-3.el7.noarch                                                                                                                   6/15
  Verifying  : python2-crypto-2.6.1-15.el7.x86_64                                                                                                                    7/15
  Verifying  : libtomcrypt-1.17-26.el7.x86_64                                                                                                                        8/15
  Verifying  : python-cffi-1.6.0-5.el7.x86_64                                                                                                                        9/15
  Verifying  : libtommath-0.42.0-6.el7.x86_64                                                                                                                       10/15
  Verifying  : sshpass-1.06-2.el7.x86_64                                                                                                                            11/15
  Verifying  : python-httplib2-0.9.2-1.el7.noarch                                                                                                                   12/15
  Verifying  : python-enum34-1.0.4-1.el7.noarch                                                                                                                     13/15
  Verifying  : python-pycparser-2.14-1.el7.noarch                                                                                                                   14/15
  Verifying  : python2-cryptography-1.7.2-2.el7.x86_64                                                                                                              15/15

Installed:
  ansible.noarch 0:2.7.8-1.el7

Dependency Installed:
  libtomcrypt.x86_64 0:1.17-26.el7         libtommath.x86_64 0:0.42.0-6.el7        python-cffi.x86_64 0:1.6.0-5.el7        python-enum34.noarch 0:1.0.4-1.el7
  python-httplib2.noarch 0:0.9.2-1.el7     python-idna.noarch 0:2.4-1.el7          python-keyczar.noarch 0:0.71c-2.el7     python-paramiko.noarch 0:2.1.1-9.el7
  python-ply.noarch 0:3.4-11.el7           python-pycparser.noarch 0:2.14-1.el7    python2-crypto.x86_64 0:2.6.1-15.el7    python2-cryptography.x86_64 0:1.7.2-2.el7
  python2-jmespath.noarch 0:0.9.0-3.el7    sshpass.x86_64 0:1.06-2.el7

Complete!
[root@lab ~]#

Now to validate the success of our installation we can check the ansible version installed on the system using the following command:

[root@lab ~]# ansible --version
ansible 2.7.8
  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 = /bin/ansible
  python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
[root@lab ~]#


Conclusion

We hope that this quick introduction guide was helpful to you. We will be setting up this system to act as our Ansible master node in a future article.

Saturday, 2 March 2019

Ansible Tower and Ansible project comparison

After being bought by Red Hat, Ansible continued to offer a free open source platform, which is currently called the Ansible Project. Red Hat has created proprietary management add-ons that offer an advanced control and centralization of the infrastructure, called Ansible Tower. Red Hat runs the Ansible Automation platform, which is composed of the Ansible Engine and Ansible Tower. This product is fully supported by Red Hat as one of its lead projects.



Ansible project

The Ansible project is a build-up of functionalities that come from the original company, AnsibleWorks. It is a community-built automation engine. It is free, open source, and available for anyone to download or install on any Linux OS, using the package manager, source compiling, or Python PyPI. It is very simple, powerful, and agentless.

To use the Ansible automation engine, users do not need any third-party applications or interfaces. They can simply send a command or write a playbook and execute it directly to the engine. This allows the user to access a variety of predefined modules, plugins, and APIs working as building blocks for managing all kinds of IT tasks and network objects. As it is agentless, Ansible relies on SSH to manage the Linux hosts, and WinRM for the Windows hosts. The SSH protocol is also used to control some of the network devices. Some more unsual devices or cloud and virtualization services require the use of Ansible pre-defined APIs to help manage or access them.


Nodes can be defined by their IP addresses or hostname; for the latter, we will have to rely on a DNS server or the local DNS file. APIs are used to communicate with third-party services, such as public or private clouds. Modules, which constitute Ansible's biggest pre-defined function library, allow the users to simplify long and complex tasks into a few lines in a playbook. They cover a large number of tasks, systems, packages, files, datastores, API calls, network device configurations, and so on. Finally, Ansible plugins are used to improve Ansible's core functionality, such as fast host caching, to avoid facts gathering on the network.


Ansible Tower

Ansible Tower is the Red Hat proprietary layer that sits on top of the Ansible project engine. It is made up of a number of add-ons and modules, composed of REST APIs and web services, that work together to create a friendly web interface that acts as an automation hub from which the IT administrator can select a number of tasks or playbooks to be executed on a number of machines. It still relies on the Ansible Engine to send commands and collect the reports. Ansible Tower cleverly collects the status of tasks and the reports that come back from hosts. All of this data is presented in the Ansible dashboard, showing hosts, the status of the inventory, and the recent jobs, activities, and snapshots.
Ansible Tower scales as the environment grows, and acts accordingly by showing in real-time all the statuses of the hosts, tasks, and playbooks. It highlights the successful playbook jobs, as well as those that failed to run, in order to troubleshoot any issues. In its multi-playbook workflows, the user can create pipelines of playbooks to be executed in sequence on any type of inventory, using one or more users' credentials and on a personalized timescale. With pipelining enabled, an IT administrator can automate complex operations (application provisioning, continuous deployment with containers, running test workflows) by breaking them down into smaller tasks using pipelines and, depending on the output (success or failure), run a specific play.


Ansible Tower offers a smart inventory platform that enables you to pull the host's inventory from any source, including a public or private cloud, or a local CMDB. The smart inventory builds hosts caching, which allows the user to run playbooks based on the facts of the hosts, which are pieces of information and properties related to them and gathered by Ansible. It also allows you to set up built-in notifications about the status of tasks, workflows, and playbooks via email, SMS, and push notifications on third-party platforms, such as Slack or Hipchat. Ansible Tower also allows task scheduling for routine updates, device patching, and custom backup schedule options. 

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...