Ansible is one of many configuration management tools but has its own unique set of differences. The platform aims to provide solutions for the entirety of a setup. With consideration for infrastructure provisioning, application deployment, and overall orchestration taken into account.
Some of its features it uses to achieve this are agentless management, multi-node deployment, ad hoc task execution, module libraries, and use of higher level install scripts referred to as playbooks. Security and reliability is maintained throughout this with SSH as the transport protocol.
Compared to to other CM tools the learning curve is also seen as much lower with Ansible, making it easier to understand and use from the outset. Only Python and a designated control machine are required for the actual installation. With all configuration for the “inventory” assets written in YAML to keep things simple and clean.
1 – Control Machine Installation
The host you want to use as the control machine for Ansible requires Python 2.6 or 2.7 installed. This control machine can be a desktop, laptop, or workstation etc as long it’s running a Linux based OS such as Debian/Ubuntu, Arch, CentOS, RHEL, OS X, or any version of BSD.
Windows as a platform is not currently supported for the control machine.
In this post the commands are shown for installing Ansible onto the control machine using system package managers, and for only a few of the many Linux distributions on offer.
Arch Linux
Ansible has a Pacman package in the community repository.
[alert-announce]
- $ sudo pacman -S ansible
[/alert-announce]
The AUR also has a package build that pulls directly from GitHub called ansible-git
. Any Aurum helper can be used to automatically build and install this, for example:
[alert-announce]
- $ yaourt -S ansible-git
[/alert-announce]
Debian
Open up the Debian software sources file.
[alert-announce]
- $ sudo vim /etc/apt/sources.list
[/alert-announce]
Add the following line to /etc/apt/sources.list
:
deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main
Add the Ansible software repository key to the system; it’s the same source as the Ubuntu PPA.
[alert-announce]
- $ sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-keys 93C4A3FD7BB9C367
[/alert-announce]
Update the package manager to verify the changes and then install Ansible itself:
[alert-announce]
- $ sudo apt-get update
- $ sudo apt-get install ansible
[/alert-announce]
Ubuntu
Install the common software properties package if you don’t already have it.
[alert-announce]
- $ sudo apt-get install software-properties-common
[/alert-announce]
Add the official Ansible package repository to the system and update the package manager database.
[alert-announce]
- $ sudo apt-add-repository ppa:ansible/ansible
- $ sudo apt-get update
[/alert-announce]
Install Ansible from the newly added package repository.
[alert-announce]
- $ sudo apt-get install ansible
[/alert-announce]
Fedora
Fedora users can install Ansible directly:
[alert-announce]
- $ sudo yum -y update
- $ sudo yum -y install ansible
[/alert-announce]
RHEL / CentOS
EPEL must be configured before trying to install Ansible on these systems.
[alert-announce]
- $ sudo yum -y update
- $ sudo yum -y install ansible
[/alert-announce]
2 – Remote Nodes SSH Setup
On the remote nodes you want Ansible to interact with you need to register the control machine’s public SSH key. This is as Ansible uses SSH to communicate and operate by default.
To generate a new SSH key for the control machine use the next command on the control machine host:
[alert-announce]
- $ cd .ssh/
- $ ssh-keygen -t rsa -b 4096 -C “ansible-control-host”
[/alert-announce]
Then copy the new key across to the remote client nodes; changing the -p
value for your own relevant SSH port number. Along with the usernames plus remote host IP addresses.
[alert-announce]
- $ ssh-copy-id -i ansible-control-host -p 3980 [email protected]
- $ ssh-copy-id -i ansible-control-host -p 3980 [email protected]
- $ ssh-copy-id -i ansible-control-host -p 3980 [email protected]
[/alert-announce]
Next open the main Ansible configuration file; which is explained more in a latter section.
[alert-announce]
- sudo vim /etc/ansible/ansible.cfg
[/alert-announce]
Locate the lines that describe private key authentication (shown below) and remove the #
symbol whilst adding in the path to the new private key we created.
[alert-announce]
/etc/ansible/ansible.cfg
- # if set, always use this private key file for authentication, same as
- # if passing –private-key to ansible or ansible-playbook
- private_key_file = ~/.ssh/ansible-control-host
[/alert-announce]
Save and exit the file.
This forces Ansible to use this private key for all operations by default. An alternative to this would be to use the ansible_ssh_private_key_file
variable in the hosts
file explained later on.
Like with the control machine the remote nodes must have Python installed (2.4 or later) as a prerequisite to using Ansible with them. So any remote nodes that do not have Python already installed must be attended to before continuing.
3 – Ansible Hosts File Setup
Continuing on with the control machine – backup the template Ansible hosts file.
[alert-announce]
- $ sudo mv /etc/ansible/hosts /etc/ansible/hosts.orig
[/alert-announce]
Begin writing to a new buffer to create a new “hosts” file.
[alert-announce]
- $ sudo vim /etc/ansible/hosts
[/alert-announce]
Add the contents of the next code snippet into the hosts file, substituting in the IP addresses of your remotes in the process.
[alert-announce]
/etc/ansible/hosts
- [servers]
- remote.one.ip.address
- remote.two.ip.address
- remote.three.ip.address
[/alert-announce]
This configuration file is very flexible and can be expanded to use variables, aliases, and port numbers. Which is what we need to add to ensure the SSH connectivity.
Note: If your SSH port is the default port 22 on these remote nodes then you do not have to set this upcoming port variable.
Expand the file by adding a hostname alias, host variable, user variable, and port number variable:
[alert-announce]
/etc/ansible/hosts
- [servers]
- server-name-1 ansible_host=remote.one.ip.address ansible_user=username ansible_port=3980
- server-name-2 ansible_host=remote.two.ip.address ansible_user=username ansible_port=3980
- server-name-3 ansible_host=remote.three.ip.address ansible_user=username ansible_port=3980
[/alert-announce]
Save the changes and exit the text editor.
As an extra option here, adding an ansible_ssh_private_key_file=~/.ssh/ansible-control-host
variable to each host line is another possibility. Instead of what we set in the last step i.e. the default private key directive in Ansible’s main configuration file (ansible.cfg
).
4 – Test Ansible Connectivity
An Ansible module named “ping” is useful for testing the previous host file configuration we added.
Note that all
can be replaced for a group name like server
– which is taken from the example earlier to only select those hosts in that group.
[alert-announce]
- $ ansible all -m ping
[/alert-announce]
A successful hosts and SSH key configuration returns an output similar to:
[alert-announce]
- hostname1 | SUCCESS => {
- “changed”: false,
- “invocation”: {
- “module_args”: {
- “data”: null
- },
- “module_name”: “ping”
- },
- “ping”: “pong”
- }
- hostname2 | SUCCESS => {
- “changed”: false,
- “invocation”: {
- “module_args”: {
- “data”: null
- },
- “module_name”: “ping”
- },
- “ping”: “pong”
- }
- hostname3 | SUCCESS => {
- “changed”: false,
- “invocation”: {
- “module_args”: {
- “data”: null
- },
- “module_name”: “ping”
- },
- “ping”: “pong”
- }
[/alert-announce]
Manual options are also sometimes added to these ad hoc Ansible commands.
Here -u
selects a Linux user to issue the command as:
[alert-announce]
- $ ansible all -m ping -u <username>
[/alert-announce]
Furthermore the -b
option triggers the command to be run with sudo
privileges:
[alert-announce]
- $ ansible all -m ping -u <username> -b
[/alert-announce]
This is all with the “ping” module example, but live commands are just as easy.
[alert-announce]
- $ ansible all -a “/bin/echo hello world!”
[/alert-announce]
You can do this without invoking the program directly and use the command
module with Ansible instead.
Return the “servers” group drive partitions using the df
program:
[alert-announce]
- $ ansible -m command -a “df -h” servers
[/alert-announce]
Example output from one host:
[alert-announce]
Output
- hostname1 | SUCCESS | rc=0 >>
- Filesystem Size Used Avail Use% Mounted on
- /dev/disk/by-label/DOROOT 30G 6.1G 22G 22% /
- udev 10M 0 10M 0% /dev
- tmpfs 202M 25M 178M 13% /run
- tmpfs 505M 0 505M 0% /dev/shm
- tmpfs 5.0M 0 5.0M 0% /run/lock
- tmpfs 505M 0 505M 0% /sys/fs/cgroup
- tmpfs 101M 0 101M 0% /run/user/1001
[/alert-announce]
Checking disk space on multiple nodes has never been easier!
[alert-announce]
- $ ansible -m command -a “free -h” servers
[/alert-announce]
Example output from one host:
[alert-announce]
- hostname2 | SUCCESS | rc=0 >>
- total used free shared buffers cached
- Mem: 1.0G 875M 134M 25M 187M 570M
- -/+ buffers/cache: 117M 892M
- Swap: 2.0G 32K 2.0G
[/alert-announce]
Query the system’s uptime of only one requested host using the assigned alias from the hosts file:
[alert-announce]
- $ ansible -m command -a “uptime -p” hostname3
[/alert-announce]
Example output:
[alert-announce]
Output:
- hostname3 | SUCCESS | rc=0 >>
- up 7 weeks, 1 day, 7 minutes
[/alert-announce]
5 – Ansible Configuration File
Custom changes to the Ansible install and how it behaves are made through the configuration files.
Changes in relation to the configuration are processed and picked up in the following order:
[alert-announce]
- * ANSIBLE_CONFIG (an environment variable)
- * ansible.cfg (in the current directory)
- * .ansible.cfg (in the home directory)
- * .ansible.cdg (in /etc/ansible/ansible.cfg)
[/alert-announce]
In this section we’re taking a quick look at the ansible.cfg
file we modified slightly earlier.
There’s not much wrong with the default contents of the main /etc/ansible.cfg
file, but you may need to delve into it at some point in the future.
[alert-announce]
- sudo vim /etc/ansible/ansible.cfg
[/alert-announce]
Here are some cherry picked lines and directives from the file that may be of interest. Remember if/when setting these to remove the #
symbol to uncomment.
To assign a different directory for a custom hosts file location.
[alert-announce]
/etc/ansible/ansible.cfg
- #inventory = /etc/ansible/hosts
[/alert-announce]
This next line designates the number of parallel processes to generate when talking with remote hosts. The value will always depend upon your hardware capabilities and amount of remote nodes in play.
Higher fork values will help to complete actions across the nodes faster. Assuming you have the hardware needed. A common value is 50, rather than the default of 5.
[alert-announce]
/etc/ansible/ansible.cfg
- #forks = 5
[/alert-announce]
To control whether an Ansible playbook prompts for a sudo password when sudoing – set this next directive to true.
[alert-announce]
/etc/ansible/ansible.cfg
- #ask_sudo_pass = True
[/alert-announce]
Similarly to set whether an Ansible playbook prompts for a password when run – set this next line to true.
[alert-announce]
/etc/ansible/ansible.cfg
- #ask_pass = True
[/alert-announce]
This sets the default SSH port for all system connections, be aware that any settings in the inventory (e.g. hosts file) will override this.
[alert-announce]
- #remote_port = 22
[/alert-announce]
Set the time out value for SSH queries here on this line:
[alert-announce]
/etc/ansible/ansible.cfg
- # SSH timeout
- #timeout = 10
[/alert-announce]
Enable playbook logging capability in the specified directory on these lines here:
[alert-announce]
/etc/ansible/ansible.cfg
- # logging is off by default unless this path is defined
- # if so defined, consider logrotate
- #log_path = /var/log/ansible.log
[/alert-announce]
Who doesn’t like cowsay
?
[alert-announce]
/etc/ansible/ansible.cfg
- # don’t like cows? that’s unfortunate.
- # set to 1 if you don’t want cowsay support or export ANSIBLE_NOCOWS=1
- #nocows = 1
[/alert-announce]
The lines following these let you tweak and customise components of cowsay even further!
After which the remaining sections that have been omitted here contain more background areas of Ansible, should you need to examine or change them in the future.
[alert-announce]
/etc/ansible/ansible.cfg
- [privilege_escalation]
- <…>
- [paramiko_connection]
- <…>
- [ssh_connection]
- <…>
- [accelerate]
- <…>
- [selinux]
- <…>
[/alert-announce]
Any major changes or crucial updates to the configuration file syntax and formatting will likely be pushed to the GitHub development configuration file at:
https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg
Or shown in the official documentation.
7 – Ansible Temp Directory Permissions
Should the permissions and or ownership rights of the below directory become allocated to root, Ansible will not be able to write to this directory (and thereby fail to run).
/home/$USER/.ansible/tmp/
Here’s how the permissions should look; substituted with your own Linux username.
[alert-announce]
- drwx—— 2 scarlz scarlz 4096 Jun 21 15:12 ./
- drwx—— 3 scarlz scarlz 4096 Jun 21 15:12 ../
[/alert-announce]
Simply make sure the user you are running Ansible as posseses sufficient permissions to utilise this directory. If this is not the case either alter the permissions with chmod
/ chown
or failing that delete the directory then re-run Ansible.