Automating Linux System Configuration with Ansible: A Step-by-Step Guide

Today, we're diving into the world of Ansible, a powerful automation tool that simplifies managing and configuring Linux systems. This guide will walk you through setting up Ansible, configuring SSH key-based authentication for seamless operations, and using Ansible ad-hoc commands to perform various configuration tasks on a remote server.

What is Ansible?

Ansible is an automation engine that helps you provision, configure, and manage computer infrastructure. It's known for its simplicity and agentless architecture, meaning you don't need to install any special software on the systems you want to manage. Ansible communicates with managed nodes primarily over SSH.

Why SSH Key-Based Authentication? While Ansible can use password authentication, such steps are tedious when making multiple configuration changes on many remote systems. SSH key-based authentication allows passwordless access that is fully automated. This is crucial because Ansible relies on SSH to communicate with Linux-managed nodes , and entering passwords for each task is highly inconvenient. Without key-based authentication, you'd need to enter a password for every Ansible command.

Step-by-Step Guide Let's get started with configuring a system using Ansible!

  1. Configure Key-Based SSH Authentication First, we need to set up SSH key-based authentication between your control node (where Ansible is installed) and the remote managed node (192.168.1.100). This step is essential because it enables passwordless access, which is fundamental for automated remote administration with Ansible.

    • Generate an SSH key pair:

        ssh-keygen
      

      Importance: This command creates a unique pair of cryptographic keys (a public key and a private key). The private key stays on your control node and must be kept secure, while the public key will be shared with the managed nodes. This pair is the foundation of secure, passwordless authentication. Pressing Enter three times to skip the passphrase simplifies automation by not requiring a password for the key itself.

    • Copy the public key to the managed node:

        ssh-copy-id root@192.168.1.100
      

      Importance: This step securely transfers your public key to the root user's ~/.ssh/authorized_keys file on the managed node (192.168.1.100). By doing so, the managed node is configured to trust your control node's private key for authentication, allowing you to log in without a password. You type

      yes to confirm the connection and Passw0rd! as the temporary password to authorize the key copy.

    • Test the SSH connection:

        ssh root@192.168.1.100
      

      Importance: This test verifies that the SSH key-based authentication has been set up correctly. If you are not prompted for a password, it confirms that the managed node recognizes your public key and grants access, meaning Ansible will also be able to connect without requiring a password. This is a crucial validation step before proceeding with Ansible commands.

    • Exit the SSH session:

        exit
      

      Importance: Exiting the SSH session returns you to your control node's command prompt ([root@centos ~]#). This ensures you are operating from the correct system for subsequent Ansible installation and configuration steps.

  2. Install Ansible Now, let's install Ansible on your control node.

  • Ensure your SSH connection is disconnected. Your command prompt should read

    [root@centos ~]#.

    Importance: This ensures you are operating on the control node, which is the system where Ansible will be installed. It's crucial to distinguish between the control node and the managed node to avoid installing Ansible in the wrong place.

  • Check if Ansible is already installed:

      ansible --version
    

    Importance: This command is used to confirm whether Ansible is already present on the local system (the control node) and to check its version. This prevents unnecessary reinstallation and helps verify the system's current state before proceeding.

  • Install the ansible-core package using DNF:

      sudo dnf install ansible-core -y
    

    Importance: This step installs the core Ansible package on your control node using the DNF package manager. Installing Ansible is fundamental as it provides all the necessary tools and binaries to begin automating tasks on remote systems. The installation typically takes about one minute.

  • Verify the installation:

      ansible --version
    

    Importance: Repeating the Ansible version check after installation confirms that the ansible-core package has been successfully installed and is ready for use. This final check ensures that the tool is operational before moving on to configuring managed hosts.

    1. Add Managed Host to Ansible Inventory\

      Ansible needs to know which hosts it manages. We'll add our managed node to the Ansible inventory file.

      • Add the managed host to /etc/ansible/hosts:

          echo 192.168.1.100 >> /etc/ansible/hosts
        

        Importance: This step is crucial for Ansible to know which servers it needs to manage. The /etc/ansible/hosts file is Ansible's default inventory file, where you list all your managed nodes. By adding 192.168.1.100 to this file, you are telling Ansible that this IP address is a target it can interact with.

      • Run a ping test to verify connectivity:

          ansible 192.168.1.100 -m ping
        

        Importance: This command performs a simple "ping" test using Ansible's ping module. It verifies that Ansible can successfully connect to the managed node (192.168.1.100) via SSH and execute a basic command. A "pong" response indicates that the connection is working, and Ansible is ready to send more complex commands. The SUCCESS and CHANGED fields in the output provide immediate feedback on the command's execution status.

  1. Use Ansible Ad-Hoc Commands Ad-hoc commands are a great way to quickly perform single tasks on managed nodes and understand Ansible's capabilities. They are useful for quick, one-off operations without needing to write a full playbook.
  • Create a user named webadmin:

      ansible 192.168.1.100 -m ansible.builtin.user -a "name=webadmin password="
    

    Importance: This ad-hoc command uses the ansible.builtin.user module to create a new system user named webadmin on the managed node. This demonstrates Ansible's ability to manage user accounts efficiently across remote systems. Creating the user with a blank password is often done in lab environments for simplicity, but in production, you would set a secure password or manage SSH keys for the new user.

  • Verify user creation:

    • Connect to the managed node via SSH:

        ssh root@192.168.1.100
      

      Importance: Connecting via SSH allows you to directly inspect the managed node and confirm that the previous Ansible command had the intended effect. This manual verification step is vital for debugging and ensuring that your automation is working as expected.

    • Check for the webadmin user:

        tail /etc/passwd | grep -i webadmin
      

      Importance: The /etc/passwd file stores user account information on Linux systems. Using tail and grep to search for webadmin confirms that the user entry has been added to the system, verifying the success of the Ansible user creation task.

    • Exit the SSH session:

        exit
      

      Importance: Exiting the SSH session returns you to your control node, allowing you to continue executing Ansible commands from the central management point.

    1. Create a directory /projects with specific permissions:
            ansible 192.168.1.100 -m ansible.builtin.file -a "dest=/projects mode=755 owner=centos group=centos state=directory"

Importance: This command utilizes the ansible.builtin.file module to create a directory named /projects on the managed node. It also sets specific permissions (mode=755), ownership (owner=centos), and group (group=centos). This illustrates Ansible's capability to manage file system objects, ensuring consistency in directory structures and permissions across your infrastructure.

  • Verify directory creation:

    • Connect to the managed node via SSH:

        ssh root@192.168.1.100
      

      Importance: As with user creation, direct SSH access is used here to manually confirm the directory's existence and its attributes on the managed node.

    • Check the directory:

        ls -l / | grep -i projects
      

      Importance: The ls -l / command lists the contents of the root directory with detailed information, and grep -i projects filters the output to show only lines containing "projects". This confirms that the /projects directory was created with the specified permissions and ownership.

    • Exit the SSH session:

        exit
      

      Importance: Returning to the control node is essential for continuing the Ansible workflow.

  • Copy a local file to the managed node:

      ansible 192.168.1.100 -m ansible.builtin.copy -a "src=/etc/hosts dest=/tmp/hosts"
    
  • Verify file copy:

    • Connect to the managed node via SSH:

        ssh root@192.168.1.100
      
    • Check for the copied file:

        ls /tmp/hosts | grep -i hosts
      
    • Exit the SSH session:

        exit
      
  • Install the Nmap package:

      ansible 192.168.1.100 -m ansible.builtin.yum -a "name=nmap state=present"
    

    This might take up to a minute.

  • Verify Nmap installation:

    • Connect to the managed node via SSH:

        ssh root@192.168.1.100
      
    • Check if Nmap is installed:

        dnf list installed | grep -i nmap
      
    • Exit the SSH session:

        exit
      
  • Stop the firewalld service:

      ansible 192.168.1.100 -m ansible.builtin.service -a "name=firewalld state=stopped"
    

    Note: Stopping the firewall is generally not recommended in a production environment.

  • Verify firewalld status:

    • Connect to the managed node via SSH:

        ssh root@192.168.1.100
      
    • Check the service status:

        systemctl status firewalld
      
    • Exit the SSH session:

        exit
      

Beyond Ad-Hoc Commands: Ansible Playbooks

While ad-hoc commands are great for quick tasks, Ansible playbooks offer a more robust and repeatable way to manage your infrastructure. Playbooks can target many managed nodes and are far more efficient for complex configurations. The tasks we performed today with ad-hoc commands are very similar to what you'd find within an Ansible playbook.

0
Subscribe to my newsletter

Read articles from Kelvin R. Tobias directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kelvin R. Tobias
Kelvin R. Tobias