Introduction to Ad-Hoc Commands
Get introduced to Ansible Ad-Hoc Commands and their importance.
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:
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.
- Create the
/ansible
directory withBash
.
Run the following command:
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.
- Create the
/ansible
directory with Ansible. Run the following command:
ansible localhost -m file -a "path=/ansible state=directory"
Review the output for the ansible command below:
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.
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.
ansible localhost -m stat -a "path=/ansible"
Copy
Use the copy
module to copy info.md
to to-dos.md
.
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.
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.
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
.
ansible localhost -m file -a "path=/ansible/to-dos.md state=absent"
Ansible Module Index
Ansible
ships with a number of modules (called themodule 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:
# Create a directory using Bashmkdir /ansible# Create a directory using Ansibleansible localhost -m file -a "path=/ansible state=directory"# Pingansible localhost -m ping# Statansible localhost -m stat -a "path=/ansible"# Copyansible localhost -m copy -a "src=/ansible/info.md dest=/ansible/to-dos.md"# Replaceansible localhost -m replace -a "path=/ansible/to-dos.md regexp='^\[\s' replace='[x'"# Debug and Lookupansible localhost -m debug -a "msg={{lookup('file', '/ansible/to-dos.md') }}"# Fileansible localhost -m file -a "path=/ansible/to-dos.md state=absent"
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.