Skip to main content

Configuring Ansible

Keep your Ansible installation secure and tidy with these guidelines.

In a previous article, I covered Red Hat Ansible basics and installed Ansible, creating one control node named RHEL8 and four managed nodes (node1, node2, node3, and node4), all running Red Hat Enterprise Linux. Now, for Ansible to communicate with a managed node, you need to configure the control node and the managed nodes with a user account, and give that user account privilege escalation to run commands without having to enter a password.

Add a user account to all managed nodes (node1, node2, node3, and node4) and the control node (RHEL8). To keep things simple in this example, I will create an ansible user account, add the ansible user to the wheel group, and then configure SSH authentication.

User accounts

When configuring a new user account (in this case, the ansible user), create the account across all nodes:

[kc@RHEL8 ~]$ sudo useradd ansible

Then add the ansible user to the wheel group:

[kc@RHEL8 ~]$ sudo usermod -aG wheel ansible

Set a password for the ansible user so you can log in as that user:

[kc@RHEL8 ~]$ sudo passwd ansible
Changing password for user ansible.
New password:
Retype new password:
passwd: all authentication tokens updated successfully. 

Next, configure the ansible user for passwordless privilege escalation using the /etc/sudoers file:

%wheel ALL=(ALL) NOPASSWD: ALL

Once you create the new ansible user on all managed and control nodes, generate an SSH key on the control node and then copy the SSH public key to all managed nodes. In this example, I use the defaults while configuring SSH:

[kc@RHEL8 ~]$ sudo su - ansible
[ansible@RHEL8 ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ansible/.ssh/id_rsa):
Created directory '/home/ansible/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ansible/.ssh/id_rsa.
Your public key has been saved in /home/ansible/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:saD6SI4u47J50N5UmV2UfpZcXhbW6UzhrDH4ksr2z4w ansible@RHEL8
The key's randomart image is:
+---[RSA 2048]----+
| ... +=|
| o . =o+|
| .+.o o *+= |
| .+..o. B =o |
| . .. S = o |
|. ... . . . |
| ooo + |
|+=oo. . . + |
|O*o . E.+ |
+----[SHA256]-----+

Now, copy the SSH public key to all managed nodes, which lets the ansible user log into all managed hosts without having to enter a password:

[ansible@RHEL8 ~]$ ssh-copy-id ansible@node1.example.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ansible/.ssh/id_rsa.pub"
The authenticity of host 'node1.example.com (3.15.137.216)' can't be established.
ECDSA key fingerprint is SHA256:SJMRfA1B8NDEA9BwxE6aiPs30YGS+Sp1eBRtocyK5sY.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ansible@node1.example.com's password:

Number of key(s) added: 1

Now try logging into the machine with SSH: 'ansible@node1.example.com'"
and check to make sure that only the key(s) you wanted are added.  

[ansible@RHEL8 ~]$

Configuration files

The default Ansible configuration file is located under /etc/ansible/ansible.cfg. Most of Ansible’s settings can be modified using this configuration file to meet the needs of your environment, but the default configurations should satisfy most use cases. Regardless, it is worth knowing where Ansible searches for configuration files.

Ansible searches for configuration files in the following order, processing the first file it finds and ignoring the rest:

  1. $ANSIBLE_CONFIG if the environment variable is set.
  2. ansible.cfg if it’s in the current directory.
  3. ~/.ansible.cfg if it’s in the user’s home directory.
  4. /etc/ansible/ansible.cfg, the default config file.

The default inventory file is found inside /etc/ansible/hosts, but this location can be changed in the configuration file. You can also specify which inventory file to use with the -i switch.

Your inventory file looks like this:

[nodes]

node1.example.com
node2.example.com
node3.example.com
node4.example.com

[webservers]
node2.example.com
node3.example.com

It is recommended that you specify different host files for various projects.

Ansible ad-hoc commands

An ad-hoc command is a command that you might issue to perform a quick task, but will not use in the immediate future. To appreciate Ansible ad-hoc commands and to help you use Ansible more efficiently, look at some essential Ansible command-line options:

Option Description
-b, --become Run command with privileges (doesn’t prompt for password).
-m Provide module name to use.
-a, --args Insert module arguments.
-u Connect as different user.
-h, --help Display help content.
-v, --verbose Run commands in verbose mode.

 

The complete list of Ansible command-line options can be found here. Now, have a look at some examples.

Checking connectivity with ad-hoc commands

To check connectivity to managed hosts using the ping module:

[ansible@RHEL8 ~]$ ansible all -m ping

In the above command, all specifies that Ansible should run this command on all hosts. Here is the response to that command:

[ansible@RHEL8 ~]$ ansible all -m ping
node2.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
node1.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
node3.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
node4.example.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
[ansible@RHEL8 ~]$

Managing packages with ad-hoc commands

Using Ansible’s ad-hoc commands, you can also install software packages to your managed hosts. All you need to issue is a one-liner to install a single package to a group of managed hosts.

Install the Apache httpd server on your webservers managed hosts' group:

[ansible@RHEL8 ~]$ ansible webservers -m yum -a "name=httpd state=present" -b

Managing services with ad-hoc commands

Since you successfully installed Apache’s httpd server in the last step, see how you can use Ansible’s ad-hoc commands to start and enable the httpd service, so your Apache httpd web server is up and running.

In order to enable a service, issue:

[ansible@RHEL8 ~]$  ansible webservers -b -m service -a "name=httpd enabled=yes"

To start, restart, and stop a service, change the value of the state argument to started to start the service, restarted to restart a service, and stopped to stop a service:

[ansible@RHEL8 ~]$  ansible webservers -b -m service -a "name=httpd state=started"

Ansible ad-hoc commands are excellent and suitable for running a single task. A full list of modules can be found here.

Playbooks

Ansible playbooks are a powerful way of using Ansible. Unlike Ansible ad-hoc commands, Ansible playbooks can be saved and reused.

Playbooks are defined in YAML Ain’t Markup Language (YAML). Each playbook is comprised of one or more plays. The goal of plays is to map a group of hosts to tasks. Each play consists of one or more tasks, and these tasks are executed one at a time.

Here is a simple Ansible httpd.yaml playbook to install Apache’s httpd server on the webservers group:

---
- hosts: webservers
  remote_user: ansible
  tasks:
  - name: Ensure apache is installed and updated
    yum:
      name: httpd
      state: latest
    become: yes

 

In order to run this Ansible playbook, issue the following command in the format:

[ansible@RHEL8 ~]$ ansible-playbook -i <hostfile> <playbook.yaml>

Since you're using the default hosts file (/etc/ansible/hosts), you can ignore -i flag and just issue the command in the format:

[ansible@RHEL8 ~]$ ansible-playbook <playbook.yaml>

So, for this example:

[ansible@RHEL8 ~]$ ansible-playbook httpd.yaml

PLAY [webservers] *************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [node2.example.com]
ok: [node3.example.com]

TASK [Ensure apache is installed and updated] *********************************************************************
changed: [node2.example.com]
changed: [node3.example.com]

PLAY RECAP ********************************************************************************************************
node2.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node3.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[ansible@RHEL8 ~]$

Playbooks are powerful when you need to run multiple tasks on different groups of managed hosts. To demonstrate how you can use more than ad-hoc commands, use a playbook to:

  1. Install the httpd server.
  2. Enable and start the httpd service in your webservers managed hosts' group.
  3. Install git on all managed hosts.

The playbook may look something like this:

---
- hosts: webservers
  remote_user: ansible
  become: yes
  tasks:
  - name: Installing apache
    yum:
      name: httpd
      state: latest
  - name: Enabling httpd service
    service:
      name: httpd
      enabled: yes
    notify:
      - name: restart httpd
  handlers:
  - name: restart httpd
    service:
      name: httpd
      state: restarted

- hosts: all
  remote_user: ansible
  become: yes
  tasks:
  - name: Installing git
    yum:
      name: git
      state: latest

In the above example, you performed two plays in one playbook. Read more about Ansible playbooks here.

Conclusion

Ansible is simple, easy to set up, and powerful. Ansible is agentless, which makes it easy for a sysadmin to get started with automation and spend less time configuring. With this tool, every sysadmin—irrespective of their experience level—can begin automating their infrastructure in just a few hours, if not minutes. The ease-of-use and robust toolset makes Ansible a highly desirable automation platform to learn.

Topics:   Ansible   Automation  
Author’s photo

Keerthi Chinthaguntla

Keerthi is aspiring Cloud, DevOps engineer, he has been working with Windows and Linux systems. He believes in continuous learning (CL) and continuous sharing (CS), on his way building his very own CL CS pipeline. When he is not playing in the CLI, you will find him playing Cricket.  More about me

Try Red Hat Enterprise Linux

Download it at no charge from the Red Hat Developer program.