Inspect Hosts with Ad Hoc Commands

AnsibleBeginner
Practice Now

Introduction

A one-off Ansible command can inspect a fleet or apply a small, explicit configuration state. Choosing the right module makes its behavior and returned results easier to understand.

You will inspect two Linux targets, prepare a managed directory and distribute a controller source file. You will compare command execution with modules that report whether the requested state actually needed a change. The inventory and SSH connections are already prepared.

Inspect a Host Group with Modules

In this step, you will choose one-off Ansible modules to inspect the two prepared managed nodes.

Open the Terminal and select the workspace:

cd /home/labex/project

An ad hoc command runs one module directly against selected inventory hosts, without a playbook. Its basic shape is ansible PATTERN -m MODULE -a ARGUMENTS. The lab supplies a webservers group containing both SSH targets. Preview that group:

ansible webservers --list-hosts

Expect exactly web1 and web2. Use the command module from the preceding lab to run uname -s, which prints the operating-system kernel name:

ansible webservers -m ansible.builtin.command -a 'uname -s'

Each host should print Linux. The command module normally reports CHANGED even for a read-only query. Inspect stdout and return status rather than interpreting that label as a configuration change.

The setup module gathers facts, structured information discovered on a managed node. The module's filter argument narrows returned facts. Inspect the distribution name:

ansible webservers -m ansible.builtin.setup -a 'filter=ansible_distribution'

Each successful result should include an ansible_facts object containing "ansible_distribution": "Ubuntu". setup usually reports changed: false for this inspection. Facts describe the target, not your controller; later labs will use them in automation.

A nonzero task result is a failure, and UNREACHABLE indicates a connection problem. Two expected hosts require two successful results. Do not confuse an empty selection with a completed inspection.

Declare a Managed Directory

In this step, you will use a state-oriented module to prepare the same directory on both targets.

The file module manages filesystem state. Its path identifies the target path, and state=directory requests a directory rather than an empty file. mode=0750 grants the owner full access, the group read/search access and others no access. The leading zero denotes an octal permission value.

Ordinary tasks run as the prepared automation account. Create a directory inside that user's home, so no become is needed:

ansible webservers -m ansible.builtin.file -a 'path=/home/automation/ops state=directory mode=0750'

Both hosts should report changed: true when the directory is first created, with a path or dest field identifying /home/automation/ops. The directory is owned by automation because that account creates it.

Run the same declaration again:

ansible webservers -m ansible.builtin.file -a 'path=/home/automation/ops state=directory mode=0750'

Now expect changed: false on both hosts: the requested state already exists. This differs from repeatedly issuing a general command such as touch, which may still update timestamps.

Copy a Controller File to Both Targets

In this step, you will create a small controller source file and deploy its exact contents with explicit target permissions.

printf writes the text and a trailing newline; > creates or replaces the source in the current project. The quoted format keeps the message together, while \n requests the newline:

printf 'Managed by Ansible\n' > message.txt

The copy module transfers a controller source to a managed destination. src is on the controller, while dest is on each target. For a regular file, mode=0640 gives the owner read/write, the group read and others no access:

ansible webservers -m ansible.builtin.copy -a 'src=/home/labex/project/message.txt dest=/home/automation/ops/message.txt mode=0640'

Each target should report changed: true on the initial copy. Run the same transfer again:

ansible webservers -m ansible.builtin.copy -a 'src=/home/labex/project/message.txt dest=/home/automation/ops/message.txt mode=0640'

Expect changed: false when the bytes and requested permissions already match. The file module prepared the parent directory; copying a file does not replace that directory-creation step.

Read the actual remote content with the command module:

ansible webservers -m ansible.builtin.command -a 'cat /home/automation/ops/message.txt'

Both stdout results should show Managed by Ansible. The command query may report CHANGED, but the earlier copy module's changed:false result describes an already matching managed file. Your controller source remains separate from both remote copies.

Summary

You ran ad hoc modules against a real two-host group, interpreted command output and discovered distribution facts. You declared a directory, copied a separate controller source with explicit permissions, and observed unchanged results when state-oriented modules found matching state on a repeat run.