Cloud & DevOpsHow ToLinuxTech&Dev&code

Ansible Deployment

Installing Ansible

It is very simple to install Ansible.  Ansible software only needs to be installed on the control node from which Ansible will be run. Hosts that are managed by Ansible do not required to have Ansible installed. Ansible Installation involves few steps and has minimal requirements.

The control node must be a Linux or UNIX system. Microsoft Windows is not supported as a control node, although Windows systems can be the managed hosts.

Python 3 (version 3.5 or later) or Python 2 (version 2.7 or later) needs to be installed on the control nodes.

Install Ansible Engine on Control node

[root@onionlinux ~]# yum install ansible

Linux and UNIX managed hosts need to have Python 2 (version 2.6 or later) or Python 3 (version 3.5 or later) installed for most modules to work properly.

Install Python in Managed node

[root@onionlinux ~]# yum module install python36

Microsoft Windows managed hosts require PowerShell 3.0 or later on the managed host rather than Python. In addition, the managed hosts must have PowerShell remoting configured. Ansible also requires at least .NET Framework 4.0 or later to be installed on Windows managed hosts.

To senup windows managed host you can follow https://docs.ansible.com/ansible/latest/user_guide/windows.html.

We can write Ansible Playbooks for network devices using the same basic techniques that we uses when writing playbooks for servers. Because most network devices cannot run Python, Ansible runs network modules on the control node, not on the managed hosts. some  special connection methods are used to communicate with network devices, typically using either CLI over SSH, XML over SSH, or API over HTTP/HTTPS.

Follow   Ansible for Network Automation document to setup managed host for networking devices.

Ansible Inventory

Ansible inventory is collection of hosts that is managed by Ansible, These hosts can be individual or can be a part og groups, which can be managed collectively. Groups can contain child groups and a host can be part of multiple groups. The inventory can also set variables that applies to the hosts and groups that it defines.

There are two ways to define host inventory

Static Inventory: It can be defined by a simple text file, and that is static.

Dynamic Inventory: Dynamic inventory file can be updated dynamically according to adding and removing the hosts. It can be generated by a script or other program as needed, using external information providers.

Specifying Managed Hosts in a Static Inventory

Static inventory file is a simple text file that specifies the managed hosts that Ansible targets. We can write this file in different formats, including INI-style or YAML. INI-style format is commonly used for static Inventory.

An INI-style static inventory file is a list of host names or IP addresses of managed hosts, each on a single line:

app1.onionlinux.com
app2.onionlinux.com
db1.onionlinux.com
db2.onionlinux.com
172.16.2.142

To organize managed hosts, we uses host groups, it allow us to more effectively run Ansible against a collection of systems. In this case, each section starts with a host group name enclosed in square brackets ([]).  This can be followed by the host name or an IP address for each managed host in the group, each on a single line.

In the following example, the host inventory defines two host groups: appservers and db-servers.

[appservers]
app1.onionlinux.com
app2.onionlinux.com
10.0.0.42

[db-servers]
db1.onionlinux.com
db2.onionlinux.com

Hosts can be part of multiple groups. Recommended practice is to organize your hosts into multiple groups, possibly organized in different ways depending on the role on the host. This allows us to easily apply Ansible plays on specific group of hosts.

[appservers]
app1.onionlinux.com
app2.onionlinux.com
172.16.2.142

[db-servers]
db1.onionlinux.com
db2.onionlinux.com

[south-datacenter]
app1.onionlinux.com
db1.onionlinux.com

[north-datacenter]
app2.onionlinux.com
db2.onionlinux.com

[production]
app1.onionlinux.com
app2.onionlinux.com
db1.onionlinux.com
db2.onionlinux.com

[development]
172.16.2.142

there are two host groups which always exist:

  • The all host group contains all hosts explicitly listed in the inventory.
  • The ungrouped host group contains every host explicitly listed in the inventory which is not a member of any group.

 Nested Groups

Ansible host inventories can include groups of host groups. This is accomplished by creating a host group name with the :children suffix. The following example creates a new group called india, which includes all hosts from the mumbai and bangalore groups. A group can have both managed hosts and child groups as members, you could add a [india] section that has its own list of managed hosts. That list of hosts would be merged with the additional hosts that the india group inherits from its child groups.

[mumbai]
mumbai1.onionlinux.com
mumbai2.onionlinux.com

[bangalore]
bangalore1.onionlinux.com
bangalore2.onionlinux.com

[india:children]
mumbai
bangalore

Simplifying the Host Specifications with Ranges

We can specify ranges in the IP addresses  or host names to simplify Ansible host inventories. We can specify either numeric or alphabetic ranges. Ranges have the following syntax:

[START:END]

Ranges match all values from START to END, inclusively. Below are some examples:

  • 172.16.[4:7].[0:255] matches all IPv4 addresses in the 172.16.4.0/22 network (172.16.4.0 through 172.16.7.255).
  • server[01:20].onionlinux.com matches all hosts named server01.onionlinux.com through server20.onionlinux.com.
  • [a:c].dns.onionlinux.com matches hosts named a.dns.onionlinux.com, b.dns.onionlinux.com, and c.dns.onionlinux.com.
  • 2097:sf3::[a:j] matches all IPv6 addresses from 2097:sf3::a through 2097:db8::j.
[north]
delhi[1:2].onionlinux.com

[south]
bangalore[01:02].onionlinux.com

Verifying the Inventory

We can use ansible command to verify a hosts presence in the inventory:

[user1@controlnode ~]$ ansible delhi1.onionlinux.com --list-hosts
 hosts (1):
   delhi1.onionlinux.com

 [user1@controlnode ~]$ ansible delhi01.onionlinux.com --list-hosts
 [WARNING]: provided hosts list is empty, only localhost is available 
  
  hosts (0):

To list all hosts in a group, we can use below command:

[user1@controlnode ~]$ ansible south --list-hosts
 hosts (2):   
   bangalore01.example.com
   bangalore02.example.com

If a inventory contains a host and a host group with the same name, the ansible command prints a warning and targets the host. The host group is ignored, in that case

There are various ways to deal with this situation, the easiest way is to ensure that host groups should not use the same names as hosts in the inventory.

Location of inventory

default location of inventory file is /etc/ansible/hosts/ generally we don’t use the default file to configure the static inventory, we defines inventory file in same directory where we define our ansible configurations.

We use ansible and ansible-playbook commands to run Ansible ad hoc commands and playbooks. To specify the location of an inventory file use ansible command with the --inventory PATHNAME or -i PATHNAME option, where PATHNAME is the path to the desired inventory file.

Defining Variables in the Inventory

Values of variables used by playbooks can be specified in host inventory files. These variables only apply to specific hosts or host groups. It is better to define these inventory variables in a separate file and not directly in the inventory file.

Dynamic Inventory

Inventory information can also be dynamically generated, using information provided by external databases. The open source community has written a number of dynamic inventory scripts that are available to use for Ansible projects. If those scripts do not meet our needs, we can also write our own scripts.

For example, a dynamic inventory program could contact your Amazon EC2 account or Azure account or Red Hat Satellite server, and use information stored there to construct an Ansible inventory. Script does this when we run Ansible, it can populate the inventory with up-to-date information provided by the service as new hosts are added and old hosts are removed.

Managing Ansible Configuration Files

Behavior of an Ansible installation can be customized by modifying settings in the Ansible configuration file. Ansible chooses its configuration file from one of several possible locations on the control node.

Using /etc/ansible/ansible.cfg

Ansible default configuration file located at /etc/ansible/ansible.cfg. This file is used if no other configuration file found.

Using ~/.ansible.cfg

Ansible looks for .ansible.cfg file in the user’s home directory. This configuration is used instead of  /etc/ansible/ansible.cfg if it exists.

Using ./ansible.cfg

If an ansible.cfg file exists in the directory in which the ansible command is executed, it is used instead of the global file or the user’s personal file. This allows administrators to create a directory structure where different environments or projects are stored in separate directories, with each directory containing a configuration file configured with a unique set of settings.

This is recommended to create  ansible.cfg file in a directory from which you run Ansible commands. This directory may also contain many files used by your Ansible project, such as an inventory, vars, and a playbook. This is the most common location used for the Ansible configuration file. It is unusual to use a ~/.ansible.cfg or /etc/ansible/ansible.cfg file in practice.

Using of ANSIBLE_CONFIG environment variable

We can use different configuration files by placing them in different directories and then executing Ansible commands from the appropriate directory, but this method can be restrictive and hard to manage as the number of configuration files grows. Best option is to define the location of the configuration file with the ANSIBLE_CONFIG environment variable. When this variable is defined, Ansible uses the configuration file that the variable specifies instead of any of the previously mentioned configuration files.

Precedence of Ansible Configuration Files

Ansible only uses settings from the configuration file with the highest precedence. Even if other files with lower precedence exist, their settings will be ignored. Therefore, recommended is to create your own configuration file in instead of  using global configuration file /etc/ansible/ansible.cfg , duplicate all desired settings from that file to your own user-level configuration file. Ansible only uses configuration settings from the first file that it finds.

Any file specified by the ANSIBLE_CONFIG environment variable overrides all other configuration files. If that variable is not set, the directory in which the ansible command was run is then checked for an ansible.cfg file. If that file is not present, the user’s home directory is checked for a .ansible.cfg file. The global /etc/ansible/ansible.cfg file is only used if no other configuration file is found. If the /etc/ansible/ansible.cfg configuration file is not present, Ansible contains defaults which it uses.

To check ansible configuration file being used and the version, use ansible –version command.

[user1@controlnode ~]$ ansible --version
  ansible 2.8.0
  config file = /etc/ansible/ansible.cfg
 

...output omitted...

Another way to display the active Ansible configuration file is to use the -v option.

[user@controlnode ~]$ ansible servers --list-hosts -v Using /etc/ansible/ansible.cfg as config file
 

...output omitted...

Managing Settings in the Configuration File

Ansible configuration file consists several sections, each section contains settings defined as key-value pairs. Each section titles are enclosed in square brackets. Generally for basic operation, we use following two sections:

  • [defaults] sets defaults for Ansible operation
  • [privilege_escalation] configures how Ansible performs privilege escalation on managed hosts
[defaults]
inventory = ./inventory
remote_user = user
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

The directives in this file are explained in the following table:

Directive Description
inventory Specifies the path of inventory file.
remote_user Name of user to log in as on the managed hosts. If not specified, the current user’s name is used.
ask_pass Whether prompt or not to prompt for an SSH password. We can make it  false if using SSH public key authentication.
become To automatically switch user on the managed host (typically to root) after connecting. This can also be specified in a playbook.
become_method How to switch user (typically sudo, which is the default, but su is an option).
become_user The user to switch to on the managed host (typically root, which is the default).
become_ask_pass Whether to prompt for a password for your become_method. Defaults to false.

Running Ad Hoc Commands

Ad hoc command is a way of executing a single Ansible task quickly, one that we do not need to save to run multiple times. Ad hoc commands are useful for quick tests and changes. Ad hoc commands also have their limits, and in general we will use Ansible Playbooks to realize the full power of Ansible.

ansible command to run ad hoc commands:

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

host-pattern : used to specify the managed host.

-m & -a option: used to pass the argument, the name of module, Modules are small programs that are expected to implement the tasks. Some modules doesn’t need additional information, but some need additional arguments to specify the details of their operation. The -a option takes a list of those arguments as a quoted string.

One of the simplest ad hoc commands uses the ping module. This module doesn’t do an ICMP ping, but checks to see whether we can run Python-based modules on managed hosts or not.

[user1@controlnode ~]$ ansible all -m ping servera.lab.example.com | SUCCESS => {
  "ansible_facts": { 
     "discovered_interpreter_python":"/usr/libexec/platform-python" },
	 "changed": false,
	 "ping": "pong"
}

To list out all the modules installed in the system use ansible-doc -l  command.

To view documentation of any module we can use ansible-doc  <module_name> command.

To learn mode about ansible modules go here
You can read more basic about Ansible in my another post ‘Ansible: Infrastructure As A Code

 


I hope you like this post “Ansible Deployment”, if you have any questions? please leave comment below! 

Thanks for reading. If you like this post probably you might like my next ones, so please support me by subscribing my blog.

Rohit Kumar Singh

Technical writer, enthusiastic to learn new technologies and exploring the things.

One thought on “Ansible Deployment

Leave a Reply

Your email address will not be published. Required fields are marked *