Learn › Linux Automation with Salt › Ask the right machines
Choose exact IDs or a list, request facts from real agents, and distinguish a missing return from a reported result.
An automation command has two questions hidden inside it: which machines should receive this request, and what should happen there? A correct operation sent to the wrong machine is still a mistake.
In this lesson, you will request facts from the two agents you enrolled in Lesson 1. You will choose recipients before running a command, compare the replies with that choice, and explain an incomplete result without guessing its cause. No package, file or service change is needed for a healthy fleet.
Before you begin: finish Meet and trust your fleet. You should be able to identify the master terminal, explain why each minion key was accepted, and obtain a fresh Salt reply from each named agent. Basic shell quoting and sudo are enough; no programming is required.
Keep the same running three-machine session if it is still available. A fresh session starts with the Lesson 1 configuration: both minions need verified enrollment, and the second has a wrong master address to diagnose. Complete that preparation before these exercises. A previous session's keys and fingerprints do not identify newly created machines.
Run Salt requests in the salt-master terminal. Here is the request you already know:
sudo salt 'minion-a' test.ping
sudo salt runs the Salt command with the required local permission on the master.'minion-a' is the target expression. With the default matcher, this pattern matches the ID minion-a.test.ping is what the selected agent is asked to run. This asks for a Salt reply, not an ICMP network ping.The master publishes the request; matching, connected agents execute it and send back their own results. The target describes who should act. It is not an IP route, a service-health test or an independent check of identity.
{"caption":"One logical request and its named result. This is not a network-packet diagram; the minion establishes the Salt connections to its master.","direction":"vertical","nodes":[{"id":"request","label":"Master request"},{"id":"agent","label":"minion-a"},{"id":"return","label":"Named result"}],"edges":[{"from":"request","to":"agent","label":"matches ID","kind":"plain","stage":1},{"from":"agent","to":"return","label":"test.ping","kind":"plain","stage":2}]}
Salt normally labels each returned result with a minion ID. Read that label as well as the value. A True underneath minion-a is evidence that this agent answered this request; it does not establish that every service on that machine is healthy.
Our intended fleet contains the verified IDs minion-a and minion-b. These three selectors mean different things:
'minion-a' matches the one ID with that name.-L 'minion-a,minion-b' names the two IDs, separated by a comma.'minion-*' matches any ID beginning with minion-, using the default glob matcher.A glob is a pattern: * can match any sequence of characters. Quote the pattern so your shell passes it to Salt rather than trying to match local filenames first. A naming pattern can be convenient, but it is not a permanent membership boundary: adding minion-c could widen its scope.
>>> Use the exact ID when only that machine is intended. Both other selectors include minion-a in this inventory. Decide the set before choosing the syntax.
Do not omit -L from a list request: 'minion-a,minion-b' by itself is one glob expression containing a comma, not a two-ID list.
In the master terminal:
sudo salt-key --list=accepted
sudo salt --timeout=8 'minion-a' test.ping
Find both previously verified IDs in the accepted-key list. Do not accept an unfamiliar key just to make a request succeed. The list records accepted identities; it does not tell you which agents are currently connected.
For the second command, look for a result labeled minion-a with the value True. Record the ID and value you actually see. We use an eight-second wait for this small practice fleet; it is a collection window, not a promise about network speed or application readiness.
If the expected reply is absent, stop this worked path and use the investigation step later in this lesson. Do not invent a successful result. You can inspect an agent through its management terminal even when it cannot answer Salt.
Suppose you need the reported operating system for minion-a, before choosing a compatible package later. On the master:
sudo salt --timeout=8 'minion-a' grains.item id os
Grains are facts made available by a minion. grains.item requests named entries; here, id and os. Inspect the outer minion-ID label, then the values inside its result. In this prepared Debian fleet, the normal OS report is Debian. Use your actual response as evidence; a different value deserves investigation.
The outer result label identifies which minion returned this entry. The id grain is also reported by the agent. Neither a familiar label nor a reported OS independently repeats Lesson 1's fingerprint verification. A compromised or misconfigured agent may report misleading facts.
>>> Facts are useful input to a decision, with limits. Identity provenance comes from the enrollment process and trusted inventory; application health needs an application check.
Before this request, write the expected return IDs: minion-a and minion-b. Then run it on the master:
sudo salt --timeout=8 -L 'minion-a,minion-b' grains.item id os
Read the whole result. The order of replies can vary. Compare a set of IDs, not which reply appeared first.
Make a separate entry in your notes for minion-a and minion-b. For each one, record whether a result arrived, its id and os values or the actual error, and what remains unknown. In both cases, application health is still untested.
A successful reply from one agent does not stand in for another. Distinguish three observations: a reply with the requested facts, a reply reporting an error, and no result collected for an expected ID. These lead to different next checks.
If both intended agents report the expected facts, leave their configuration alone. A useful operational decision can be: the evidence answers this question; no machine change is justified.
An operator wants facts from both agents and proposes:
sudo salt --timeout=8 'minion-a,minion-b' grains.item id os
Explain the mismatch before running anything: without -L, Salt receives a single glob expression. Replace the target syntax with the explicit list form from the previous step, then verify that both intended IDs returned facts.
Now compare with a quoted pattern, using only this read-only query:
sudo salt --timeout=8 'minion-*' grains.item id os
In our two-agent inventory, it should select the same IDs. Record whether it did. That does not make the two selectors interchangeable in a growing fleet.
>>> The explicit list still names only the two intended IDs. The patterns can include the new agent. Recheck membership before a consequential change; names alone do not establish role or authorization.
The justified change here was to the proposed request, not to a healthy server. Verification means comparing the returned IDs with the intended set, then interpreting each result.
On the master, predict the result of asking a name that is not in this lab inventory, then try this read-only request:
sudo salt --timeout=8 'minion-does-not-exist' test.ping
Expect no successful named minion reply; the CLI may report that no minions matched. Read its actual message. Do not reinterpret that message as a Boolean False returned by an agent.
Silence from a real expected ID needs more investigation. A wrong target, an unavailable agent, a trust problem, a broken path or a late response can all prevent collection of the expected result. A timeout means the CLI stopped waiting; it does not prove that a requested operation never ran. This matters especially before retrying a later operation that changes something.
>>> You know that one expected result is missing. You do not yet know why. Preserve that distinction while choosing a check that can separate possible explanations.
For a genuinely missing minion-b reply, first compare the target with the accepted-key list on the master. Through the minion-b management terminal, inspect:
sudo systemctl is-active salt-minion
sudo journalctl -u salt-minion -n 20 --no-pager
ip route get 10.77.0.10
A service status, a recent log message and a route selection each answer a different question. Explain what you would check next and why. Use Lesson 1's configuration and trust procedure if its prerequisites are not satisfied. Do not reset keys, edit routes or restart healthy services just because the first query was incomplete. After a justified repair, rerun a narrow request and account for both agents again.
Close the earlier command examples. A teammate needs the reported operating system from minion-b only. Minion-a must be excluded.
Write your intended ID set and choose a read-only command. Run it in the correct terminal, then explain:
1. Why your target includes minion-b and excludes minion-a. 2. Which ID returned, what its OS fact says, and whether an error or missing reply changed your conclusion. 3. What the result does not prove about trust or application health. 4. Whether any machine change is justified by this request.
If you needed to reopen the example, record that help and try the task again later without it. A command that ran successfully is useful evidence; it is not an assessment of your explanation.
Keep a short note: question → intended IDs → command → observed IDs and results → missing evidence → decision → verification. Do not paste secrets or private keys into it.
This lesson has no automatic pass score. The Lesson 1 enrollment check does not measure target selection or your reasoning. Reading progress records that you opened steps; it does not certify independent mastery.
On your next visit, before looking back at the worked example, reason about this changed accepted inventory: minion-a, minion-b, and minion-backup. The requirement still names only minion-a and minion-b. Choose a target, predict which IDs it selects and which replies you would expect if both agents are available, and explain why 'minion-*' would widen the intended scope. Selection does not guarantee a reply. This is a reasoning exercise; the current lab still has two minions.
When the next lesson is available, reuse that target decision before the first managed-file change. You will describe a required result, inspect what changed, and repeat the request to check whether further work was needed.
References: Salt 3006 target matching, Salt CLI, missing returns and timeouts. This lesson's command behavior is reviewed against the lab's pinned Salt 3006.27 implementation.
Practice Ask the right machines in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.