Master node essential configuration
The Ansible configuration is mainly stored in the ansible.cfg configuration file, which is usually located in /etc/ansible/ansible.cfg in most system package managers and the Python PyPI installation. It may also be located in the home directory of the user who installed Ansible, or whichever location the ANSIBLE_CONFIG environment variable is pointing to. In this section, we will be covering the most useful configuration that can be altered using Ansible to make your life easier.
Open your ansible.cfg file using your favorite text editor, either in CLI mode (using vi or nano) or with a GUI (using Gedit or Atom):
sudo nano /etc/ansible/ansible.cfg
Many would agree that the default configuration of Ansible is fine for normal usage. Ansible is available to use as soon as it is installed.
You can always access the Ansible example configuration file to have a look at how the options are being used. The example can be found at the following link: raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg.
Ansible's configuration file is divided into several sections. The main section that we will concentrate on is the [defaults] general section. We will start by introducing the basic parameters in this section.
- inventory: This is a parameter to indicate the file that is hosting the inventory for Ansible. On most systems, it points to /etc/ansible/hosts, as follows:
inventory = /etc/ansible/hosts
- roles_path: This is a parameter to indicate where the Ansible playbook should look for additional roles to the system default:
roles_path = /etc/ansible/roles
- log_path: This a parameter to indicate where Ansible should be storing its log. Make sure that the user running Ansible has permission to write on the specified location. An example is as follows:
log_path = /var/log/ansible.log
- retry_files_enabled: This is a parameter to enable the retry feature, allowing Ansible to create a .retry file whenever a playbook fails. It is better to keep this disabled unless you really need it. This is because it creates multiple files and clogs your playbook folder with old failed tasks that are already logged in both the Ansible log and the dashboard's playbook execution status section. Here is an example of the parameter disabled:
retry_files_enabled = False
- host_keychecking: This is a parameter that changes its recommended value depending on the environment. Usually, it is used in a continuously changing environment, where old machines get deleted and new machines take their places. It is more frequently used in a cloud or a virtualized environment, where virtual machines and deployment instances take the IP addresses of older machines. Ansible holds a key for those machines to prevent security issues. Disabling this parameter will make Ansible ignore the error messages related to the known_hosts keys:
host_key_checking = False
- forks: This is a parameter to define the number of parallel tasks executed to the client hosts. The default number is five, to save on both resources and network bandwidth. If there are enough resources and a large bandwidth to serve many hosts, it can be raised to the maximum number of hosts as follows:
forks = 10
- sudo_user and ask_sudo_pass: These are both legacy parameters. It is still possible to use them with the current version of Ansible, but they are not reliable. It is recommended to set these parameters when creating groups in Ansible's inventory—this is explained in more detail in the next chapter, but an example is as follows:
sudo_user = install
ask_sudo_pass = True
- remote_port: This is a parameter to indicate which port is to be used by SSH on the client hosts. It is also a parameter that is better set in the inventory groups:
remote_port = 22
- nocolor: This is an optional parameter. It allows you to show different colors for the Ansible tasks and playbook to indicate errors and successes:
nocolor = 0
The following parameters relate to the SSH connection with the host [ssh_connection].
pipelining: This parameter enables the feature of reducing the number of SSH operations required to execute a module. This happens by executing Ansible modules without an actual file transfer and can improve Ansible's performance greatly. It requires having requiretty disabled in /etc/sudoers on all the managed hosts. An example of its use is as follows:
pipelining = True
The scp_if_ssh and transfer_method parameters: Both of these are responsible for file transfers between the master node and the client hosts. Choosing the smart value allows Ansible to choose between SFTP and SCP to opt for the most suitable protocol when transferring files:
scp_if_ssh = smart
transfer_method = smart
The following two examples relate to the persistence of the SSH connection, [persistent_connection]. We are only covering timeout for a connection and a retry for a failed one. The SSH timeout can be set by editing the value of those two parameters as follows, firstly:
connect_timeout = 30
And secondly:
connect_retry_timeout = 15
Finally, let's look at the [colors] color selection. This section gets activated when enabling the color feature in the [default] section. It allows you to choose different colors for various output statuses. This may be helpful when using a special display or to help with color blindness:
warn = bright purple
error = red
debug = dark gray
ok = green
changed = yellow
skip = cyan
On another note, we should never forget that Ansible relies on SSH to communicate with its clients. Configuration should be done on the master node to create an SSH key that is then copied to all the client hosts to enable passwordless remote access. This helps to remove passwords saved as plain text and enables full automation of the tasks. Creating an SSH key can either be simple or more complicated and more secure. We will go with the simple option:
ssh-keygen -t rsa
Keep on pressing enter while accepting the key and leaving the passphrase empty:
ssh-copyid user@host1
This task can be a bit dull and very manual. Scripting using the expect command can be very handy when trying to sort out SSH keys and authentication. First, we need to make sure that expect is installed, since it is not usually installed by default. The following examples show this process for a variety of operating systems.
This command line shows how to install the tool Expect on a Linux from the Red Hat family:
sudo yum install -y expect-devel
This command line shows how to install the tool Expect on a Linux from the Debian family:
sudo apt install -y expect
This command line shows how to install the tool Expect on MAC OS X:
brew install expect
We can then create a script file with the following:
#!/usr/bin/expect -f
set login "install"
set addr [lindex $argv 0]
set pw [lindex $argv 1]
spawn ssh-copy-id $login@$addr
expect "*yes/no*" {
send "yes\r"
expect "*?assword*" { send "$pw\r" }
} "*?asswor*" { send "$pw\r" }
interact
This script should have execution privileges to be executed. It can then be used with another loop script to be executed on several machines whose IP address range or hostnames are known:
#!/bin/bash
password=`cat /root/installpassword.txt`
for j in 10 11 12 13 14 15 16 17 18 19 20
do
./expectscript 192.168.1.$j $password
done
Alternatively, we can use an orchestration tool to do the same task. Let's use Ansible to help with client configuration by using the simple copy and shell modules:
ansible all -m copy -a "src=~ /.ssh/id_rsa.pub dest=/tmp/id_rsa.pub" --ask-pass -c install
ansible all -m shell -a "cat /tmp/id_rsa.pub >> /home/install/.ssh/authorized_keys" --ask-pass -c install