Remote Machines Management using Ansible

Kcsanjeeb
4 min readFeb 19, 2024

--

In this guide, we’ll walk through the process of setting up Ansible on a designated server and configuring it to manage multiple client machines seamlessly.

Prerequisites

Before diving into Ansible setup, ensure the following prerequisites are met:

  • Access to the designated Ansible server and client machines.
  • Administrative privileges (sudo access) on all machines.
  • Familiarity with basic Linux commands.

Step 1: Network Configuration

Firstly, let’s establish a consistent network configuration across all machines involved in the setup:

Ensure SSH access is enabled from the Ansible server to all client machines for seamless communication.
As previously discussed in our blog series on configuring network settings using the nmcli command line interface in CentOS 9/RHEL 9, you can refer to the following article for detailed guidance:

https://medium.com/@kcsanjeeb091/efficient-development-with-github-jenkins-nginx-and-python-a-cicd-journey-b311d7cc3df9

Step 2: Installing Ansible

On the Ansible Server (Machine 1)

Install Required Packages: Begin by installing the necessary packages. Since Ansible might not be available in the default repositories, we’ll need to enable the EPEL repository to install it.

[devops@ansible ~]$ yum -y install epel-release
[devops@ansible ~]$ dnf config-manager --set-enabled crb
[devops@ansible ~]$ yum install epel-release
[devops@ansible ~]$ yum -y install python3
[devops@ansible ~]$ yum -y install python3-pip

On other Client Servers (Machine 2, Machine 3, Machine 4)

Other client servers require Python to run Ansible because Ansible itself is implemented in Python. When Ansible executes tasks on remote servers, it needs a Python interpreter available on those servers to interpret and execute the Ansible modules and playbooks.

[devops@webserver ~]$ sudo yum install python -y
[devops@developer ~]$ sudo yum install python -y
[devops@tomcatserver ~]$ sudo yum install python -y

# CHECK IF INSTALLED
[devops@tomcatserver ~]$ sudo rpm -q python3
python3-3.9.18-3.el9.aarch64

Step 3: Configuring Ansible

Create Inventory File: Inventory file helps Ansible identify the hosts it manages. Create an inventory file in the desired location (e.g., /home/devops/playbooks/inventory) and define the hosts.

[devmachines]
192.168.208.101

[webservers]
192.168.208.102

[tomcat_servers]
192.168.208.103

Create cfg File: The ansible.cfg file is a configuration file used by Ansible to customize its behavior. Let's break down the contents of the provided ansible.cfg file:

[defaults]
inventory=/home/devops/playbooks/inventory
remote_user=devops

[privilege_escalation]
become=true
  1. [defaults] Section:
  • This section defines default settings that apply globally to Ansible.
  • inventory=/home/devops/playbooks/inventory: Specifies the path to the inventory file. Ansible uses this inventory file to determine the hosts it manages and their associated variables.
  • remote_user=devops: Sets the default remote user to devops. When Ansible connects to remote hosts, it will attempt to SSH as the specified user unless overridden in playbooks or command-line options.
  1. [privilege_escalation] Section:
  • This section configures privilege escalation settings, which allow Ansible to execute tasks with elevated privileges (typically using sudo).
  • become=true: Enables privilege escalation. When this option is set to true, Ansible will attempt to execute tasks with escalated privileges using sudo or a similar mechanism. This is useful for performing tasks that require administrative privileges on remote hosts.

You can install the minimal ansible-core package for the current user:

[devops@ansible playbooks]$ python3 -m pip install --user ansible-core
[devops@ansible playbooks]$ ansible all --list-hosts
hosts (3):
192.168.208.101
192.168.208.102
192.168.208.103

Verify connectivity to the client servers by testing their responsiveness to network requests.

[devops@ansible playbooks]$ ansible all  -m ping
192.168.208.102 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
192.168.208.101 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
192.168.208.103 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}

[devops@ansible playbooks]$ ansible webservers -m ping
192.168.208.102 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}

To ensure consistency across all machines, we’ll create a user named ‘david’ using Ansible. Execute the following command:

[devops@ansible playbooks]$ ansible all -m user -a 'name=david'

This command will create the user ‘david’ on all specified machines if it doesn’t already exist. The state=present parameter ensures that Ansible creates the user only if it doesn't already exist, preventing unnecessary changes.

[devops@ansible playbooks]$ ansible all -m user -a 'name=david'
192.168.208.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1002,
"home": "/home/david",
"name": "david",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1002
}
192.168.208.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1002,
"home": "/home/david",
"name": "david",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1002
}
192.168.208.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1002,
"home": "/home/david",
"name": "david",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1002
}

Now, let’s verify whether Ansible successfully executed the task across different client machines:

# DEVELOPER MACHINE 
[devops@developer ~]$ grep david /etc/passwd
david:x:1002:1002::/home/david:/bin/bash

# WEBSERVER MACHINE
[devops@webserver ~]$ grep david /etc/passwd
david:x:1002:1002::/home/david:/bin/bash

# TOMCATSERVER MACHINE
[devops@tomcatserver ~]$ grep david /etc/passwd
david:x:1002:1002::/home/david:/bin/bash

Now, as everything is running fine, we will delete the created user in all the machines :

[devops@ansible playbooks]$ ansible all -m user -a 'name=david remove=yes state=absent'

In this guide, we’ve successfully set up Ansible on the designated server and established communication with client machines. Additionally, we’ve executed a basic task of user management using Ansible’s declarative syntax. This marks the foundation for further automation and configuration management tasks using Ansible, empowering administrators to efficiently manage their infrastructure at scale.

With Ansible’s robust features and straightforward setup process, organizations can leverage automation to drive agility, reliability, and consistency in their IT operations.

--

--