Close Menu
DPC Virtual Tips
    Read More

    Configure vCenter File-Based Backups to NFS: Practical Lab Guide

    September 11, 2026

    Creating Your First Ansible Playbook: A Practical Lab Guide

    September 10, 2026

    Linux Commands to Investigate High Disk Partition Usage

    September 9, 2026
    • Home
    • About Us
    • Contact
    • Cookie Policy
    • Comment Policy
    • Privacy Policy
    • Terms of Use
    Monday, September 14
    DPC Virtual Tips
    • Home
    • Linux & Automation
    • HPC & Slurm
    • VMware & Virtualization
    • About Us
    • Contact
    DPC Virtual Tips
    Home » Creating Your First Ansible Playbook: A Practical Lab Guide
    Linux & Automation

    Creating Your First Ansible Playbook: A Practical Lab Guide

    By Danilo ChiacchioSeptember 10, 202610 Mins Read
    Facebook Twitter Pinterest LinkedIn Tumblr Email
    Creating Your First Ansible Playbook
    Creating Your First Ansible Playbook
    Share
    Facebook Twitter LinkedIn Pinterest Email

    Ansible becomes much easier to understand when you stop looking at individual concepts and start using it to solve a real administrative task.

    In this guide, I will use a lab environment to create and run a first Ansible playbook against multiple Linux servers. Instead of building a simple “Hello World” example, the playbook will perform an actual system administration task: ensure that the NFS client package is installed and that the required NFS client target is running on a group of HPC nodes.

    The goal is not only to show the YAML syntax. We will build the inventory, validate connectivity, create the playbook, check it before execution, run it against multiple hosts, interpret the result, and verify the final state.

    Lab Environment Used in This Guide

    The environment used for this article consists of one Ansible control node and six Linux managed nodes.

    The control node is the system where Ansible is installed and where all Ansible commands are executed. The managed nodes are the remote systems that Ansible connects to over SSH.

    For this lab, I used:

    • Control node: CentOS Stream 9
    • Python: Python 3.9
    • Ansible: ansible-core 2.14.18 in the original lab
    • Managed nodes: hpc2-node01 through hpc2-node06
    • Connectivity: SSH key-based authentication
    • Lab objective: install nfs-utils and start nfs-client.target on all managed nodes

    The Ansible version shown in the original lab is intentionally preserved because it documents the environment in which the procedure was tested. If you reproduce this lab with a newer Ansible release, some package versions or behavior may differ. Ansible maintains newer ansible-core branches today, so always check the current supported release before building a new environment:

    Ansible control node and managed nodes used in the lab
    Ansible control node and managed nodes used in the lab

    How Ansible Works in This Lab

    For this example, we only need to understand five basic components:

    • The control node is the machine where Ansible runs.
    • The managed nodes are the Linux servers that Ansible will configure.
    • The inventory tells Ansible which hosts exist and allows us to organize them into groups.
    • A playbook is a YAML file describing the desired configuration.
    • A task calls an Ansible module to perform a specific action, such as installing a package or starting a service.

    Important: Ansible is agentless for this type of Linux management. We do not install an Ansible agent on each managed server. The control node connects to them remotely, normally using SSH.

    Install Ansible on the Control Node

    In my lab, Ansible was installed on a CentOS Stream 9 control node.

    First, install the EPEL repository:

    dnf install -y epel-release

    Then install Ansible:

    dnf install -y ansible

    Confirm the installation:

    ansible --version

    In the original lab, the command returned ansible-core 2.14.18.

    Your output may be different if you are reproducing this guide with a newer repository or Ansible release.

    For current installation methods and supported packages, it is a good idea to compare your environment with the official Ansible installation documentation.

    Configure SSH Access to the Managed Nodes

    Before Ansible can manage the remote servers, the control node must be able to connect to them over SSH.

    For this lab, SSH key-based authentication was configured between the Ansible control node and all six managed nodes.

    For this lab, I use SSH key-based authentication instead of password-based automation, which provides a cleaner approach for repeatable administration.

    Once the keys are configured, test a managed node directly:

    ssh hpc2-node01

    The objective is to confirm that the control node can establish the SSH session using the configured key:

    SSH connection from the Ansible control node to hpc2-node01 using key authentication
    SSH connection from the Ansible control node to hpc2-node01 using key authentication

    In this lab I used administrative access to simplify the environment. In production, consider using a dedicated automation account with controlled sudo privileges instead of relying on direct root access.

    Create the Ansible Project Directories

    I prefer to keep the inventory and playbooks separated.

    Create the project structure:

    mkdir -p /root/ansible/inventory
    mkdir -p /root/ansible/playbooks

    Move into the project directory:

    cd /root/ansible

    The structure will look like this:

    /root/ansible/
    ├── inventory/
    │   └── hosts.ini
    └── playbooks/
        └── install_nfs_client.yml

    Create the Ansible Inventory

    Create the inventory file:

    touch inventory/hosts.ini

    Add the six managed nodes:

    [hpc_nodes]
    hpc2-node01 ansible_host=192.168.255.121
    hpc2-node02 ansible_host=192.168.255.122
    hpc2-node03 ansible_host=192.168.255.123
    hpc2-node04 ansible_host=192.168.255.124
    hpc2-node05 ansible_host=192.168.255.125
    hpc2-node06 ansible_host=192.168.255.126

    The name between brackets:

    [hpc_nodes]

    defines an inventory group.

    Instead of targeting each server individually, we can now execute Ansible against the entire hpc_nodes group.

    Validate the Inventory

    Before creating a playbook, verify that Ansible can parse the inventory correctly.

    Run:

    ansible-inventory \
      -i inventory/hosts.ini \
      --graph

    You should see the hpc_nodes group and its six members.

    This is an important check because inventory naming mistakes can cause a perfectly valid playbook to run against zero hosts.

    Test Ansible Connectivity

    Now test communication with the entire group:

    ansible \
      -i inventory/hosts.ini \
      hpc_nodes \
      -m ansible.builtin.ping

    A successful response should return pong for each managed node:

    Ansible ping test returning pong from the HPC managed nodes
    Ansible connectivity test returning pong from all six managed nodes.

    The Ansible ping module is not the same as the operating system ping command.

    It does not simply send ICMP packets. It verifies that Ansible can connect to the managed node and execute the module successfully.

    If all six hosts return successfully, the control node, inventory, SSH authentication, and basic remote execution path are working.

    Create Your First Ansible Playbook

    Now we can create the actual playbook.

    Create the file:

    touch playbooks/install_nfs_client.yml

    Add the following content:

    ---
    - name: Install and start NFS client components on HPC nodes
      hosts: hpc_nodes
      become: true
    
      tasks:
    
        - name: Ensure nfs-utils is installed
          ansible.builtin.package:
            name: nfs-utils
            state: present
    
        - name: Ensure nfs-client.target is started
          ansible.builtin.systemd_service:
            name: nfs-client.target
            state: started

    There are a few important details here.

    The line:

    hosts: hpc_nodes

    must match the inventory group exactly.

    The following line:

    become: true

    allows tasks that require elevated privileges to execute using Ansible privilege escalation.

    The first task ensures that the nfs-utils package exists.

    The second task ensures that nfs-client.target is running in this lab environment.

    I am using Fully Qualified Collection Names such as:

    ansible.builtin.package

    and:

    ansible.builtin.systemd_service

    because they make it explicit which collection provides the module and reduce ambiguity as automation projects grow. Ansible documentation similarly recommends FQCNs for clarity and avoiding naming conflicts.

    Ansible playbook used to install NFS client components on the HPC nodes
    Ansible playbook used to install NFS client components on the HPC nodes

    One important detail: service and target behavior can vary between Linux distributions and versions. If you are reproducing this example outside the environment used here, verify how the NFS client is managed on that operating system.

    Validate the Playbook Before Running It

    Before making any changes to remote systems, check the YAML and playbook structure.

    Run:

    ansible-playbook \
      -i inventory/hosts.ini \
      playbooks/install_nfs_client.yml \
      --syntax-check

    If there are no syntax errors, Ansible should identify the playbook successfully.

    This catches common problems such as invalid YAML indentation or malformed playbook structure before you try to execute the tasks across multiple servers.

    Preview the Changes with Check Mode

    Ansible also provides check mode, which can be useful for previewing what supported tasks would change.

    Run:

    ansible-playbook \
      -i inventory/hosts.ini \
      playbooks/install_nfs_client.yml \
      --check

    Check mode is a simulation rather than a guarantee of the final execution result. Modules that support check mode report what they expect to change, while modules that do not support it may not provide the same behavior.

    I use it as an additional validation step, not as a replacement for testing and post-change verification.

    Run the Playbook

    Once the inventory, SSH connectivity, syntax, and expected changes look correct, execute the playbook:

    ansible-playbook \
      -i inventory/hosts.ini \
      playbooks/install_nfs_client.yml

    The playbook runs against all hosts in the hpc_nodes inventory group.

    Ansible processes the tasks in order and then displays a PLAY RECAP for each managed node.

    How to Read the Play Recap

    A typical recap contains counters similar to:

    ok=3
    changed=0
    unreachable=0
    failed=0

    These values are important when diagnosing an Ansible execution:

    • ok indicates tasks that completed successfully or found the system already in the desired state.
    • changed indicates how many tasks actually changed something on the managed node.
    • unreachable normally points to a communication problem such as SSH connectivity, DNS resolution, authentication, or routing.
    • failed indicates that Ansible reached the host but a task itself failed.

    In my lab, nfs-utils was already installed and the NFS client target was already in the required state, so the execution returned:

    changed=0

    That is useful information. Ansible inspected the systems but did not make unnecessary changes.

    Verify the Result on the Managed Nodes

    A successful play recap is important, but I also like to verify the final state directly.

    Check the installed package across the group:

    ansible \
      -i inventory/hosts.ini \
      hpc_nodes \
      -b \
      -m ansible.builtin.command \
      -a "rpm -q nfs-utils"

    Then verify the NFS client target:

    ansible \
      -i inventory/hosts.ini \
      hpc_nodes \
      -b \
      -m ansible.builtin.command \
      -a "systemctl is-active nfs-client.target"

    This gives us an additional confirmation that the expected state exists on the managed nodes after the playbook execution.

    The important workflow is:

    Define
       ↓
    Validate
       ↓
    Preview
       ↓
    Execute
       ↓
    Verify

    That pattern becomes much more valuable as playbooks start changing production systems instead of a small lab.

    Understanding Idempotency

    One of the most useful characteristics of configuration management is the ability to describe a desired state.

    Consider the package task:

    - name: Ensure nfs-utils is installed
      ansible.builtin.package:
        name: nfs-utils
        state: present

    We are not telling Ansible:

    Run an installation command every time.

    We are telling it:

    Make sure this package is present.

    If the package is already installed, an idempotent module can determine that no change is necessary.

    That is why a second execution can return:

    changed=0

    when the systems already match the desired state.

    However, it is important not to assume that every Ansible task is automatically idempotent. Idempotency depends on the module being used and on how the playbook is written.

    For example, a task based on a raw shell command can behave very differently from a module specifically designed to manage a package, file, user, or service state.

    Common Problems When Running a First Playbook

    If Ansible reports:

    UNREACHABLE

    check SSH connectivity, DNS or hostname resolution, SSH keys, network access, and the remote username.

    If you receive:

    no hosts matched

    compare the value in:

    hosts:

    with the group name defined in the inventory.

    For this article, both must use:

    hpc_nodes

    If privilege escalation fails, verify that the remote account has the required sudo permissions and that your Ansible privilege escalation configuration matches the environment.

    If Ansible reports a YAML or syntax error, run:

    ansible-playbook \
      -i inventory/hosts.ini \
      playbooks/install_nfs_client.yml \
      --syntax-check

    before troubleshooting the remote nodes.

    Where to Go Next

    This lab covered the complete basic workflow required to start building useful Ansible automation:

    Control node
          ↓
    Inventory
          ↓
    SSH connectivity
          ↓
    Playbook
          ↓
    Syntax validation
          ↓
    Check mode
          ↓
    Execution
          ↓
    Verification

    Once this workflow is familiar, the next step is not necessarily to learn dozens of additional Ansible concepts.

    It is better to start applying the same workflow to real infrastructure tasks.

    For example, on DPC Virtual Tips I also use Ansible in a VMware lab to automate virtual machine deployment. That provides a natural next step after understanding inventory, playbooks, modules, and remote execution.

    Final Words

    Creating a first Ansible playbook is more useful when the exercise solves a real administrative problem.

    In this lab, we configured one Ansible control node to manage six Linux systems, created an inventory, validated SSH connectivity, built a playbook, checked its syntax, previewed the execution, ran it against the entire group, interpreted the play recap, and verified the final state.

    The YAML itself is only one part of the process.

    For infrastructure automation, the more important skill is building a predictable workflow where you can understand what will change, why it will change, which systems will be affected, and how to confirm the result afterward.

    That is the same approach I use throughout the infrastructure and troubleshooting guides published on DPC Virtual Tips.

    External References

    • Ansible Installation Guide
    • Ansible Playbook Guide
    • Ansible Check Mode Documentation
    • Ansible Releases and Maintenance
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous ArticleLinux Commands to Investigate High Disk Partition Usage
    Next Article Configure vCenter File-Based Backups to NFS: Practical Lab Guide
    Danilo Chiacchio
    • LinkedIn

    Infrastructure Engineer with hands-on experience in virtualization, Linux, Windows Server, and enterprise infrastructure troubleshooting. I work with real-world infrastructure environments and technical labs, focusing on diagnosing problems, understanding root causes, and documenting practical solutions. DPC Virtual Tips was created to share hands-on troubleshooting guides, lab experiences, technical procedures, and lessons learned while working with technologies such as VMware, Linux, HPC/Slurm, networking, storage, and infrastructure automation with Python.

    Related Posts

    Linux Commands to Investigate High Disk Partition Usage

    September 9, 2026

    How to Investigate TCP Retransmissions on Linux

    September 3, 2026

    Manage Chrony NTP Configuration with Ansible: Practical Playbook

    September 2, 2026

    Comments are closed.

    Search
    Categories
    • HPC & Slurm (11)
    • Linux & Automation (12)
    • VMware & Virtualization (16)
    Read More
    VMware & Virtualization

    Configure vCenter File-Based Backups to NFS: Practical Lab Guide

    By Danilo ChiacchioSeptember 11, 202610 Mins Read
    Linux & Automation

    Creating Your First Ansible Playbook: A Practical Lab Guide

    By Danilo ChiacchioSeptember 10, 202610 Mins Read
    Linux & Automation

    Linux Commands to Investigate High Disk Partition Usage

    By Danilo ChiacchioSeptember 9, 20267 Mins Read
    HPC & Slurm

    How to Investigate Jobs Stuck in COMPLETING State on Slurm

    By Danilo ChiacchioSeptember 8, 202612 Mins Read
    VMware & Virtualization

    Restoring vCenter Server from a File-Based Backup: Practical Lab Walkthrough

    By Danilo ChiacchioSeptember 7, 20269 Mins Read
    Latest Posts

    Configure vCenter File-Based Backups to NFS: Practical Lab Guide

    September 11, 2026

    Creating Your First Ansible Playbook: A Practical Lab Guide

    September 10, 2026

    Linux Commands to Investigate High Disk Partition Usage

    September 9, 2026
    Images from Gallery
    hpc main commands
    linux commands
    install rock linux
    lustre fs
    shell scripting
    vSAN Trace Files
    Categories
    • HPC & Slurm
    • Linux & Automation
    • VMware & Virtualization
    • Home
    • About Us
    • Contact
    • Cookie Policy
    • Comment Policy
    • Privacy Policy
    • Terms of Use
    Copyright © 2026, DPC Virtual Tips. All rights reserved.

    Type above and press Enter to search. Press Esc to cancel.

    We use cookies to improve your browsing experience, analyze website traffic, and display relevant advertising. You can accept all cookies or manage your preferences at any time.