Introduction to Ad-Hoc Commands

An Ansible ad-hoc command uses the command-line tool ansible to automate a single task on one or more nodes. An ad-hoc command looks like this:

Press + to interact
ansible [pattern] -m [module] -a "[module options]"

Ad-hoc commands offer a quick and easy way to execute automation, but they are not built for reusability. Their advantages are that they leverage Ansible modules which are idempotent, and the knowledge gained by using them directly ports over to the Ansible playbook language.

The importance of idempotence

Why not script it? Why not just write your own automation using PowerShell, Bash, or Python? The short answer is idempotence.

Using an imperative language, you are writing a prescriptive order of operations that do not account for all the various scenarios that might be true.

For example, take the task of creating a directory. This is accomplished by running a single command.

Problem

What happens when you rerun the command? You get an error stating that the directory exists.

Solution

That’s easy enough to address. Add a try-catch block to account for this scenario.

However, what if you want to modify the permissions? Each new situation requires that you reevaluate the automation and add additional logic.

You want a way to declare the end state and have the automation handle the rest.

Idempotent automation

Ansible uses a declarative language that allows you to define what should be created and let it figure out the rest.

When you use Ansible to create a directory, you declare the configuration, and Ansible figures out how to make it happen. If the folder exists, it returns the status for SUCCESS because the logic exists to handle that scenario.

If the permissions need to change, then you update the mode parameter. You shift from writing code for every task and every scenario to declaring every task.

Ansible can do this by using automation that is idempotent. When automation is idempotent, it can be repeated an arbitrary number of times, and the results will be the same.

Idempotency is at the core of how to make your infrastructure repeatable with Ansible.

Let’s look at the creating a directory example in play to understand the difference between imperative and declarative language.

  1. Create the /ansible directory with Bash.

Run the following command:

Press + to interact
mkdir /ansible

File exists
mkdir: cannot create directory ‘/ansible’: File exists.

mkdir returned an error because the directory already existed.

If the command is placed in a script, additional error handling is required to account for the existing directory.

  1. Create the /ansible directory with Ansible. Run the following command:
Press + to interact
ansible localhost -m file -a "path=/ansible state=directory"

Review the output for the ansible command below:

Press + to interact
localhost | SUCCESS => {
"changed": false,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/ansible",
"size": 192,
"state": "directory",
"uid": 0
}

In its simplest form, this is the difference between imperative and declarative. Declarative automation gives you the ability to run something over and over again and expect the same result.

You could write additional logic in your Bash scripts to account for such scenarios. This usually ends up being redundant and time-consuming.

When are ad-hoc commands useful?

Ad-hoc commands are great for infrequent tasks. For example, if you need to restart a service across several hosts in response to an incident, you can quickly accomplish this with a one-liner.

Use cases for ad-hoc tasks:

  • Rebooting servers
  • Managing services
  • Managing files
  • Fact gathering
  • Connectivity testing

Exercise Ad-Hoc Commands
If you have a lot of experience with a scripting language, you will be tempted to use the language you know well. As often as you can, exercise ad-hoc Ansible commands to improve your competency with Ansible.

Using ad-hoc commands

Ad-hoc commands demonstrate the simplicity and capability of Ansible. The concepts and knowledge that you’ll learn directly port over to the Ansible playbook language.

The ansible command requires a:

  • Pattern
  • Module-name
  • Argument list (if required by the module)

Use the host pattern of localhost to run the following ad-hoc commands.

Ping

The ping module tests connectivity. It does not use ICMP and requires Python on the remote-node. It does not require any additional arguments.

Press + to interact
ansible localhost -m ping
  • localhost - Host pattern
  • -m ping - Specifies the ping module

Stat

The stat module retrieves facts about the /ansible directory. This module is similar to the Linux/Unix stat command.

Press + to interact
ansible localhost -m stat -a "path=/ansible"

Copy

Use the copy module to copy info.md to to-dos.md.

Press + to interact
ansible localhost -m copy -a "src=/ansible/info.md dest=/ansible/to-dos.md"

Run the copy command twice. Notice Ansible returns a CHANGED status after the first run and SUCCESS status after the second.

Replace

Use the replace module to update the to-dos.md file.

Press + to interact
ansible localhost -m replace -a "path=/ansible/to-dos.md regexp='^\[\s' replace='[x'"

The regular expression matches the start of line ^ followed by a [ and a space character \s. It then replaces the match with [x. The result is a checkbox in the markdown file.

Debug and lookup

Use the debug module with the lookup plugin to get the contents of the to-dos.md file.

Press + to interact
ansible localhost -m debug -a "msg={{lookup('file', '/ansible/to-dos.md') }}"

Notice that the markdown now displays a checkbox [x].

You will learn more about the debug and lookup plugin later. For now, know that the debug module is used for debugging variables or expressions and the lookup plugin allows Ansible to access data from outside sources.

File

Use the file module to remove the to-dos.md file by setting the state parameter to absent.

Press + to interact
ansible localhost -m file -a "path=/ansible/to-dos.md state=absent"

Ansible Module Index
Ansible ships with a number of modules (called the module library). You can find documentation for these modules in the Ansible Module Index.

Practice the modules/commands in the terminal. We have provided a summarized view of the commands below:

Press + to interact
# Create a directory using Bash
mkdir /ansible
# Create a directory using Ansible
ansible localhost -m file -a "path=/ansible state=directory"
# Ping
ansible localhost -m ping
# Stat
ansible localhost -m stat -a "path=/ansible"
# Copy
ansible localhost -m copy -a "src=/ansible/info.md dest=/ansible/to-dos.md"
# Replace
ansible localhost -m replace -a "path=/ansible/to-dos.md regexp='^\[\s' replace='[x'"
# Debug and Lookup
ansible localhost -m debug -a "msg={{lookup('file', '/ansible/to-dos.md') }}"
# File
ansible localhost -m file -a "path=/ansible/to-dos.md state=absent"
Terminal 1
Terminal
Loading...

In this lesson, we introduced ad-hoc commands, idempotency, Ansible commands, and modules. The following are the commands and modules we explored:

  • file: To add and remove directories.
  • stat: To retrieve facts about directories.
  • copy: To copy files.
  • replace: To update files.
  • Debug: To debug variables and expressions.
  • lookup: A plugin to access data from outside sources.

Get hands-on with 1300+ tech skills courses.